void CNewSearchDlg::OnOK()
{
	Settings.SaveWindow( _T("NewSearch"), this );

	m_wndSearch.GetWindowText( m_pSearch->m_sSearch );

	CSchemaPtr pSchema = m_wndSchemas.GetSelected();

	if ( m_pSearch->m_pXML != NULL ) delete m_pSearch->m_pXML;

	m_pSearch->m_pSchema	= NULL;
	m_pSearch->m_pXML		= NULL;

	if ( pSchema != NULL )
	{
		m_pSearch->m_pSchema	= pSchema;
		m_pSearch->m_pXML		= pSchema->Instantiate();

		m_wndSchema.UpdateData( m_pSearch->m_pXML->AddElement( pSchema->m_sSingular ), TRUE );

		Settings.Search.LastSchemaURI = pSchema->GetURI();
	}
	else
	{
		Settings.Search.LastSchemaURI.Empty();
	}

	if ( ! m_pSearch->CheckValid() )
	{
		m_wndSearch.SetFocus();
		return;
	}

	CSkinDialog::OnOK();
}
Beispiel #2
0
bool CLibraryTileItem::Update()
{
	ASSUME_LOCK( Library.m_pSection );

	if ( m_pAlbum->m_nUpdateCookie == m_nCookie ) return false;

	m_nCookie		= m_pAlbum->m_nUpdateCookie;
	m_sTitle		= m_pAlbum->m_sName;
	m_nIcon32		= m_pAlbum->m_pSchema ? m_pAlbum->m_pSchema->m_nIcon32 : -1;
	m_nIcon48		= m_pAlbum->m_pSchema ? m_pAlbum->m_pSchema->m_nIcon48 : -1;
	m_bCollection	= m_pAlbum->m_oCollSHA1.isValid();

	CSchemaPtr pSchema = m_pAlbum->m_pSchema;

	if ( pSchema != NULL && m_pAlbum->m_pXML != NULL )
	{
		m_sSubtitle1 = pSchema->m_sTileLine1;
		m_sSubtitle2 = pSchema->m_sTileLine2;

		pSchema->ResolveTokens( m_sSubtitle1, m_pAlbum->m_pXML );
		pSchema->ResolveTokens( m_sSubtitle2, m_pAlbum->m_pXML );
	}
	else
	{
		m_sSubtitle1.Empty();
		m_sSubtitle2.Empty();
	}

	return true;
}
Beispiel #3
0
void CSchemaCombo::Load(LPCTSTR pszSelectURI, int nType, int nAvailability, BOOL bReset)
{
	if ( ( GetStyle() & CBS_OWNERDRAWVARIABLE ) == 0 )
	{
		ModifyStyle( 0, CBS_OWNERDRAWVARIABLE|CBS_HASSTRINGS );
	}

	SetExtendedUI();

	m_nType			= nType;
	m_nAvailability	= nAvailability;

	if ( bReset ) ResetContent();

	if ( bReset && m_sNoSchemaText.GetLength() )
	{
		SetItemData( AddString( _T(" ") ), 0 );
		SetCurSel( 0 );
	}

	for ( POSITION pos = SchemaCache.GetIterator() ; pos ; )
	{
		CSchemaPtr pSchema = SchemaCache.GetNext( pos );

		BOOL bSelected = pSchema->CheckURI( pszSelectURI );

		if ( ! bReset )
		{
			int nIndex = FindSchema( pSchema );

			if ( nIndex >= 0 )
			{
				if ( bSelected ) SetCurSel( nIndex );
				continue;
			}
		}

		if ( ( bSelected || pSchema->m_nType == nType || nType == -1 ) &&
			 ( bSelected || pSchema->m_nAvailability <= nAvailability ) )
		{
			int nIndex = AddString( pSchema->m_sTitle );
			SetItemData( nIndex, (LPARAM)pSchema );

			if ( bSelected ) SetCurSel( nIndex );
		}
	}

	if ( bReset && nAvailability < CSchema::saMax )
	{
		SetItemData( AddString( _T("ZZZ") ), 0 );
	}
}
Beispiel #4
0
void CSchemaCombo::Select(LPCTSTR pszURI)
{
	for ( int nItem = 0 ; nItem < GetCount() ; nItem++ )
	{
		CSchemaPtr pSchema = (CSchemaPtr)GetItemData( nItem );

		if ( pSchema != NULL && pSchema->CheckURI( pszURI ) )
		{
			SetCurSel( nItem );
			return;
		}
	}

	SetCurSel( 0 );
}
Beispiel #5
0
void CSearchPanel::OnSchemaChange()
{
	CSchemaPtr pSchema = m_boxSearch.m_wndSchemas.GetSelected();
	
	m_boxSchema.m_wndSchema.SetSchema( pSchema, TRUE );
	m_boxSchema.SetSize( pSchema != NULL ? 1 : 0 );
	
	if ( pSchema != NULL )
	{
		HICON hIcon = ShellIcons.ExtractIcon( pSchema->m_nIcon16, 16 );
		m_boxSchema.SetIcon( hIcon );
		CString strTitle = pSchema->m_sTitle;
		int nPos = strTitle.Find( ':' );
		if ( nPos > 0 ) strTitle = strTitle.Mid( nPos + 1 );
		m_boxSchema.SetCaption( strTitle );
	}

	CBaseMatchWnd* pMainSearchFrame = static_cast< CBaseMatchWnd* >(GetParent());
	if ( pMainSearchFrame )
	{
		CList< CSchemaMember* > pColumns;

		if ( pSchema )
		{
			CString strMembers = pSchema->m_sDefaultColumns;
			for ( POSITION pos = pSchema->GetMemberIterator() ; pos ; )
			{
				CSchemaMember* pMember = pSchema->GetNextMember( pos );

				if ( strMembers.Find( _T("|") + pMember->m_sName + _T("|") ) >= 0 )
					pColumns.AddTail( pMember );
			}
		}

		pMainSearchFrame->m_wndList.SelectSchema( pSchema, &pColumns );
	}
}
Beispiel #6
0
void CHomeSearchCtrl::Search(bool bAutostart)
{
	CString strText, strURI, strEntry, strClear;

	m_wndText.GetWindowText( strText );
	strText.TrimLeft();
	strText.TrimRight();

	LoadString( strClear, IDS_SEARCH_PAD_CLEAR_HISTORY );
	if ( _tcscmp ( strClear , strText ) == 0 ) return;

	// Check if user mistakenly pasted download link to search input box
	if (theApp.OpenURL( strText, TRUE, TRUE ) )
	{
		m_wndText.SetWindowText( _T("") );
		return;
	}

	CSchemaPtr pSchema = m_wndSchema.GetSelected();
	if ( pSchema != NULL ) strURI = pSchema->GetURI();

	Settings.Search.LastSchemaURI = strURI;

	CQuerySearchPtr pSearch = new CQuerySearch();
	pSearch->m_bAutostart	= bAutostart;
	pSearch->m_sSearch		= strText;
	pSearch->m_pSchema		= pSchema;
	BOOL bValid = pSearch->CheckValid( false );
	if ( ! bValid && bAutostart )
	{
		// Invalid search, open help window
		CQuerySearch::SearchHelp();
	}
	else if ( AdultFilter.IsSearchFiltered( pSearch->m_sSearch ) && bAutostart )
	{
		// Adult search blocked, open help window
		CHelpDlg::Show( _T("SearchHelp.AdultSearch") );
	}
	else
	{
		if ( bValid )
		{
			// Load all
			CStringList oList;
			for ( int i = 0; ; i++ )
			{
				strEntry.Format( _T("Search.%.2i"), i + 1 );
				CString strValue( theApp.GetProfileString( _T("Search"), strEntry ) );
				if ( strValue.IsEmpty() )
					break;
				int lf = strValue.Find( _T('\n') );
				if ( strText.CompareNoCase( ( lf != -1 ) ? strValue.Left( lf ) : strValue ) )
					oList.AddTail( strValue );
			}

			// Cut to 200 items
			while ( oList.GetCount() >= 200 )
				oList.RemoveTail();

			// New one (at top)
			oList.AddHead( strURI.IsEmpty() ? strText : ( strText + _T('\n') + strURI ) );

			// Save list
			POSITION pos = oList.GetHeadPosition();
			for ( int i = 0; pos; ++i )
			{
				strEntry.Format( _T("Search.%.2i"), i + 1 );
				theApp.WriteProfileString( _T("Search"), strEntry, oList.GetNext( pos ) );
			}

			FillHistory();
		}

		new CSearchWnd( pSearch );
	}

	m_wndText.SetWindowText( _T("") );
}
Beispiel #7
0
void CRemote::PageSearch()
{
	if ( CheckCookie() ) return;
	m_nTab = tabSearch;

	CMainWnd* pMainWnd = static_cast< CMainWnd* >( theApp.m_pMainWnd );
	if ( pMainWnd == NULL || ! pMainWnd->IsKindOf( RUNTIME_CLASS(CMainWnd) ) ) return;

	CSingleLock pLock( &theApp.m_pSection );
	if ( ! SafeLock( pLock ) ) return;

	INT_PTR nSearchID = NULL;
	INT_PTR nCloseID = NULL;
	CSearchWnd* pSearchWnd = NULL;
	CString str;

	_stscanf( GetKey( L"id" ), L"%Ii", &nSearchID );
	_stscanf( GetKey( L"close" ), L"%Ii", &nCloseID );

	Prepare();		// Header
	Output( L"searchHeader" );

	for ( CSearchWnd* pFindWnd = NULL; ( pFindWnd = static_cast< CSearchWnd* >( pMainWnd->m_pWindows.Find( RUNTIME_CLASS(CSearchWnd), pFindWnd ) ) ) != NULL; )
	{
		Prepare();
		INT_PTR nFindWnd = reinterpret_cast< INT_PTR >( pFindWnd );
		if ( nCloseID == nFindWnd )
		{
			pFindWnd->PostMessage( WM_CLOSE );
			continue;
		}
		else if ( nSearchID == nFindWnd )
		{
			pSearchWnd = pFindWnd;
			Add( L"search_selected", L"true" );
		}

		str.Format( L"%Ii", nFindWnd );
		Add( L"search_id", str );
		str = pFindWnd->GetCaption();
		if ( str.Find( L"Search : " ) == 0 ) str = str.Mid( 9 ).SpanExcluding( L"[" );
		Add( L"search_caption", str );
		Output( L"searchTab" );
	}

	if ( pSearchWnd == NULL )
	{
		str.Empty();

		for ( POSITION pos = SchemaCache.GetIterator(); pos != NULL; )
		{
			CSchemaPtr pSchema = SchemaCache.GetNext( pos );
			if ( ! pSchema->m_bPrivate && pSchema->m_nType == CSchema::stFile )
			{
				str += L"<option value=\"" + pSchema->GetURI();
				str += L"\">" + pSchema->m_sTitle;
				str += L"</option>\r\n";
			}
		}

		Prepare();		// Header
		Add( L"schema_option_list", str );
		Output( L"searchNew" );
		Output( L"searchFooter" );
		return;
	}

	if ( ! GetKey( L"stop" ).IsEmpty() )
	{
		pSearchWnd->PostMessage( WM_COMMAND, ID_SEARCH_STOP );
		Sleep( 500 );
	}

	CLockedMatchList pMatches( pSearchWnd->GetMatches() );

	str = GetKey( L"sort" );
	if ( ! str.IsEmpty() )
	{
		int nColumn = 0;
		_stscanf( str, L"%i", &nColumn );

		if ( pMatches->m_bSortDir != 1 && pMatches->m_nSortColumn == nColumn )
			pMatches->SetSortColumn( nColumn, FALSE );
		else
			pMatches->SetSortColumn( nColumn, TRUE );

		pSearchWnd->PostMessage( WM_TIMER, 7 );
	}

	str = GetKey( L"expcol" );
	if ( ! str.IsEmpty() )
	{
		CMatchFile** pLoop = pMatches->m_pFiles;
		for ( DWORD nCount = 0; nCount < pMatches->m_nFiles; nCount++, pLoop++ )
		{
			if ( (*pLoop)->GetURN() == str )
			{
				(*pLoop)->Expand( GetKey( L"collapse" ).IsEmpty() );
				pSearchWnd->PostMessage( WM_TIMER, 7 );
				break;
			}
		}
	}

	str = GetKey( L"download" );
	if ( ! str.IsEmpty() )
	{
		CMatchFile** pLoop = pMatches->m_pFiles;
		for ( DWORD nCount = 0; nCount < pMatches->m_nFiles; nCount++, pLoop++ )
		{
			if ( (*pLoop)->GetURN() == str )
			{
				Downloads.Add( *pLoop );
				pSearchWnd->PostMessage( WM_TIMER, 7 );
				m_sResponse.Empty();
				m_sRedirect = L"downloads?group_reveal=all";
				return;
			}
		}
	}

	if ( ! GetKey( L"setfilter" ).IsEmpty() )
	{
		pMatches->m_sFilter = GetKey( L"filter" );
		pMatches->Filter();
		pSearchWnd->PostMessage( WM_TIMER, 7 );
	}

	Prepare();		// Header
	str.Format( L"%Ii", nSearchID );
	Add( L"search_id", str );
	str.Format( L"%i", GetRandomNum( 0i32, _I32_MAX ) );
	Add( L"random", str );
	if ( ! pSearchWnd->IsPaused() )
		Add( L"searching", L"true" );
	Add( L"search_filter", pMatches->m_sFilter );
	Output( L"searchTop" );

	PageSearchHeaderColumn( MATCH_COL_NAME, Skin.GetHeaderTranslation( L"CMatchCtrl", L"File" ), L"left" );
	PageSearchHeaderColumn( MATCH_COL_SIZE, Skin.GetHeaderTranslation( L"CMatchCtrl", L"Size" ), L"center" );
	PageSearchHeaderColumn( MATCH_COL_RATING, Skin.GetHeaderTranslation( L"CMatchCtrl", L"Rating" ), L"center" );
	PageSearchHeaderColumn( MATCH_COL_STATUS, Skin.GetHeaderTranslation( L"CMatchCtrl", L"Status" ), L"center" );
	PageSearchHeaderColumn( MATCH_COL_COUNT, Skin.GetHeaderTranslation( L"CMatchCtrl", L"Host/Count" ), L"center" );
	PageSearchHeaderColumn( MATCH_COL_SPEED, Skin.GetHeaderTranslation( L"CMatchCtrl", L"Speed" ), L"center" );
	PageSearchHeaderColumn( MATCH_COL_CLIENT, Skin.GetHeaderTranslation( L"CMatchCtrl", L"Client" ), L"center" );

	Output( L"searchMiddle" );

	CMatchFile** pLoop = pMatches->m_pFiles;

	for ( DWORD nCount = 0; nCount < pMatches->m_nFiles; nCount++, pLoop++ )
	{
		CMatchFile* pFile = *pLoop;
		if ( pFile->GetFilteredCount() == 0 ) continue;

		Add( L"row_urn", pFile->GetURN() );
		Add( L"row_filename", pFile->m_sName );
		if ( pFile->GetFilteredCount() <= 1 )
			Add( L"row_single", L"true" );
		else if ( pFile->m_bExpanded )
			Add( L"row_expanded", L"true" );
		else
			Add( L"row_collapsed", L"true" );

		Output( L"searchRowStart" );

		PageSearchRowColumn( MATCH_COL_SIZE, pFile, Settings.SmartVolume( pFile->m_nSize ) );

		str.Empty();
		for ( INT_PTR nStar = pFile->m_nRating / max( 1, pFile->m_nRated ); nStar > 1; nStar -- ) str += L'*';
		PageSearchRowColumn( MATCH_COL_RATING, pFile, str );

		str.Empty();
		str += pFile->m_bBusy == TRI_TRUE ? L'B' : L'-';
		str += pFile->m_bPush == TRI_TRUE ? L'F' : L'-';
		str += pFile->m_bStable == TRI_FALSE ? L'U' : L'-';
		PageSearchRowColumn( MATCH_COL_STATUS, pFile, str );

		str.Empty();
		if ( pFile->GetFilteredCount() > 1 )
			str.Format(L"(%u sources)", pFile->GetFilteredCount());
		else
			str = (CString)inet_ntoa( pFile->GetBestAddress() );
		PageSearchRowColumn( MATCH_COL_COUNT, pFile, str );


		PageSearchRowColumn( MATCH_COL_SPEED, pFile, pFile->m_sSpeed );
		PageSearchRowColumn( MATCH_COL_CLIENT, pFile, pFile->GetFilteredCount() == 1 ? pFile->GetBestVendorName() : L"" );

		Output( L"searchRowEnd" );
		Prepare( L"column_" );
		Prepare( L"row_" );

		if ( pFile->m_bExpanded )
		{
			for ( CQueryHit* pHit = pFile->GetHits(); pHit != NULL; pHit = pHit->m_pNext )
			{
				if ( ! pHit->m_bFiltered ) continue;

				Add( L"row_urn", pFile->GetURN() );
				Add( L"row_filename", pHit->m_sName );
				Add( L"row_source", L"true" );
				Output( L"searchRowStart" );

				PageSearchRowColumn( MATCH_COL_SIZE, pFile, Settings.SmartVolume( pHit->m_nSize ) );
				str.Empty();
				for ( int nStar = pHit->m_nRating; nStar > 1; nStar -- ) str += L"*";
				PageSearchRowColumn( MATCH_COL_RATING, pFile, str );

				str.Empty();
				str += pFile->m_bBusy == TRI_TRUE ? L'B' : L'-';
				str += pFile->m_bPush == TRI_TRUE ? L'F' : L'-';
				str += pFile->m_bStable == TRI_FALSE ? L'U' : L'-';
				PageSearchRowColumn( MATCH_COL_STATUS, pFile, str );

				PageSearchRowColumn( MATCH_COL_COUNT, pFile, (CString)inet_ntoa( pHit->m_pAddress ) );
				PageSearchRowColumn( MATCH_COL_SPEED, pFile, pHit->m_sSpeed );
				PageSearchRowColumn( MATCH_COL_CLIENT, pFile, pHit->m_pVendor->m_sName );

				Output( L"searchRowEnd" );
				Prepare( L"column_" );
				Prepare( L"row_" );
			}
		}
	}

	Output( L"searchBottom" );
	Prepare();
	Output( L"searchFooter" );
}
void CLibraryAlbumView::Update()
{
	CLibraryTreeItem* pFolders = GetFolderSelection();

	m_pStaticStyle = m_pStyle;
	m_pStyle = NULL;
	BOOL bGhostFolder = FALSE;

	if ( pFolders != NULL && pFolders->m_pVirtual != NULL && pFolders->m_pSelNext == NULL )
	{
		CAlbumFolder* pFolder = pFolders->m_pVirtual;

		if ( CheckURI( pFolder->m_sSchemaURI, CSchema::uriMusicAlbum ) )
			m_pStyle = CSchema::uriMusicAlbum;
		else if ( CheckURI( pFolder->m_sSchemaURI, CSchema::uriMusicArtist ) )
			m_pStyle = CSchema::uriMusicArtist;
		else if ( CheckURI( pFolder->m_sSchemaURI, CSchema::uriMusicAll ) || CheckURI( pFolder->m_sSchemaURI, CSchema::uriMusicGenre ) )
			m_pStyle = CSchema::uriMusicAll;
		else if ( CheckURI( pFolder->m_sSchemaURI, CSchema::uriGhostFolder ) )
			bGhostFolder = TRUE;
	}

	CSchemaPtr pSchema	= SchemaCache.Get( Settings.Library.FilterURI );
	DWORD nCookie		= GetFolderCookie();
	BOOL bChanged		= m_pStyle != m_pStaticStyle;

	if ( Settings.Library.ShowVirtual )
		pSchema = NULL;

	CLibraryAlbumTrack** pList = m_pList + m_nCount - 1;

	for ( int nItem = m_nCount ; nItem ; nItem--, pList-- )
	{
		CLibraryAlbumTrack* pTrack	= *pList;
		CLibraryFile* pFile			= Library.LookupFile( pTrack->m_nIndex );

		if ( pFile != NULL && pFile->m_nSelectCookie == nCookie &&
			 ( pFile->IsAvailable() || bGhostFolder ) &&
			 ( ! pSchema || pSchema->Equals( pFile->m_pSchema ) ||
			 ( ! pFile->m_pMetadata && pSchema->FilterType( pFile->m_sName ) ) ) )
		{
			bChanged |= pTrack->Update( pFile );
			pFile->m_nListCookie = nCookie;
		}
		else
		{
			if ( pTrack == m_pFocus ) m_pFocus = NULL;
			if ( pTrack == m_pFirst ) m_pFirst = NULL;
			if ( pTrack->m_bSelected ) Select( pTrack, TRI_FALSE );
			delete pTrack;
			MoveMemory( pList, pList + 1, ( m_nCount - nItem ) * sizeof *pList );
			m_nCount--;
			bChanged = TRUE;
		}
	}

	if ( bChanged )
	{
		CRect rcClient;
		GetClientRect( &rcClient );
		int nMax	= m_nCount * m_szTrack.cy;
		m_nScroll	= max( 0, min( m_nScroll, nMax - rcClient.Height() + 1 ) );
	}

	for ( POSITION pos = LibraryMaps.GetFileIterator() ; pos ; )
	{
		CLibraryFile* pFile = LibraryMaps.GetNextFile( pos );

		if ( pFile->m_nSelectCookie == nCookie &&
			 pFile->m_nListCookie != nCookie &&
			 ( pFile->IsAvailable() || bGhostFolder ) &&
			 ( ! pSchema || pSchema->Equals( pFile->m_pSchema ) ||
			 ( ! pFile->m_pMetadata && pSchema->FilterType( pFile->m_sName ) ) ) )
		{
			CLibraryAlbumTrack* pTrack = new CLibraryAlbumTrack( pFile );

			if ( m_nCount == m_nBuffer )
			{
				m_nBuffer += 64;
				CLibraryAlbumTrack** pNewList = new CLibraryAlbumTrack*[ m_nBuffer ];
				if ( m_nCount ) CopyMemory( pNewList, m_pList, m_nCount * sizeof( CLibraryAlbumTrack* ) );
				delete [] m_pList;
				m_pList = pNewList;
			}

			m_pList[ m_nCount++ ] = pTrack;
			pFile->m_nListCookie = nCookie;
			bChanged = TRUE;
		}
	}

	if ( bChanged )
	{
		m_pStaticStyle = m_pStyle;
		qsort( m_pList, m_nCount, sizeof *m_pList, SortList );
		UpdateScroll();
	}
}
Beispiel #9
0
void CSchemaCombo::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	if ( lpDrawItemStruct->itemID == (UINT)-1 ) return;
	if ( ( lpDrawItemStruct->itemAction & ODA_SELECT ) == 0 &&
		 ( lpDrawItemStruct->itemAction & ODA_DRAWENTIRE ) == 0 ) return;

	CRect rcItem( &lpDrawItemStruct->rcItem );
	CPoint pt( rcItem.left + 1, rcItem.top + 1 );
	CDC dc;

	dc.Attach( lpDrawItemStruct->hDC );
	if ( Settings.General.LanguageRTL )
		SetLayout( dc.m_hDC, LAYOUT_RTL );

	dc.SetTextColor( ( lpDrawItemStruct->itemState & ODS_SELECTED )
		? CoolInterface.m_crHiText : CoolInterface.m_crDropdownText );

	CSchemaPtr pSchema = (CSchemaPtr)lpDrawItemStruct->itemData;

	if ( pSchema != NULL )
	{
		/*dc.FillSolidRect( &rcItem,
			GetSysColor( ( lpDrawItemStruct->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHT : COLOR_WINDOW ) );*/
		if ( IsWindowEnabled() )
		{
			if ( lpDrawItemStruct->itemState & ODS_SELECTED )
				dc.FillSolidRect( &rcItem, CoolInterface.m_crHighlight );
			else
				dc.FillSolidRect( &rcItem, CoolInterface.m_crDropdownBox );
		}
		else
			dc.FillSolidRect( &rcItem, GetBkColor(lpDrawItemStruct->hDC) );

		dc.SetBkMode( TRANSPARENT );

		ShellIcons.Draw( &dc, pSchema->m_nIcon16, 16, pt.x, pt.y, CLR_NONE,
			( lpDrawItemStruct->itemState & ODS_SELECTED ) );

		rcItem.left += 20; rcItem.right -= 2;

		CFont* pOldFont = (CFont*)dc.SelectObject( &theApp.m_gdiFont );
		CString strURI = pSchema->GetURI();

		if ( dc.GetTextExtent( pSchema->m_sTitle + strURI ).cx > rcItem.Width() - 20
			 && strURI.GetLength() > 8 )
		{
			LPCTSTR pszLeft = _tcschr( (LPCTSTR)strURI + 7, '/' );
			int nRight		= strURI.ReverseFind( '/' );

			if ( pszLeft && nRight >= 0 )
			{
				int nLeft = static_cast< int >( pszLeft - (LPCTSTR)strURI );  // !!! (TODO)
				strURI = strURI.Left( nLeft ) + _T("/\x2026") + strURI.Mid( nRight );
			}
		}

		if ( dc.GetTextExtent( pSchema->m_sTitle + strURI ).cx <= rcItem.Width() - 20 )
		{
			// COLORREF crBackup = dc.SetTextColor( GetSysColor( COLOR_GRAYTEXT ) );
			dc.DrawText( strURI, &rcItem, DT_SINGLELINE|DT_RIGHT|DT_VCENTER|DT_NOPREFIX );
			// dc.SetTextColor( crBackup );
		}

		dc.SelectObject( &theApp.m_gdiFontBold );
		dc.DrawText( pSchema->m_sTitle, &rcItem, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_NOPREFIX );
		dc.SelectObject( pOldFont );
	}
	else if ( lpDrawItemStruct->itemID == 0 )
	{
		/*dc.FillSolidRect( &rcItem,
			GetSysColor( ( lpDrawItemStruct->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHT : COLOR_WINDOW ) );*/
		if ( IsWindowEnabled() )
		{
			if ( lpDrawItemStruct->itemState & ODS_SELECTED )
				dc.FillSolidRect( &rcItem, CoolInterface.m_crHighlight );
			else
				dc.FillSolidRect( &rcItem, CoolInterface.m_crDropdownBox );
		}
		else
			dc.FillSolidRect( &rcItem, GetBkColor(lpDrawItemStruct->hDC) );
		dc.SetBkMode( TRANSPARENT );

		CoolInterface.Draw( &dc, IDR_SEARCHFRAME, 16,
			pt.x, pt.y, CLR_NONE, ( lpDrawItemStruct->itemState & ODS_SELECTED ) );

		rcItem.left += 20; rcItem.right -= 2;

		CFont* pOldFont = (CFont*)dc.SelectObject( &theApp.m_gdiFontBold );
		dc.DrawText( m_sNoSchemaText, &rcItem, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_NOPREFIX );
		dc.SelectObject( pOldFont );
	}
	else
	{
		dc.Draw3dRect( &rcItem, CoolInterface.m_crDropdownBox , CoolInterface.m_crDropdownBox );
		rcItem.DeflateRect( 1, 1 );

		if ( lpDrawItemStruct->itemState & ODS_SELECTED )
		{
			dc.Draw3dRect( &rcItem, CoolInterface.m_crBorder, CoolInterface.m_crBorder );
			rcItem.DeflateRect( 1, 1 );
			dc.FillSolidRect( &rcItem, CoolInterface.m_crBackSel );
		}
		else
		{
			dc.FillSolidRect( &rcItem, GetSysColor( COLOR_WINDOW /* COLOR_BTNFACE */ ) );
		}

		dc.SetBkMode( TRANSPARENT );

		pt = rcItem.CenterPoint();
		pt.x -= 8;
		pt.y -= 8;

		CoolInterface.Draw( &dc, IDI_CHEVRON, 16, pt.x, pt.y );
	}

	dc.Detach();
}