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

📄 ctrlbrowseframe.cpp

📁 p2p软件
💻 CPP
字号:
//
// CtrlBrowseFrame.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 "Schema.h"
#include "SchemaCache.h"
#include "G2Packet.h"
#include "CtrlBrowseFrame.h"
#include "CtrlMatch.h"
#include "DlgHitColumns.h"
#include "Skin.h"

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

IMPLEMENT_DYNAMIC(CBrowseFrameCtrl, CWnd)

BEGIN_MESSAGE_MAP(CBrowseFrameCtrl, CWnd)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SETCURSOR()
	ON_WM_LBUTTONDOWN()
	ON_WM_SIZE()
	ON_WM_PAINT()
	ON_UPDATE_COMMAND_UI(ID_SEARCH_DETAILS, OnUpdateSearchDetails)
	ON_COMMAND(ID_SEARCH_DETAILS, OnSearchDetails)
	ON_NOTIFY(BTN_SELCHANGED, IDC_BROWSE_TREE, OnTreeSelection)
	ON_UPDATE_COMMAND_UI(ID_LIBRARY_TREE_PHYSICAL, OnUpdateLibraryTreePhysical)
	ON_COMMAND(ID_LIBRARY_TREE_PHYSICAL, OnLibraryTreePhysical)
	ON_UPDATE_COMMAND_UI(ID_LIBRARY_TREE_VIRTUAL, OnUpdateLibraryTreeVirtual)
	ON_COMMAND(ID_LIBRARY_TREE_VIRTUAL, OnLibraryTreeVirtual)
END_MESSAGE_MAP()

#define SIZE_INTERNAL	1982
#define SPLIT_SIZE		6
#define BAR_HEIGHT		28


/////////////////////////////////////////////////////////////////////////////
// CBrowseFrameCtrl construction

CBrowseFrameCtrl::CBrowseFrameCtrl()
{
	m_bTreeVisible	= FALSE;
	m_nTreeSize		= Settings.Search.BrowseTreeSize;
	m_bPanelEnable	= FALSE;
	m_bPanelVisible	= Settings.Search.DetailPanelVisible;
	m_nPanelSize	= Settings.Search.DetailPanelSize;
	m_pTree[0]		= NULL;
	m_pTree[1]		= NULL;
	m_nTree			= 1;
}

CBrowseFrameCtrl::~CBrowseFrameCtrl()
{
	if ( m_pTree[0] != NULL ) m_pTree[0]->Release();
	if ( m_pTree[1] != NULL ) m_pTree[1]->Release();
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseFrameCtrl message handlers

BOOL CBrowseFrameCtrl::Create(CWnd* pParentWnd, CMatchCtrl* pMatch)
{
	CRect rect( 0, 0, 0, 0 );
	m_wndList = pMatch;
	m_wndList->SetBrowseMode();
	return CWnd::Create(	NULL, _T("CBrowseFrameCtrl"), WS_CHILD|WS_VISIBLE,
							rect, pParentWnd, IDC_BROWSE_FRAME, NULL );
}

int CBrowseFrameCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
	
	if ( ! m_wndTreeTop.Create( this, WS_CHILD|WS_VISIBLE|CBRS_NOALIGN, AFX_IDW_TOOLBAR ) ) return -1;
	m_wndTreeTop.SetBarStyle( m_wndTreeTop.GetBarStyle() | CBRS_TOOLTIPS|CBRS_BORDER_BOTTOM );
	m_wndTreeTop.SetOwner( GetOwner() );
	
	m_wndTree.Create( this );
	m_wndDetails.Create( this );
	m_wndList->SetParent( this );
	m_wndList->SetOwner( GetParent() );
	
	return 0;
}

void CBrowseFrameCtrl::OnDestroy() 
{
	CWnd::OnDestroy();
}

void CBrowseFrameCtrl::OnSkinChange()
{
	Skin.CreateToolBar( _T("CBrowseTree.Top"), &m_wndTreeTop );
}

void CBrowseFrameCtrl::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize( nType, cx, cy );
	
	CRect rc;
	GetClientRect( &rc );
	
	if ( rc.Height() < 32 ) return;
	
	if ( rc.Width() < m_nTreeSize + SPLIT_SIZE )
	{
		m_nTreeSize = max( 0, rc.Width() - SPLIT_SIZE );
	}
	
	HDWP hDWP = BeginDeferWindowPos( 4 );
	
	if ( m_bTreeVisible )
	{
		DeferWindowPos( hDWP, m_wndTreeTop, NULL, rc.left, rc.top, m_nTreeSize,
			BAR_HEIGHT, SWP_SHOWWINDOW );
		DeferWindowPos( hDWP, m_wndTree, NULL, rc.left, rc.top + BAR_HEIGHT, m_nTreeSize,
			rc.Height() - BAR_HEIGHT, SWP_SHOWWINDOW );
		rc.left += m_nTreeSize + SPLIT_SIZE;
	}
	else
	{
		m_wndTreeTop.ShowWindow( SW_HIDE );
		m_wndTree.ShowWindow( SW_HIDE );
	}
	
	rc.top ++;
	
	if ( rc.Height() < m_nPanelSize + SPLIT_SIZE )
	{
		m_nPanelSize = max( 0, rc.Height() - SPLIT_SIZE );
	}
	
	if ( m_bPanelEnable && m_bPanelVisible )
	{
		DeferWindowPos( hDWP, m_wndDetails, NULL, rc.left, rc.bottom - m_nPanelSize, rc.Width(),
			m_nPanelSize, SWP_NOZORDER|SWP_SHOWWINDOW );
		rc.bottom -= m_nPanelSize + SPLIT_SIZE;
	}
	else
	{
		m_wndDetails.ShowWindow( SW_HIDE );
	}
	
	DeferWindowPos( hDWP, m_wndList->GetSafeHwnd(), NULL, rc.left, rc.top,
		rc.Width(), rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW );
	
	EndDeferWindowPos( hDWP );
}

void CBrowseFrameCtrl::OnPaint() 
{
	CPaintDC dc( this );
	CRect rcClient;
	
	GetClientRect( &rcClient );
	
	CRect rcBar(	rcClient.left + m_nTreeSize,
					rcClient.top,
					rcClient.left + m_nTreeSize + SPLIT_SIZE,
					rcClient.bottom );
	
	if ( m_wndTree.IsWindowVisible() )
	{
		dc.FillSolidRect( rcBar.left, rcBar.top, 1, rcBar.Height(), GetSysColor( COLOR_BTNFACE ) );
		dc.FillSolidRect( rcBar.left + 1, rcBar.top, 1, rcBar.Height(), GetSysColor( COLOR_3DHIGHLIGHT ) );
		dc.FillSolidRect( rcBar.right - 1, rcBar.top, 1, rcBar.Height(), GetSysColor( COLOR_3DSHADOW ) );
		dc.FillSolidRect( rcBar.left + 2, rcBar.top, rcBar.Width() - 3, rcBar.Height(), GetSysColor( COLOR_BTNFACE ) );
		dc.ExcludeClipRect( &rcBar );
		dc.FillSolidRect( rcBar.left, rcBar.top, rcClient.right - rcBar.left, 1, GetSysColor( COLOR_3DHIGHLIGHT ) );
	}
	else
	{
		dc.FillSolidRect( rcClient.left, rcClient.top, rcClient.Width(), 1, GetSysColor( COLOR_3DHIGHLIGHT ) );
	}
	
	rcBar.SetRect(	rcClient.left,
					rcClient.bottom - m_nPanelSize - SPLIT_SIZE,
					rcClient.right,
					rcClient.bottom - m_nPanelSize );
	
	if ( m_wndDetails.IsWindowVisible() )
	{
		if ( m_wndTree.IsWindowVisible() ) rcBar.left += m_nTreeSize + SPLIT_SIZE;
		
		dc.FillSolidRect( rcBar.left, rcBar.top, rcBar.Width(), 1, GetSysColor( COLOR_BTNFACE ) );
		dc.FillSolidRect( rcBar.left, rcBar.top + 1, rcBar.Width(), 1, GetSysColor( COLOR_3DHIGHLIGHT ) );
		dc.FillSolidRect( rcBar.left, rcBar.bottom - 1, rcBar.Width(), 1, GetSysColor( COLOR_3DSHADOW ) );
		dc.FillSolidRect( rcBar.left, rcBar.top + 2, rcBar.Width(), rcBar.Height() - 3,
			GetSysColor( COLOR_BTNFACE ) );
		dc.ExcludeClipRect( &rcBar );
	}
}

