📄 matchobjects.cpp
字号:
UpdateRange( nCount, nCount );
(*pLoop)->m_bSelected = FALSE;
bChanged = TRUE;
}
for ( CQueryHit* pHit = (*pLoop)->m_pHits ; pHit ; pHit = pHit->m_pNext )
{
if ( pHit->m_bSelected )
{
UpdateRange( nCount, nCount );
pHit->m_bSelected = FALSE;
bChanged = TRUE;
}
}
}
m_pSelectedFiles.RemoveAll();
m_pSelectedHits.RemoveAll();
return bChanged;
}
//////////////////////////////////////////////////////////////////////
// CMatchList filter
void CMatchList::Filter()
{
CSingleLock pLock( &m_pSection, TRUE );
Settings.Search.FilterMask = 0;
if ( m_bFilterBusy ) Settings.Search.FilterMask |= ( 1 << 0 );
if ( m_bFilterPush ) Settings.Search.FilterMask |= ( 1 << 1 );
if ( m_bFilterUnstable ) Settings.Search.FilterMask |= ( 1 << 2 );
if ( m_bFilterReject ) Settings.Search.FilterMask |= ( 1 << 3 );
if ( m_bFilterLocal ) Settings.Search.FilterMask |= ( 1 << 4 );
if ( m_bFilterBogus ) Settings.Search.FilterMask |= ( 1 << 5 );
if ( m_pszFilter ) delete [] m_pszFilter;
m_pszFilter = NULL;
if ( m_sFilter.GetLength() )
{
LPCTSTR pszPtr = m_sFilter;
BOOL bQuote = FALSE;
BOOL bNot = FALSE;
int nWordLen = 3;
CStringList pWords;
for ( int nStart = 0, nPos = 0 ; *pszPtr ; nPos++, pszPtr++ )
{
if ( *pszPtr == '\"' || ( ! bQuote && ( *pszPtr == ' ' || *pszPtr == '\t' || *pszPtr == '-' ) ) )
{
if ( nStart < nPos )
{
pWords.AddTail( ( bNot ? '-' : '+' ) + m_sFilter.Mid( nStart, nPos - nStart ) );
nWordLen += ( nPos - nStart ) + 2;
}
nStart = nPos + 1;
if ( *pszPtr == '\"' )
{
bQuote = ! bQuote;
}
else if ( *pszPtr == '-' && ! bQuote )
{
bNot = TRUE;
}
if ( bNot && ! bQuote && *pszPtr != '-' ) bNot = FALSE;
}
}
if ( nStart < nPos )
{
pWords.AddTail( ( bNot ? '-' : '+' ) + m_sFilter.Mid( nStart, nPos - nStart ) );
nWordLen += ( nPos - nStart ) + 2;
}
m_pszFilter = new TCHAR[ nWordLen ];
LPTSTR pszFilter = m_pszFilter;
for ( POSITION pos = pWords.GetHeadPosition() ; pos ; )
{
CString strWord = pWords.GetNext( pos );
CopyMemory( pszFilter, (LPCTSTR)strWord, sizeof(TCHAR) * ( strWord.GetLength() + 1 ) );
pszFilter += strWord.GetLength() + 1;
}
*pszFilter++ = 0;
*pszFilter++ = 0;
}
CMatchFile** pLoop = m_pFiles;
m_nItems = 0;
m_nFilteredFiles = 0;
m_nFilteredHits = 0;
for ( DWORD nCount = m_nFiles, nItems = 0 ; nCount ; nCount--, pLoop++ )
{
if ( nItems = (*pLoop)->Filter() )
{
m_nItems += nItems;
m_nFilteredFiles ++;
m_nFilteredHits += (*pLoop)->m_nFiltered;
}
else
{
if ( (*pLoop)->m_bSelected ) Select( *pLoop, NULL, FALSE );
}
}
SetSortColumn( m_nSortColumn, m_bSortDir < 0 );
UpdateRange();
}
//////////////////////////////////////////////////////////////////////
// CMatchList hit filtering
BOOL CMatchList::FilterHit(CQueryHit* pHit)
{
pHit->m_bFiltered = FALSE;
if ( m_bFilterBusy && pHit->m_bBusy == TS_TRUE ) return FALSE;
if ( m_bFilterPush && pHit->m_bPush == TS_TRUE && pHit->m_nProtocol != PROTOCOL_ED2K ) return FALSE;
if ( m_bFilterUnstable && pHit->m_bStable == TS_FALSE ) return FALSE;
if ( m_bFilterReject && pHit->m_bMatched == FALSE ) return FALSE;
if ( m_bFilterBogus && pHit->m_bBogus ) return FALSE;
if ( m_nFilterMinSize > 0 && pHit->m_nSize < m_nFilterMinSize ) return FALSE;
if ( m_nFilterMaxSize > 0 && pHit->m_nSize > m_nFilterMaxSize ) return FALSE;
if ( m_pszFilter )
{
LPCTSTR pszName = pHit->m_sName;
for ( LPCTSTR pszFilter = m_pszFilter ; *pszFilter ; )
{
if ( *pszFilter == '-' )
{
if ( _tcsistr( pszName, pszFilter + 1 ) != NULL ) return FALSE;
}
else
{
if ( _tcsistr( pszName, pszFilter + 1 ) == NULL ) return FALSE;
}
pszFilter += _tcslen( pszFilter + 1 ) + 2;
}
}
if ( pHit->m_nSpeed )
pHit->m_sSpeed = Settings.SmartVolume( pHit->m_nSpeed, TRUE, TRUE );
else
pHit->m_sSpeed.Empty();
return ( pHit->m_bFiltered = TRUE );
}
//////////////////////////////////////////////////////////////////////
// CMatchList schema selection
void CMatchList::SelectSchema(CSchema* pSchema, CPtrList* pColumns)
{
CSingleLock pLock( &m_pSection, TRUE );
CMatchFile** pLoop = m_pFiles;
for ( DWORD nCount = m_nFiles ; nCount ; nCount--, pLoop++ )
{
if ( (*pLoop)->m_pColumns )
{
delete [] (*pLoop)->m_pColumns;
(*pLoop)->m_pColumns = NULL;
(*pLoop)->m_nColumns = 0;
}
}
if ( m_pColumns ) delete [] m_pColumns;
m_pColumns = NULL;
m_nColumns = 0;
m_pSchema = pSchema;
if ( ! pSchema || ! pColumns ) return;
m_pColumns = new CSchemaMember*[ pColumns->GetCount() ];
for ( POSITION pos = pColumns->GetHeadPosition() ; pos ; )
{
m_pColumns[ m_nColumns++ ] = (CSchemaMember*)pColumns->GetNext( pos );
}
Filter();
}
//////////////////////////////////////////////////////////////////////
// CMatchList sort column selection
void CMatchList::SetSortColumn(int nColumn, BOOL bDirection)
{
m_nSortColumn = nColumn;
m_bSortDir = bDirection ? -1 : 1;
if ( m_nSortColumn < 0 || ! m_nFiles ) return;
int nFirst = 0;
int nLast = m_nFiles - 1;
DWORD nStack = 0;
int nStackFirst[128];
int nStackLast[128];
for ( ; ; )
{
if ( nLast - nFirst <= 16 )
{
int nIndex;
CMatchFile* pPrevious = m_pFiles[ nFirst ];
CMatchFile* pCurrent;
for ( nIndex = nFirst + 1 ; nIndex <= nLast ; ++nIndex )
{
pCurrent = m_pFiles[ nIndex ];
if ( pPrevious->Compare( pCurrent ) == m_bSortDir )
{
int nIndex2;
m_pFiles[ nIndex ] = pPrevious;
for ( nIndex2 = nIndex - 1 ; nIndex2 > nFirst ; )
{
CMatchFile* pTemp = m_pFiles[ nIndex2 - 1 ];
if ( pTemp->Compare( pCurrent ) == m_bSortDir )
{
m_pFiles[ nIndex2-- ] = pTemp;
}
else break;
}
m_pFiles[ nIndex2 ] = pCurrent;
}
else
{
pPrevious = pCurrent;
}
}
}
else
{
CMatchFile* pPivot;
{
CMatchFile* pTemp;
DWORD nMiddle = ( nFirst + nLast ) >> 1;
pTemp = m_pFiles[ nFirst ];
if ( pTemp->Compare( m_pFiles[ nLast ] ) == m_bSortDir )
{
m_pFiles[ nFirst ] = m_pFiles[ nLast ]; m_pFiles[ nLast ] = pTemp;
}
pTemp = m_pFiles[ nMiddle ];
if ( m_pFiles[ nFirst ]->Compare( pTemp ) == m_bSortDir )
{
m_pFiles[ nMiddle ] = m_pFiles[ nFirst ]; m_pFiles[ nFirst ] = pTemp;
}
pTemp = m_pFiles[ nLast ];
if ( m_pFiles[ nMiddle ]->Compare( pTemp ) == m_bSortDir )
{
m_pFiles[ nLast ] = m_pFiles[ nMiddle ]; m_pFiles[ nMiddle ] = pTemp;
}
pPivot = m_pFiles[ nMiddle ];
}
{
DWORD nUp;
{
DWORD nDown = nFirst;
nUp = nLast;
for ( ; ; )
{
do
{
++nDown;
} while ( pPivot->Compare( m_pFiles[ nDown ] ) == m_bSortDir );
do
{
--nUp;
} while ( m_pFiles[ nUp ]->Compare( pPivot ) == m_bSortDir );
if ( nUp > nDown )
{
CMatchFile* pTemp = m_pFiles[ nDown ];
m_pFiles[ nDown ] = m_pFiles[ nUp ];
m_pFiles[ nUp ] = pTemp;
}
else
break;
}
}
{
if ( ( nUp - nFirst + 1 ) >= ( nLast - nUp ) )
{
nStackFirst[ nStack ] = nFirst;
nStackLast[ nStack++ ] = nUp;
nFirst = nUp + 1;
}
else
{
nStackFirst[ nStack ] = nUp + 1;
nStackLast[ nStack++ ] = nLast;
nLast = nUp;
}
}
continue;
}
}
if ( nStack > 0 )
{
nFirst = nStackFirst[ --nStack ];
nLast = nStackLast[ nStack ];
}
else
break;
}
UpdateRange();
}
//////////////////////////////////////////////////////////////////////
// CMatchList updates
void CMatchList::UpdateRange(DWORD nMin, DWORD nMax)
{
m_nUpdateMin = min( m_nUpdateMin, nMin );
m_nUpdateMax = max( m_nUpdateMax, nMax );
m_bUpdated = TRUE;
}
void CMatchList::ClearUpdated()
{
m_bUpdated = FALSE;
m_nUpdateMin = 0xFFFFFFFF;
m_nUpdateMax = 0;
}
//////////////////////////////////////////////////////////////////////
// CMatchList clear new
void CMatchList::ClearNew()
{
CSingleLock pLock( &m_pSection, TRUE );
for ( DWORD nFile = 0 ; nFile < m_nFiles ; nFile++ )
{
m_pFiles[ nFile ]->ClearNew();
}
m_bNew = TRUE;
}
//////////////////////////////////////////////////////////////////////
// CMatchList serialize
void CMatchList::Serialize(CArchive& ar)
{
int nVersion = 11;
if ( ar.IsStoring() )
{
ar << nVersion;
ar << m_sFilter;
ar << m_bFilterBusy;
ar << m_bFilterPush;
ar << m_bFilterUnstable;
ar << m_bFilterReject;
ar << m_bFilterLocal;
ar << m_bFilterBogus;
ar << m_nFilterMinSize;
ar << m_nFilterMaxSize;
ar << m_nFilterSources;
ar << m_nSortColumn;
ar << m_bSortDir;
ar.WriteCount( m_nFiles );
for ( DWORD nFile = 0 ; nFile < m_nFiles ; nFile++ )
{
CMatchFile* pFile = m_pFiles[ nFile ];
pFile->Serialize( ar, nVersion );
}
}
else
{
ar >> nVersion;
if ( nVersion < 8 ) AfxThrowUserException();
ar >> m_sFilter;
ar >> m_bFilterBusy;
ar >> m_bFilterPush;
ar >> m_bFilterUnstable;
ar >> m_bFilterReject;
ar >> m_bFilterLocal;
ar >> m_bFilterBogus;
if ( nVersion >= 10 )
{
ar >> m_nFilterMinSize;
ar >> m_nFilterMaxSize;
}
else
{
DWORD nInt32;
ar >> nInt32; m_nFilterMinSize = nInt32;
ar >> nInt32; m_nFilterMaxSize = nInt32;
}
ar >> m_nFilterSources;
ar >> m_nSortColumn;
ar >> m_bSortDir;
m_nFiles = m_nBuffer = ar.ReadCount();
m_pFiles = new CMatchFile*[ m_nFiles ];
ZeroMemory( m_pFiles, sizeof(CMatchFile*) * m_nFiles );
for ( DWORD nFile = 0 ; nFile < m_nFiles ; nFile++ )
{
CMatchFile* pFile = new CMatchFile( this );
m_pFiles[ nFile ] = pFile;
pFile->Serialize( ar, nVersion );
CMatchFile** pMap = m_pSizeMap + (DWORD)( pFile->m_nSize & 0xFF );
pFile->m_pNextSize = *pMap;
*pMap = pFile;
if ( pFile->m_bSHA1 )
{
pMap = m_pMapSHA1 + ( pFile->m_pSHA1.n[0] );
pFile->m_pNextSHA1 = *pMap;
*pMap = pFile;
}
if ( pFile->m_bTiger )
{
pMap = m_pMapTiger + ( pFile->m_pTiger.n[0] );
pFile->m_pNextTiger = *pMap;
*pMap = pFile;
}
if ( pFile->m_bED2K )
{
pMap = m_pMapED2K + ( pFile->m_pED2K.n[0] );
pFile->m_pNextED2K = *pMap;
*pMap = pFile;
}
}
Filter();
}
}
//////////////////////////////////////////////////////////////////////
// CMatchFile construction
CMatchFile::CMatchFile(CMatchList* pList, CQueryHit* pHit)
{
m_pList = pList;
m_pHits = NULL;
m_pBest = NULL;
m_nTotal = NULL;
m_nFiltered = 0;
m_nSources = 0;
m_pNextSize = NULL;
m_pNextSHA1 = NULL;
m_pNextTiger = NULL;
m_pNextED2K = NULL;
m_bSHA1 = FALSE;
m_bTiger = FALSE;
m_bED2K = FALSE;
m_nSize = pHit ? pHit->m_nSize : 0;
m_sSize = Settings.SmartVolume( m_nSize, FALSE );
m_bBusy = TS_UNKNOWN;
m_bPush = TS_UNKNOWN;
m_bStable = TS_UNKNOWN;
m_bPreview = FALSE;
m_nSpeed = 0;
m_nRating = 0;
m_nRated = 0;
m_bDRM = FALSE;
m_bCollection = FALSE;
m_bExpanded = Settings.Search.ExpandMatches;
m_bSelected = FALSE;
m_bExisting = FALSE;
m_bDownload = FALSE;
m_bNew = FALSE;
m_bOneValid = FALSE;
m_nShellIndex = -1;
m_pColumns = NULL;
m_nColumns = 0;
m_pPreview = NULL;
m_nPreview = 0;
if ( pHit ) Add( pHit );
}
CMatchFile::~CMatchFile()
{
while ( m_pHits )
{
CQueryHit* pNext = m_pHits->m_pNext;
delete m_pHits;
m_pHits = pNext;
}
if ( m_pColumns ) delete [] m_pColumns;
if ( m_pPreview ) delete [] m_pPreview;
}
//////////////////////////////////////////////////////////////////////
// CMatchFile add
BOOL CMatchFile::Add(CQueryHit* pHit, BOOL bForce)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -