Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

881 lines
18 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include <windows.h>
  8. #include "resource.h"
  9. #include "vcdbrowser.h"
  10. #include "SoundEmitterSystem/isoundemittersystembase.h"
  11. #include "filesystem.h"
  12. #include "tabwindow.h"
  13. #include "inputproperties.h"
  14. #include "choreowidgetdrawhelper.h"
  15. #include "UtlBuffer.h"
  16. #include "ChoreoEvent.h"
  17. #include "ChoreoView.h"
  18. CVCDBrowser *g_pVCDBrowser = NULL;
  19. enum
  20. {
  21. // Controls
  22. IDC_VB_LISTVIEW = 101,
  23. IDC_VB_FILETREE,
  24. // Messages
  25. IDC_VB_OPENVCD = 1000,
  26. };
  27. enum
  28. {
  29. COL_VCD = 0,
  30. };
  31. class CVCDList : public mxListView
  32. {
  33. public:
  34. CVCDList( mxWindow *parent, int id = 0 )
  35. : mxListView( parent, 0, 0, 0, 0, id )
  36. {
  37. // Add column headers
  38. insertTextColumn( COL_VCD, 700, "VCD" );
  39. }
  40. };
  41. class CUtlSymbolTree : public mxTreeView
  42. {
  43. public:
  44. CUtlSymbolTree( mxWindow *parent, int id = 0 ) : mxTreeView( parent, 0, 0, 0, 0, id ),
  45. m_Paths( 0, 0, FileTreeLessFunc )
  46. {
  47. }
  48. void Clear()
  49. {
  50. removeAll();
  51. m_Paths.RemoveAll();
  52. }
  53. void FindOrAddSubdirectory( char const *subdir )
  54. {
  55. FileTreePath fp;
  56. Q_strcpy( fp.path, subdir );
  57. if ( m_Paths.Find( fp ) != m_Paths.InvalidIndex() )
  58. return;
  59. m_Paths.Insert( fp );
  60. }
  61. mxTreeViewItem *FindOrAddChildItem( mxTreeViewItem *parent, char const *child )
  62. {
  63. mxTreeViewItem *p = getFirstChild( parent );
  64. if ( !p )
  65. {
  66. return add( parent, child );
  67. }
  68. while ( p )
  69. {
  70. if ( !Q_stricmp( getLabel( p ), child ) )
  71. return p;
  72. p = getNextChild( p );
  73. }
  74. return add( parent, child );
  75. }
  76. void _PopulateTree( int pathId, char const *path )
  77. {
  78. char sz[ 512 ];
  79. Q_strcpy( sz, path );
  80. char *p = sz;
  81. // Start at root
  82. mxTreeViewItem *cur = NULL;
  83. // Tokenize path
  84. while ( p && p[0] )
  85. {
  86. char *slash = Q_strstr( p, "/" );
  87. if ( !slash )
  88. {
  89. slash = Q_strstr( p, "\\" );
  90. }
  91. char *check = p;
  92. if ( slash )
  93. {
  94. *slash = 0;
  95. // see if a child of current already exists with this name
  96. p = slash + 1;
  97. }
  98. else
  99. {
  100. p = NULL;
  101. }
  102. Assert( check );
  103. cur = FindOrAddChildItem( cur, check );
  104. }
  105. setUserData( cur, (void *)pathId );
  106. }
  107. char const *GetSelectedPath( void )
  108. {
  109. mxTreeViewItem *tvi = getSelectedItem();
  110. unsigned int id = (unsigned int)getUserData( tvi );
  111. if ( id < 0 || id >= m_Paths.Count() )
  112. {
  113. Assert( 0 );
  114. return "";
  115. }
  116. return m_Paths[ id ].path;
  117. }
  118. void PopulateTree()
  119. {
  120. int i;
  121. for ( i = m_Paths.FirstInorder(); i != m_Paths.InvalidIndex(); i = m_Paths.NextInorder( i ) )
  122. {
  123. _PopulateTree( i, m_Paths[ i ].path );
  124. }
  125. mxTreeViewItem *p = getFirstChild( NULL );
  126. setOpen( p, true );
  127. }
  128. struct FileTreePath
  129. {
  130. char path[ MAX_PATH ];
  131. };
  132. static bool FileTreeLessFunc( const FileTreePath &lhs, const FileTreePath &rhs )
  133. {
  134. return Q_stricmp( lhs.path, rhs.path ) < 0;
  135. }
  136. CUtlRBTree< FileTreePath, int > m_Paths;
  137. };
  138. #pragma optimize( "", off )
  139. class CVCDOptionsWindow : public mxWindow
  140. {
  141. typedef mxWindow BaseClass;
  142. public:
  143. enum
  144. {
  145. IDC_OPENFILE = 1000,
  146. IDC_SEARCH,
  147. IDC_CANCELSEARCH,
  148. };
  149. CVCDOptionsWindow( CVCDBrowser *browser ) : BaseClass( browser, 0, 0, 0, 0 ), m_pBrowser( browser )
  150. {
  151. FacePoser_AddWindowStyle( this, WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
  152. m_szSearchString[0]=0;
  153. m_pOpen = new mxButton( this, 0, 0, 0, 0, "Open", IDC_OPENFILE );
  154. m_pSearch = new mxLineEdit( this, 0, 0, 0, 0, "", IDC_SEARCH );
  155. m_pCancelSearch = new mxButton( this, 0, 0, 0, 0, "Cancel", IDC_CANCELSEARCH );
  156. }
  157. bool PaintBackground( void )
  158. {
  159. redraw();
  160. return false;
  161. }
  162. virtual void redraw()
  163. {
  164. CChoreoWidgetDrawHelper drawHelper( this, RGBToColor( GetSysColor( COLOR_BTNFACE ) ) );
  165. }
  166. virtual int handleEvent( mxEvent *event )
  167. {
  168. int iret = 0;
  169. switch ( event->event )
  170. {
  171. default:
  172. break;
  173. case mxEvent::Size:
  174. {
  175. iret = 1;
  176. int split = 120;
  177. int x = 1;
  178. m_pOpen->setBounds( x, 1, split, h2() - 2 );
  179. x += split + 10;
  180. m_pCancelSearch->setBounds( x, 1, split, h2() - 2 );
  181. x += split + 10;
  182. m_pSearch->setBounds( x, 0, split * 3, h2() - 1 );
  183. x += split * 3 + 10;
  184. }
  185. break;
  186. case mxEvent::KeyDown:
  187. switch ( event->action )
  188. {
  189. default:
  190. break;
  191. case IDC_SEARCH:
  192. {
  193. if ( event->event == mxEvent::KeyDown )
  194. {
  195. OnSearch();
  196. }
  197. iret = 1;
  198. };
  199. break;
  200. }
  201. break;
  202. case mxEvent::Action:
  203. {
  204. switch ( event->action )
  205. {
  206. case IDC_SEARCH:
  207. iret = 1;
  208. break;
  209. case IDC_OPENFILE:
  210. {
  211. iret = 1;
  212. m_pBrowser->OnOpen();
  213. }
  214. break;
  215. case IDC_CANCELSEARCH:
  216. {
  217. iret = 1;
  218. OnCancelSearch();
  219. }
  220. break;
  221. default:
  222. break;
  223. }
  224. }
  225. break;
  226. }
  227. return iret;
  228. }
  229. char const *GetSearchString()
  230. {
  231. return m_szSearchString;
  232. }
  233. void OnSearch()
  234. {
  235. m_pSearch->getText( m_szSearchString, sizeof( m_szSearchString ) );
  236. m_pBrowser->OnSearch();
  237. }
  238. void OnCancelSearch()
  239. {
  240. m_szSearchString[ 0 ] = 0;
  241. m_pSearch->clear();
  242. m_pBrowser->OnCancelSearch();
  243. }
  244. private:
  245. mxButton *m_pOpen;
  246. mxLineEdit *m_pSearch;
  247. mxButton *m_pCancelSearch;
  248. CVCDBrowser *m_pBrowser;
  249. char m_szSearchString[ 256 ];
  250. };
  251. #pragma optimize( "", on )
  252. //-----------------------------------------------------------------------------
  253. // Purpose:
  254. // Input : *parent -
  255. //-----------------------------------------------------------------------------
  256. CVCDBrowser::CVCDBrowser( mxWindow *parent )
  257. : IFacePoserToolWindow( "VCDBrowser", "VCDs" ), mxWindow( parent, 0, 0, 0, 0 )
  258. {
  259. SetAutoProcess( false );
  260. m_bTextSearch = false;
  261. m_nPrevProcessed = -1;
  262. m_pListView = new CVCDList( this, IDC_VB_LISTVIEW );
  263. m_pOptions = new CVCDOptionsWindow( this );
  264. m_pFileTree = new CUtlSymbolTree( this, IDC_VB_FILETREE );
  265. //HIMAGELIST list = CreateImageList();
  266. // Associate the image list with the tree-view control.
  267. //m_pListView->setImageList( (void *)list );
  268. LoadAllSounds();
  269. PopulateTree( NULL );
  270. }
  271. #define CX_ICON 16
  272. #define CY_ICON 16
  273. HIMAGELIST CVCDBrowser::CreateImageList()
  274. {
  275. HIMAGELIST list;
  276. list = ImageList_Create( CX_ICON, CY_ICON,
  277. FALSE, VCD_NUM_IMAGES, 0 );
  278. // Load the icon resources, and add the icons to the image list.
  279. HICON hicon;
  280. int slot;
  281. #if defined( _DEBUG )
  282. int c = 0;
  283. #endif
  284. hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_VCD));
  285. slot = ImageList_AddIcon(list, hicon);
  286. Assert( slot == c++ );
  287. DeleteObject( hicon );
  288. return list;
  289. }
  290. //-----------------------------------------------------------------------------
  291. // Purpose:
  292. //-----------------------------------------------------------------------------
  293. void CVCDBrowser::OnDelete()
  294. {
  295. RemoveAllSounds();
  296. }
  297. //-----------------------------------------------------------------------------
  298. // Purpose:
  299. // Input : *event -
  300. // Output : int
  301. //-----------------------------------------------------------------------------
  302. int CVCDBrowser::handleEvent( mxEvent *event )
  303. {
  304. int iret = 0;
  305. if ( HandleToolEvent( event ) )
  306. {
  307. return iret;
  308. }
  309. switch ( event->event )
  310. {
  311. default:
  312. break;
  313. case mxEvent::Action:
  314. {
  315. iret = 1;
  316. switch ( event->action )
  317. {
  318. default:
  319. {
  320. iret = 0;
  321. }
  322. break;
  323. case IDC_VB_LISTVIEW:
  324. {
  325. SetActiveTool( this );
  326. bool rightmouse = ( event->flags == mxEvent::RightClicked ) ? true : false;
  327. bool doubleclicked = ( event->flags == mxEvent::DoubleClicked ) ? true : false;
  328. if ( rightmouse )
  329. {
  330. ShowContextMenu();
  331. }
  332. else if ( doubleclicked )
  333. {
  334. if ( m_pListView->getNumSelected() == 1 )
  335. {
  336. int index = m_pListView->getNextSelectedItem( -1 );
  337. if ( index >= 0 )
  338. {
  339. FileNameHandle_t vcd = (FileNameHandle_t)m_pListView->getUserData( index, 0 );
  340. OpenVCD( vcd );
  341. }
  342. }
  343. }
  344. }
  345. break;
  346. case IDC_VB_FILETREE:
  347. {
  348. SetActiveTool( this );
  349. PopulateTree( m_pFileTree->GetSelectedPath() );
  350. }
  351. break;
  352. case IDC_VB_OPENVCD:
  353. {
  354. OnOpen();
  355. }
  356. break;
  357. }
  358. }
  359. break;
  360. case mxEvent::Size:
  361. {
  362. int optionsh = 20;
  363. m_pOptions->setBounds( 0, 0, w2(), optionsh );
  364. int filetreewidth = 175;
  365. m_pFileTree->setBounds( 0, optionsh, filetreewidth, h2() - optionsh );
  366. m_pListView->setBounds( filetreewidth, optionsh, w2() - filetreewidth, h2() - optionsh );
  367. iret = 1;
  368. }
  369. break;
  370. case mxEvent::Close:
  371. {
  372. iret = 1;
  373. }
  374. break;
  375. }
  376. return iret;
  377. }
  378. bool CVCDBrowser::CNameLessFunc::Less( const FileNameHandle_t &name1, const FileNameHandle_t &name2, void *pContext )
  379. {
  380. if ( name1 < name2 )
  381. return true;
  382. return false;
  383. }
  384. void CVCDBrowser::OpenVCD( const FileNameHandle_t& handle )
  385. {
  386. char fn[ 512 ];
  387. if ( filesystem->String( handle, fn, sizeof( fn ) ) )
  388. {
  389. char pFullPath[MAX_PATH];
  390. const char *pFileName = filesystem->RelativePathToFullPath( fn, "GAME", pFullPath, sizeof(pFullPath) );
  391. if ( !pFileName )
  392. {
  393. pFileName = fn;
  394. }
  395. g_pChoreoView->LoadSceneFromFile( pFileName );
  396. }
  397. }
  398. #define SCENES_PREFIX_LEN 0
  399. //-----------------------------------------------------------------------------
  400. // Finds all .vcd files in a particular directory
  401. //-----------------------------------------------------------------------------
  402. bool CVCDBrowser::LoadVCDsFilesInDirectory( CUtlSortVector< FileNameHandle_t, CNameLessFunc >& soundlist, char const* pDirectoryName, int nDirectoryNameLen )
  403. {
  404. char *pWildCard;
  405. pWildCard = ( char * )stackalloc( nDirectoryNameLen + 7 );
  406. Q_snprintf( pWildCard, nDirectoryNameLen + 7, "%s/*.vcd", pDirectoryName );
  407. if ( !filesystem )
  408. {
  409. return false;
  410. }
  411. FileFindHandle_t findHandle;
  412. const char *pFileName = filesystem->FindFirst( pWildCard, &findHandle );
  413. while( pFileName )
  414. {
  415. if( !filesystem->FindIsDirectory( findHandle ) )
  416. {
  417. // Strip off the 'sound/' part of the name.
  418. char *pFileNameWithPath;
  419. int nAllocSize = nDirectoryNameLen + Q_strlen(pFileName) + 2;
  420. pFileNameWithPath = (char *)stackalloc( nAllocSize );
  421. Q_snprintf( pFileNameWithPath, nAllocSize, "%s/%s", &pDirectoryName[ SCENES_PREFIX_LEN ], pFileName );
  422. Q_strnlwr( pFileNameWithPath, nAllocSize );
  423. FileNameHandle_t vcd;
  424. vcd = filesystem->FindOrAddFileName( pFileNameWithPath );
  425. soundlist.InsertNoSort( vcd );
  426. }
  427. pFileName = filesystem->FindNext( findHandle );
  428. }
  429. m_pFileTree->FindOrAddSubdirectory( &pDirectoryName[ SCENES_PREFIX_LEN ] );
  430. filesystem->FindClose( findHandle );
  431. return true;
  432. }
  433. bool CVCDBrowser::InitDirectoryRecursive( CUtlSortVector< FileNameHandle_t, CNameLessFunc >& soundlist, char const* pDirectoryName )
  434. {
  435. // Compute directory name length
  436. int nDirectoryNameLen = Q_strlen( pDirectoryName );
  437. if (!LoadVCDsFilesInDirectory( soundlist, pDirectoryName, nDirectoryNameLen ) )
  438. return false;
  439. char *pWildCard = ( char * )stackalloc( nDirectoryNameLen + 4 );
  440. strcpy(pWildCard, pDirectoryName);
  441. strcat(pWildCard, "/*.");
  442. int nPathStrLen = nDirectoryNameLen + 1;
  443. FileFindHandle_t findHandle;
  444. const char *pFileName = filesystem->FindFirst( pWildCard, &findHandle );
  445. while( pFileName )
  446. {
  447. if ((pFileName[0] != '.') || (pFileName[1] != '.' && pFileName[1] != 0))
  448. {
  449. if( filesystem->FindIsDirectory( findHandle ) )
  450. {
  451. int fileNameStrLen = Q_strlen( pFileName );
  452. char *pFileNameWithPath = ( char * )stackalloc( nPathStrLen + fileNameStrLen + 1 );
  453. memcpy( pFileNameWithPath, pWildCard, nPathStrLen );
  454. pFileNameWithPath[nPathStrLen] = '\0';
  455. strcat( pFileNameWithPath, pFileName );
  456. if (!InitDirectoryRecursive( soundlist, pFileNameWithPath ))
  457. return false;
  458. }
  459. }
  460. pFileName = filesystem->FindNext( findHandle );
  461. }
  462. return true;
  463. }
  464. void CVCDBrowser::LoadAllSounds()
  465. {
  466. RemoveAllSounds();
  467. Con_Printf( "Building list of all .vcds in sound/ folder\n" );
  468. InitDirectoryRecursive( m_AllVCDs, "scenes" );
  469. m_AllVCDs.RedoSort();
  470. m_pFileTree->PopulateTree();
  471. }
  472. void CVCDBrowser::RemoveAllSounds()
  473. {
  474. m_AllVCDs.Purge();
  475. m_Scripts.RemoveAll();
  476. m_CurrentSelection.RemoveAll();
  477. m_pFileTree->Clear();
  478. }
  479. //-----------------------------------------------------------------------------
  480. // Purpose:
  481. //-----------------------------------------------------------------------------
  482. void CVCDBrowser::PopulateTree( char const *subdirectory )
  483. {
  484. char subdir[ 512 ];
  485. subdir[ 0 ] = 0;
  486. int i;
  487. CUtlSortVector< FileNameHandle_t, CNameLessFunc > sorted( 0, 0 );
  488. char const *texttofind = NULL;
  489. if ( m_bTextSearch )
  490. {
  491. subdirectory = NULL;
  492. texttofind = GetSearchString();
  493. }
  494. int len = 0;
  495. if ( subdirectory )
  496. {
  497. len = Q_strlen( subdirectory );
  498. Q_strncpy( subdir, subdirectory, sizeof( subdir ) );
  499. Q_strlower( subdir );
  500. Q_FixSlashes( subdir );
  501. }
  502. int c = m_AllVCDs.Count();
  503. for ( i = 0; i < c; i++ )
  504. {
  505. const FileNameHandle_t &vcd = m_AllVCDs[ i ];
  506. char name[ 512 ];
  507. if ( !filesystem->String( vcd, name, sizeof( name ) ) )
  508. continue;
  509. if ( subdirectory )
  510. {
  511. if ( Q_strnicmp( subdir, name, len ) )
  512. continue;
  513. }
  514. if ( m_bTextSearch && texttofind )
  515. {
  516. if ( !Q_stristr( name, texttofind ) )
  517. continue;
  518. }
  519. sorted.InsertNoSort( vcd );
  520. }
  521. sorted.RedoSort();
  522. char prevSelectedName[ 512 ];
  523. prevSelectedName[ 0 ] = 0;
  524. if ( m_pListView->getNumSelected() == 1 )
  525. {
  526. int selectedItem = m_pListView->getNextSelectedItem( 0 );
  527. if ( selectedItem >= 0 )
  528. {
  529. // Grab name of previously selected item
  530. Q_strcpy( prevSelectedName, m_pListView->getLabel( selectedItem, 0 ) );
  531. }
  532. }
  533. // Repopulate tree
  534. m_pListView->removeAll();
  535. int loadcount = 0;
  536. m_pListView->setDrawingEnabled( false );
  537. int selectedSlot = -1;
  538. for ( i = 0; i < sorted.Count(); ++i )
  539. {
  540. const FileNameHandle_t &vcd = sorted[ i ];
  541. char name[ 512 ];
  542. if ( !filesystem->String( vcd, name, sizeof( name ) ) )
  543. continue;
  544. int slot = m_pListView->add( name );
  545. m_pListView->setUserData( slot, COL_VCD, (void *)vcd );
  546. if ( !Q_stricmp( prevSelectedName, name ) )
  547. {
  548. selectedSlot = slot;
  549. }
  550. ++loadcount;
  551. }
  552. m_pListView->setDrawingEnabled( true );
  553. if ( selectedSlot != -1 )
  554. {
  555. m_pListView->setSelected( selectedSlot, true );
  556. m_pListView->scrollToItem( selectedSlot );
  557. }
  558. }
  559. void CVCDBrowser::RepopulateTree()
  560. {
  561. PopulateTree( m_pFileTree->GetSelectedPath() );
  562. }
  563. void CVCDBrowser::BuildSelectionList( CUtlVector< FileNameHandle_t >& selected )
  564. {
  565. selected.RemoveAll();
  566. int idx = -1;
  567. do
  568. {
  569. idx = m_pListView->getNextSelectedItem( idx );
  570. if ( idx != -1 )
  571. {
  572. FileNameHandle_t vcd = (FileNameHandle_t)m_pListView->getUserData( idx, 0 );
  573. selected.AddToTail( vcd );
  574. }
  575. } while ( idx != -1 );
  576. }
  577. void CVCDBrowser::ShowContextMenu( void )
  578. {
  579. SetActiveTool( this );
  580. BuildSelectionList( m_CurrentSelection );
  581. if ( m_CurrentSelection.Count() <= 0 )
  582. return;
  583. POINT pt;
  584. GetCursorPos( &pt );
  585. ScreenToClient( (HWND)getHandle(), &pt );
  586. mxPopupMenu *pop = new mxPopupMenu();
  587. if ( m_CurrentSelection.Count() == 1 && m_CurrentSelection[ 0 ] )
  588. {
  589. char sz[ 512 ];
  590. char name[ 512 ];
  591. if ( filesystem->String( m_CurrentSelection[ 0 ], name, sizeof( name ) ) )
  592. {
  593. Q_snprintf( sz, sizeof( sz ), "&Open '%s'", name );
  594. pop->add ( sz, IDC_VB_OPENVCD );
  595. }
  596. }
  597. pop->popup( this, pt.x, pt.y );
  598. }
  599. void CVCDBrowser::OnOpen()
  600. {
  601. SetActiveTool( this );
  602. BuildSelectionList( m_CurrentSelection );
  603. if ( m_CurrentSelection.Count() == 1 )
  604. {
  605. FileNameHandle_t& vcd = m_CurrentSelection[ 0 ];
  606. OpenVCD( vcd );
  607. }
  608. }
  609. static void SplitFileName( char const *in, char *path, int maxpath, char *filename, int maxfilename )
  610. {
  611. char drive[_MAX_DRIVE];
  612. char dir[_MAX_DIR];
  613. char fname[_MAX_FNAME];
  614. char ext[_MAX_EXT];
  615. _splitpath( in, drive, dir, fname, ext );
  616. if ( dir[0] )
  617. {
  618. Q_snprintf( path, maxpath, "\\%s", dir );
  619. }
  620. else
  621. {
  622. path[0] = 0;
  623. }
  624. Q_snprintf( filename, maxfilename, "%s%s", fname, ext );
  625. }
  626. //-----------------------------------------------------------------------------
  627. // Purpose:
  628. // Input : *se -
  629. //-----------------------------------------------------------------------------
  630. void CVCDBrowser::JumpToItem( const FileNameHandle_t& vcd )
  631. {
  632. SetActiveTool( this );
  633. char path[ 256 ];
  634. char filename[ 256 ];
  635. char vcdfile[ 512 ];
  636. if ( !filesystem->String( vcd, vcdfile, sizeof( vcdfile ) ) )
  637. return;
  638. SplitFileName( vcdfile, path, sizeof( path ), filename, sizeof( filename ) );
  639. char *usepath = path + Q_strlen( "/scenes/" );
  640. PopulateTree( usepath );
  641. int idx = 0;
  642. int c = m_pListView->getItemCount();
  643. for ( ; idx < c; idx++ )
  644. {
  645. FileNameHandle_t item = (FileNameHandle_t)m_pListView->getUserData( idx, 0 );
  646. if ( item == vcd )
  647. {
  648. break;
  649. }
  650. }
  651. if ( idx < c )
  652. {
  653. m_pListView->scrollToItem( idx );
  654. }
  655. }
  656. int CVCDBrowser::GetVCDCount() const
  657. {
  658. return m_AllVCDs.Count();
  659. }
  660. FileNameHandle_t CVCDBrowser::GetVCD( int index )
  661. {
  662. if ( index < 0 || index >= (int)m_AllVCDs.Count() )
  663. return NULL;
  664. return m_AllVCDs[ index ];
  665. }
  666. void CVCDBrowser::OnSearch()
  667. {
  668. if ( !GetSearchString()[ 0 ] )
  669. {
  670. OnCancelSearch();
  671. return;
  672. }
  673. SetActiveTool( this );
  674. m_bTextSearch = true;
  675. PopulateTree( GetSearchString());
  676. }
  677. void CVCDBrowser::OnCancelSearch()
  678. {
  679. SetActiveTool( this );
  680. m_bTextSearch = false;
  681. PopulateTree( m_pFileTree->GetSelectedPath() );
  682. }
  683. char const *CVCDBrowser::GetSearchString()
  684. {
  685. return m_pOptions->GetSearchString();
  686. }
  687. void CVCDBrowser::SetCurrent( char const *filename )
  688. {
  689. // Get sound name and look up .vcd from it
  690. char const *p = filename;
  691. if ( p &&
  692. ( !Q_strnicmp( p, "sound/", 6 ) || !Q_strnicmp( p, "sound\\", 6 ) ) )
  693. {
  694. p += 6;
  695. }
  696. char fn[ 512 ];
  697. Q_strncpy( fn, p, sizeof( fn ) );
  698. Q_FixSlashes( fn );
  699. int i;
  700. int c = m_pListView->getItemCount();
  701. for ( i = 0; i < c; ++i )
  702. {
  703. FileNameHandle_t vcd = (FileNameHandle_t)( m_pListView->getUserData( i, COL_VCD ) );
  704. char fixed[ 512 ];
  705. if ( !filesystem->String( vcd, fixed, sizeof( fixed ) ) )
  706. continue;
  707. Q_FixSlashes( fixed );
  708. if ( !Q_stricmp( fixed, fn ) )
  709. {
  710. m_pListView->scrollToItem( i );
  711. m_pListView->setSelected( i, true );
  712. }
  713. else
  714. {
  715. m_pListView->setSelected( i, false );
  716. }
  717. }
  718. }