BOOL CBrowseFrameCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	CRect rcClient, rc;
	CPoint point;
	
	GetCursorPos( &point );
	GetClientRect( &rcClient );
	ClientToScreen( &rcClient );
	
	rc.SetRect(	rcClient.left + m_nTreeSize,
				rcClient.top,
				rcClient.left + m_nTreeSize + SPLIT_SIZE,
				rcClient.bottom );
	
	if ( m_wndTree.IsWindowVisible() && rc.PtInRect( point ) )
	{
		SetCursor( AfxGetApp()->LoadStandardCursor( IDC_SIZEWE ) );
		return TRUE;
	}
	
	rc.SetRect(	rcClient.left,
				rcClient.bottom - m_nPanelSize - SPLIT_SIZE,
				rcClient.right,
				rcClient.bottom - m_nPanelSize );
	
	if ( m_wndTree.IsWindowVisible() ) rc.left += m_nTreeSize + SPLIT_SIZE;
	
	if ( m_wndDetails.IsWindowVisible() && rc.PtInRect( point ) )
	{
		SetCursor( AfxGetApp()->LoadStandardCursor( IDC_SIZENS ) );
		return TRUE;
	}
	
	return CWnd::OnSetCursor( pWnd, nHitTest, message );
}

void CBrowseFrameCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CRect rcClient, rc;
	GetClientRect( &rcClient );
	
	rc.SetRect(	rcClient.left + m_nTreeSize,
				rcClient.top,
				rcClient.left + m_nTreeSize + SPLIT_SIZE,
				rcClient.bottom );
	
	if ( m_wndTree.IsWindowVisible() && rc.PtInRect( point ) )
	{
		DoSizeTree();
		return;
	}
	
	rc.SetRect(	rcClient.left,
				rcClient.bottom - m_nPanelSize - SPLIT_SIZE,
				rcClient.right,
				rcClient.bottom - m_nPanelSize );
	
	if ( m_wndTree.IsWindowVisible() ) rc.left += m_nTreeSize + SPLIT_SIZE;
	
	if ( m_wndDetails.IsWindowVisible() && rc.PtInRect( point ) )
	{
		DoSizePanel();
		return;
	}
	
	CWnd::OnLButtonDown( nFlags, point );
}

BOOL CBrowseFrameCtrl::DoSizeTree()
{
	MSG* pMsg = &AfxGetThreadState()->m_msgCur;
	CRect rcClient;
	CPoint point;
	
	GetClientRect( &rcClient );
	ClientToScreen( &rcClient );
	ClipCursor( &rcClient );
	SetCapture();
	
	GetClientRect( &rcClient );
	
	int nOffset = 0xFFFF;
	
	while ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
	{
		while ( ::PeekMessage( pMsg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ) );
		
		if ( ! AfxGetThread()->PumpMessage() )
		{
			AfxPostQuitMessage( 0 );
			break;
		}
		
		GetCursorPos( &point );
		ScreenToClient( &point );
		
		int nSplit = point.x - rcClient.left;
		
		if ( nOffset == 0xFFFF ) nOffset = m_nTreeSize - nSplit;
		nSplit += nOffset;
		
		nSplit = max( nSplit, 0 );
		nSplit = min( nSplit, rcClient.right - SPLIT_SIZE );
		
		if ( nSplit < 8 )
			nSplit = 0;
		if ( nSplit > rcClient.right - SPLIT_SIZE - 8 )
			nSplit = rcClient.right - SPLIT_SIZE;
		
		if ( nSplit != m_nTreeSize )
		{
			m_nTreeSize = nSplit;
			Settings.Search.BrowseTreeSize = (DWORD)m_nTreeSize;
			OnSize( SIZE_INTERNAL, 0, 0 );
			Invalidate();
		}
	}
	
	ReleaseCapture();
	ClipCursor( NULL );
	
	return TRUE;
}

BOOL CBrowseFrameCtrl::DoSizePanel()
{
	MSG* pMsg = &AfxGetThreadState()->m_msgCur;
	CRect rcClient;
	CPoint point;
	
	GetClientRect( &rcClient );
	if ( m_bTreeVisible ) rcClient.left += m_nTreeSize + SPLIT_SIZE;
	ClientToScreen( &rcClient );
	ClipCursor( &rcClient );
	SetCapture();
	
	ScreenToClient( &rcClient );
	
	int nOffset = 0xFFFF;
	
	while ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
	{
		while ( ::PeekMessage( pMsg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ) );
		
		if ( ! AfxGetThread()->PumpMessage() )
		{
			AfxPostQuitMessage( 0 );
			break;
		}
		
		GetCursorPos( &point );
		ScreenToClient( &point );
		
		int nSplit = rcClient.bottom - point.y;
		
		if ( nOffset == 0xFFFF ) nOffset = m_nPanelSize - nSplit;
		nSplit += nOffset;
		
		if ( nSplit < 8 )
			nSplit = 0;
		if ( nSplit > rcClient.Height() - SPLIT_SIZE - 8 )
			nSplit = rcClient.Height() - SPLIT_SIZE;
		
		if ( nSplit != m_nPanelSize )
		{
			m_nPanelSize = nSplit;
			Settings.Search.DetailPanelSize = nSplit;
			OnSize( SIZE_INTERNAL, 0, 0 );
			Invalidate();
		}
	}
	
	ReleaseCapture();
	ClipCursor( NULL );
	
	return TRUE;
}

void CBrowseFrameCtrl::OnPhysicalTree(CG2Packet* pPacket)
{
	m_pTree[0] = pPacket;
	pPacket->AddRef();
	if ( m_nTree == 0 ) m_wndTree.OnTreePacket( pPacket );
	
	if ( ! m_bTreeVisible )
	{
		m_bTreeVisible = TRUE;
		PostMessage( WM_SIZE, SIZE_INTERNAL, 0 );
	}
}

void CBrowseFrameCtrl::OnVirtualTree(CG2Packet* pPacket)
{
	m_pTree[1] = pPacket;
	pPacket->AddRef();
	if ( m_nTree == 1 ) m_wndTree.OnTreePacket( pPacket );
	
	if ( ! m_bTreeVisible )
	{
		m_bTreeVisible = TRUE;
		PostMessage( WM_SIZE, SIZE_INTERNAL, 0 );
	}
}

void CBrowseFrameCtrl::OnTreeSelection(NMHDR* pNotify, LRESULT* pResult)
{
	CSingleLock pLock( &m_wndList->m_pMatches->m_pSection, TRUE );
	
	CMatchFile** ppFile = m_wndList->m_pMatches->m_pFiles;
	BOOL bGlobal = m_wndTree.GetSelectedCount() == 0;
	
	for ( DWORD nFiles = m_wndList->m_pMatches->m_nFiles ; nFiles ; nFiles--, ppFile++ )
	{
		CMatchFile* pFile = (*ppFile);
		
		for ( CQueryHit* pHit = pFile->m_pHits ; pHit ; pHit = pHit->m_pNext )
		{
			if ( pHit->m_bMatched = bGlobal ) continue;
			
			for (	CBrowseTreeItem* pSel = m_wndTree.GetFirstSelected() ; pSel ;
					pSel = pSel->m_pSelNext )
			{
				SelectTree( pSel, pHit );
			}
		}
	}
	
	CBrowseTreeItem* pTree = m_wndTree.GetFirstSelected();
	
	if ( pTree != NULL && pTree->m_pSelNext == NULL && pTree->m_pSchema != NULL )
	{
		CString strURI = pTree->m_pSchema->GetContainedURI( CSchema::stFile );
		
		if ( strURI.GetLength() &&
			 ( m_wndList->m_pSchema == NULL || m_wndList->m_pSchema->m_sURI != strURI ) )
		{
			if ( CSchema* pSchema = SchemaCache.Get( strURI ) )
			{
				CPtrList pColumns;
				CSchemaColumnsDlg::LoadColumns( pSchema, &pColumns );
				m_wndList->SelectSchema( pSchema, &pColumns );
			}
		}
	}
	
	m_wndList->m_pMatches->Filter();
	m_wndList->Update();
	
	GetOwner()->PostMessage( WM_COMMAND, MAKELONG( IDC_MATCHES, LBN_SELCHANGE ), 0 );
	
	*pResult = 0;
}

void CBrowseFrameCtrl::SelectTree(CBrowseTreeItem* pItem, CQueryHit* pHit)
{
	DWORD* pIndex = pItem->m_pFiles;
	
	for ( DWORD nIndex = pItem->m_nFiles ; nIndex ; nIndex--, pIndex++ )
	{
		if ( (*pIndex) == pHit->m_nIndex )
		{
			pHit->m_bMatched = TRUE;
			return;
		}
	}
	
	if ( pItem->m_bExpanded == TRUE ) return;
	
	CBrowseTreeItem** ppChild = pItem->m_pList;
	
	for ( nIndex = pItem->m_nCount ; nIndex ; nIndex--, ppChild++ )
	{
		SelectTree( *ppChild, pHit );
	}
}

void CBrowseFrameCtrl::OnSelChangeMatches()
{
	CSingleLock pLock( &m_wndList->m_pMatches->m_pSection, TRUE );
	m_wndDetails.Update( m_wndList->m_pMatches->GetSelectedFile( TRUE ) );
	pLock.Unlock();
	
	if ( m_bPanelEnable == FALSE )
	{
		m_bPanelEnable = TRUE;
		OnSize( SIZE_INTERNAL, 0, 0 );
	}
}

void CBrowseFrameCtrl::OnUpdateSearchDetails(CCmdUI* pCmdUI) 
{
	BOOL bVisible = m_bPanelEnable && m_wndList->IsWindowVisible();
	pCmdUI->Enable( bVisible );
	pCmdUI->SetCheck( bVisible && m_bPanelVisible );
}

void CBrowseFrameCtrl::OnSearchDetails() 
{
	m_bPanelVisible = Settings.Search.DetailPanelVisible = ! m_bPanelVisible;
	OnSize( SIZE_INTERNAL, 0, 0 );
}

void CBrowseFrameCtrl::OnUpdateLibraryTreePhysical(CCmdUI *pCmdUI)
{
	pCmdUI->Enable( m_pTree[0] != NULL );
	pCmdUI->SetCheck( m_pTree[0] != NULL && m_nTree == 0 );
}

void CBrowseFrameCtrl::OnLibraryTreePhysical()
{
	if ( m_pTree[0] != NULL )
	{
		m_nTree = 0;
		m_wndTree.OnTreePacket( m_pTree[ m_nTree ] );
	}
}

void CBrowseFrameCtrl::OnUpdateLibraryTreeVirtual(CCmdUI *pCmdUI)
{
	pCmdUI->Enable( m_pTree[1] != NULL );
	pCmdUI->SetCheck( m_pTree[1] != NULL && m_nTree == 1 );
}

void CBrowseFrameCtrl::OnLibraryTreeVirtual()
{
	if ( m_pTree[1] != NULL )
	{
		m_nTree = 1;
		m_wndTree.OnTreePacket( m_pTree[ m_nTree ] );
	}
}

⌨️ 快捷键说明

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