Browser.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. // Browser.cpp : implementation file
  13. //
  14. #include "stdafx.h"
  15. #include "Browser.h"
  16. #ifdef _DEBUG
  17. #undef new
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. ////////////////////////////////////////////////////////////////////
  23. // CBrowser Construction/Destruction
  24. CBrowser::CBrowser(void)
  25. {
  26. // set default number of subdirectories (none)
  27. for( INDEX i=0; i<DIRECTORY_SHORTCT_CT; i++)
  28. {
  29. m_aiSubDirectoriesCt[ i] = 0;
  30. }
  31. }
  32. BOOL CBrowser::Create( CWnd* pParentWnd, UINT nIDTemplate,
  33. UINT nStyle, UINT nID, BOOL bChange)
  34. {
  35. if(!CDialogBar::Create(pParentWnd,nIDTemplate,nStyle,nID))
  36. {
  37. return FALSE;
  38. }
  39. m_bVirtualTreeChanged = FALSE;
  40. m_TreeHeight = CLOSED_TREE;
  41. m_Size = m_sizeDefault;
  42. m_BrowseWindow.AttachToControl( this);
  43. m_BrowseWindow.SetBrowserPtr( this);
  44. m_TreeCtrl.SetBrowserPtr( this);
  45. m_TreeCtrl.SubclassDlgItem(IDC_VIRTUALTREE, this);
  46. m_TreeCtrl.DragAcceptFiles();
  47. m_IconsImageList.Create( IDB_DIRECTORY_ICONS, 16, 1, CLR_NONE);
  48. m_TreeCtrl.SetImageList( &m_IconsImageList, TVSIL_NORMAL);
  49. return TRUE;
  50. }
  51. ////////////////////////////////////////////////////////////////////
  52. // Overloaded functions
  53. CSize CBrowser::CalcDynamicLayout(int nLength, DWORD nMode)
  54. {
  55. CSize csResult;
  56. // Return default if it is being docked or floated
  57. if ((nMode & LM_VERTDOCK) || (nMode & LM_HORZDOCK))
  58. {
  59. if (nMode & LM_STRETCH) // if not docked stretch to fit
  60. {
  61. csResult = CSize((nMode & LM_HORZ) ? 32767 : m_Size.cx,
  62. (nMode & LM_HORZ) ? m_Size.cy : 32767);
  63. }
  64. else
  65. {
  66. csResult = m_Size;
  67. }
  68. }
  69. else if (nMode & LM_MRUWIDTH)
  70. {
  71. csResult = m_Size;
  72. }
  73. // In all other cases, accept the dynamic length
  74. else
  75. {
  76. if (nMode & LM_LENGTHY)
  77. {
  78. csResult = CSize( m_Size.cx, m_Size.cy = nLength);
  79. }
  80. else
  81. {
  82. csResult = CSize( m_Size.cx = nLength, m_Size.cy);
  83. }
  84. }
  85. CRect NewBrowserPos;
  86. CRect NewTreePos;
  87. ULONG ulNewTreeHeight = m_TreeHeight;
  88. if( csResult.cy < (m_TreeHeight + V_BORDER*2 + 10) )
  89. {
  90. ulNewTreeHeight = csResult.cy - +V_BORDER*2 - 10;
  91. }
  92. // First we calculate and set browsing window position
  93. NewBrowserPos = CRect( H_BORDER,
  94. V_BORDER + ulNewTreeHeight,
  95. csResult.cx - H_BORDER,
  96. csResult.cy - V_BORDER);
  97. m_BrowseWindow.MoveWindow( NewBrowserPos);
  98. // Finaly we set new virtual tree control size
  99. NewTreePos = CRect( H_BORDER,
  100. V_BORDER,
  101. csResult.cx - H_BORDER,
  102. V_BORDER + ulNewTreeHeight);
  103. CWnd *pwndTree = GetDlgItem( IDC_VIRTUALTREE);
  104. pwndTree->MoveWindow( NewTreePos);
  105. m_boxBrowseWnd = PIXaabbox2D( PIX2D(NewBrowserPos.TopLeft().x, NewBrowserPos.TopLeft().y),
  106. PIX2D(NewBrowserPos.BottomRight().x, NewBrowserPos.BottomRight().y) );
  107. m_BrowseWindow.m_BrowseWndWidth = NewBrowserPos.Width();
  108. m_BrowseWindow.m_BrowseWndHeight = NewBrowserPos.Height();
  109. m_boxTreeWnd = PIXaabbox2D( PIX2D(NewTreePos.TopLeft().x, NewTreePos.TopLeft().y),
  110. PIX2D(NewTreePos.BottomRight().x, NewTreePos.BottomRight().y) );
  111. return csResult;
  112. }
  113. BEGIN_MESSAGE_MAP(CBrowser, CDialogBar)
  114. //{{AFX_MSG_MAP(CBrowser)
  115. ON_COMMAND(ID_CREATE_DIRECTORY, OnCreateDirectory)
  116. ON_COMMAND(ID_DELETE_DIRECTORY, OnDeleteDirectory)
  117. ON_COMMAND(ID_SAVE_VIRTUAL_TREE, OnSaveVirtualTree)
  118. ON_COMMAND(ID_LOAD_VIRTUAL_TREE, OnLoadVirtualTree)
  119. ON_COMMAND(ID_RENAME_DIRECTORY, OnRenameDirectory)
  120. ON_WM_CONTEXTMENU()
  121. ON_COMMAND(ID_SAVE_AS_VIRTUAL_TREE, OnSaveAsVirtualTree)
  122. ON_COMMAND(ID_IMPORT_VIRTUAL_TREE, OnImportVirtualTree)
  123. ON_COMMAND(ID_EXPORT_VIRTUAL_TREE, OnExportVirtualTree)
  124. ON_UPDATE_COMMAND_UI(ID_IMPORT_VIRTUAL_TREE, OnUpdateImportVirtualTree)
  125. ON_UPDATE_COMMAND_UI(ID_EXPORT_VIRTUAL_TREE, OnUpdateExportVirtualTree)
  126. ON_COMMAND(ID_DUMP_VT, OnDumpVt)
  127. //}}AFX_MSG_MAP
  128. END_MESSAGE_MAP()
  129. /////////////////////////////////////////////////////////////////////
  130. // CBrowser message handlers
  131. /////////////////////////////////////////////////////////////////////
  132. void CBrowser::AddDirectoryRecursiv(CVirtualTreeNode *pOneDirectory, HTREEITEM hParent)
  133. {
  134. // Insert one entry into virtual directory tree
  135. HTREEITEM InsertedDir;
  136. InsertedDir = m_TreeCtrl.InsertItem( 0, L"", 0, 0, TVIS_SELECTED, TVIF_STATE, 0,
  137. hParent, TVI_SORT );
  138. pOneDirectory->vtn_Handle = (ULONG) InsertedDir;
  139. m_TreeCtrl.SetItemData( InsertedDir, (ULONG)(pOneDirectory));
  140. m_TreeCtrl.SetItemText( InsertedDir, CString(pOneDirectory->vtn_strName));
  141. m_TreeCtrl.SetItemImage( InsertedDir, pOneDirectory->vtn_itIconType,
  142. pOneDirectory->vtn_itIconType + NO_OF_ICONS);
  143. // Now add this directory's subdirectories recursively
  144. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pOneDirectory->vtn_lhChildren, it)
  145. {
  146. CVirtualTreeNode &vtn=*it;
  147. if( vtn.vtn_bIsDirectory)
  148. {
  149. AddDirectoryRecursiv( &vtn, InsertedDir);
  150. }
  151. }
  152. }
  153. void CBrowser::OnCreateDirectory()
  154. {
  155. CDlgCreateVirtualDirectory dlg;
  156. if( dlg.DoModal() == IDOK)
  157. {
  158. CloseSelectedDirectory();
  159. CVirtualTreeNode *pvtnCurrent;
  160. // Is this root directory ?
  161. if( m_TreeCtrl.GetCount() == 0)
  162. {
  163. // Set data in instanciated CVirtualTreeNode because it is Root
  164. m_VirtualTree.vtn_bIsDirectory = TRUE;
  165. m_VirtualTree.vtn_itIconType = dlg.m_iSelectedIconType;
  166. m_VirtualTree.vtn_strName = CTString( CStringA(dlg.m_strDirectoryName));
  167. // Root's parent is NULL
  168. m_VirtualTree.vnt_pvtnParent = NULL;
  169. pvtnCurrent = &m_VirtualTree;
  170. }
  171. else
  172. {
  173. // Allocate new CVirtualTreeNode to carry new directory data
  174. CVirtualTreeNode *pvtnNewDir = new CVirtualTreeNode();
  175. pvtnCurrent = pvtnNewDir;
  176. pvtnNewDir->vtn_bIsDirectory = TRUE;
  177. pvtnNewDir->vtn_itIconType = dlg.m_iSelectedIconType;
  178. pvtnNewDir->vtn_strName = CTString( CStringA(dlg.m_strDirectoryName));
  179. // Get ptr to parent CVirtualTreeNode
  180. HTREEITEM pSelectedItem = m_TreeCtrl.GetSelectedItem();
  181. if( pSelectedItem == NULL) return;
  182. pvtnNewDir->vnt_pvtnParent = (CVirtualTreeNode *)m_TreeCtrl.GetItemData( pSelectedItem);
  183. // And add this new directory into its list
  184. pvtnNewDir->vnt_pvtnParent->vtn_lhChildren.AddTail( pvtnNewDir->vtn_lnInDirectory);
  185. }
  186. m_bVirtualTreeChanged = TRUE;
  187. m_TreeCtrl.DeleteAllItems();
  188. AddDirectoryRecursiv( &m_VirtualTree, TVI_ROOT); // Fill CTreeCtrl using recursion
  189. m_TreeCtrl.SortChildren( NULL);
  190. // Now select it
  191. m_TreeCtrl.SelectItem( (HTREEITEM) pvtnCurrent->vtn_Handle);
  192. OpenSelectedDirectory();
  193. }
  194. m_TreeCtrl.SetFocus();
  195. }
  196. void CBrowser::OnUpdateVirtualTreeControl(void)
  197. {
  198. m_bVirtualTreeChanged = TRUE;
  199. m_TreeCtrl.DeleteAllItems();
  200. AddDirectoryRecursiv( &m_VirtualTree, TVI_ROOT);
  201. m_TreeCtrl.SortChildren( NULL);
  202. // Now select it
  203. m_TreeCtrl.SelectItem( (HTREEITEM) m_VirtualTree.vtn_Handle);
  204. OpenSelectedDirectory();
  205. m_TreeCtrl.SetFocus();
  206. }
  207. void CBrowser::OnDeleteDirectory()
  208. {
  209. if( m_TreeCtrl.GetCount() == 0)
  210. return;
  211. if( ::MessageBoxA( this->m_hWnd, "Do You really want to delete directory and all its subdirectories?",
  212. "Warning !", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1 |
  213. MB_TASKMODAL | MB_TOPMOST) != IDYES)
  214. {
  215. m_TreeCtrl.SetFocus();
  216. return;
  217. }
  218. CloseSelectedDirectory();
  219. DeleteDirectory();
  220. OpenSelectedDirectory();
  221. }
  222. void CBrowser::DeleteDirectory(void)
  223. {
  224. if( m_TreeCtrl.GetCount() == 0)
  225. return;
  226. CVirtualTreeNode *pvtnParent = NULL;
  227. HTREEITEM pSelectedItem = m_TreeCtrl.GetSelectedItem();
  228. if( pSelectedItem == NULL) return;
  229. CVirtualTreeNode *pVTN = (CVirtualTreeNode *)m_TreeCtrl.GetItemData( pSelectedItem);
  230. // Delete all subdirectories
  231. FORDELETELIST( CVirtualTreeNode, vtn_lnInDirectory, pVTN->vtn_lhChildren, litDel)
  232. {
  233. delete &litDel.Current();
  234. }
  235. // If this is not root directory, remove it from list and delete it
  236. if( pVTN->vnt_pvtnParent != NULL)
  237. {
  238. pvtnParent = pVTN->vnt_pvtnParent;
  239. pVTN->vtn_lnInDirectory.Remove();
  240. delete pVTN;
  241. }
  242. m_TreeCtrl.DeleteAllItems();
  243. // If it wasn't root directory, fill TreeCtrl with data
  244. if( pvtnParent != NULL)
  245. {
  246. AddDirectoryRecursiv( &m_VirtualTree, TVI_ROOT); // Fill CTreeCtrl using recursion
  247. m_TreeCtrl.SortChildren( NULL);
  248. HTREEITEM NewActiveDir = (HTREEITEM) pvtnParent->vtn_Handle;
  249. if( m_TreeCtrl.ItemHasChildren(NewActiveDir) )
  250. {
  251. NewActiveDir = m_TreeCtrl.GetChildItem( NewActiveDir);
  252. }
  253. m_TreeCtrl.SelectItem( NewActiveDir);
  254. }
  255. m_bVirtualTreeChanged = TRUE;
  256. m_TreeCtrl.SetFocus();
  257. }
  258. CVirtualTreeNode *CBrowser::FindItemDirectory(CVirtualTreeNode *pvtnCurrentDirectory,
  259. CTFileName fnItemFileName)
  260. {
  261. // Now search this directory recursivly
  262. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pvtnCurrentDirectory->vtn_lhChildren, it)
  263. {
  264. if( it->vtn_bIsDirectory)
  265. {
  266. CVirtualTreeNode *pvtnResult = FindItemDirectory( &it.Current(), fnItemFileName);
  267. if( pvtnResult != NULL) return pvtnResult;
  268. }
  269. else
  270. {
  271. if( it->vtn_fnItem == fnItemFileName)
  272. {
  273. // deselect all items in directory
  274. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pvtnCurrentDirectory->vtn_lhChildren, it2)
  275. {
  276. it2->vtn_bSelected = FALSE;
  277. }
  278. // selected requested item
  279. it->vtn_bSelected = TRUE;
  280. return pvtnCurrentDirectory;
  281. }
  282. }
  283. }
  284. return NULL;
  285. }
  286. void CBrowser::SelectItemDirectory( CTFileName fnItemFileName)
  287. {
  288. CVirtualTreeNode *pvtnItemDirectory = FindItemDirectory( &m_VirtualTree, fnItemFileName);
  289. if( pvtnItemDirectory != NULL)
  290. {
  291. CloseSelectedDirectory();
  292. // Now select it
  293. m_TreeCtrl.SelectItem( (HTREEITEM) pvtnItemDirectory->vtn_Handle);
  294. OpenSelectedDirectory();
  295. }
  296. }
  297. /*
  298. * Separate subdirectory names along current path
  299. */
  300. INDEX CBrowser::GetSelectedDirectory( CTString strArray[])
  301. {
  302. INDEX iSubDirsCt = 0;
  303. HTREEITEM pItem = m_TreeCtrl.GetSelectedItem();
  304. if( pItem == NULL) return -1;
  305. FOREVER
  306. {
  307. CTString strItemName = CTString( CStringA(m_TreeCtrl.GetItemText(pItem)));
  308. strArray[ iSubDirsCt] = strItemName;
  309. iSubDirsCt ++;
  310. if( m_TreeCtrl.GetParentItem(pItem) == NULL)
  311. break;
  312. pItem = m_TreeCtrl.GetParentItem(pItem);
  313. }
  314. return iSubDirsCt;
  315. }
  316. HTREEITEM CBrowser::GetVirtualDirectoryItem( CTString strArray[], INDEX iSubDirsCt)
  317. {
  318. INDEX j;
  319. // pick up root item ptr if path finding fails, it will be selected
  320. HTREEITEM pRootItem = m_TreeCtrl.GetRootItem();
  321. HTREEITEM pItem = pRootItem;
  322. // loop all directories starting from root and search for selected subdirectory name
  323. for( j=iSubDirsCt-1; j>=0; j--)
  324. {
  325. BOOL bSucess;
  326. HTREEITEM pStartItem = pItem;
  327. FOREVER
  328. {
  329. if( pItem == NULL)
  330. {
  331. bSucess = FALSE;
  332. break;
  333. }
  334. // get current directory's (starting from root) first subdirectory
  335. CTString strItemName = CTString( CStringA(m_TreeCtrl.GetItemText(pItem)));
  336. // is this subdirectory's name same as one in list of selected along given path
  337. if( strArray[ j] == strItemName)
  338. {
  339. // subdirectory found, if it has children or selected subdirectories counter reached 0
  340. if( m_TreeCtrl.ItemHasChildren( pItem) || (j==0) )
  341. {
  342. // mark that we found current subdirectory
  343. bSucess = TRUE;
  344. // if counter didn't reached 0
  345. if( j!=0)
  346. {
  347. // it becomes current and we will try to find his selected subdirectory
  348. pItem = m_TreeCtrl.GetChildItem( pItem);
  349. }
  350. break;
  351. }
  352. // we have no more children and counter is not 0 which means
  353. else
  354. {
  355. // that we didn't succeeded
  356. bSucess = FALSE;
  357. break;
  358. }
  359. }
  360. // this directory's name is not one we are searching for
  361. else
  362. {
  363. // so skip to next item in current directory
  364. pItem = m_TreeCtrl.GetNextItem( pItem, TVGN_NEXT);
  365. // if we have wrapped back to start of items list, we didn't find any dir with
  366. // selected name
  367. if( pStartItem == pItem)
  368. {
  369. // so we weren't successful
  370. bSucess = FALSE;
  371. break;
  372. }
  373. }
  374. }
  375. // directory search finished, if selected subdirectory wasn't found
  376. if( !bSucess)
  377. {
  378. // select root item
  379. pItem = pRootItem;
  380. // stop searching
  381. break;
  382. }
  383. }
  384. return pItem;
  385. }
  386. /*
  387. * Selects subdirectory using given path
  388. */
  389. void CBrowser::SelectVirtualDirectory( CTString strArray[], INDEX iSubDirsCt)
  390. {
  391. // get virtual directory item
  392. HTREEITEM pItem = GetVirtualDirectoryItem( strArray, iSubDirsCt);
  393. // select last found directory
  394. m_TreeCtrl.SelectItem( pItem);
  395. // make it visible
  396. m_TreeCtrl.EnsureVisible( pItem);
  397. }
  398. CTFileName CBrowser::GetIOFileName(CTString strTitle, BOOL bSave)
  399. {
  400. // You can't save with no directories
  401. if( bSave && m_TreeCtrl.GetCount()==0)
  402. return CTString("");
  403. CWorldEditorApp *pApp = (CWorldEditorApp *)AfxGetApp();
  404. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  405. char chrChoosedFileName[ 256];
  406. OPENFILENAMEA ofnSaveVirtualTree;
  407. const char *pFilters = "Virtual tree files (*.vrt)\0*.vrt\0\0";
  408. strcpy( chrChoosedFileName, pMainFrame->m_fnLastVirtualTree.FileName());
  409. strcat( chrChoosedFileName, pMainFrame->m_fnLastVirtualTree.FileExt());
  410. memset( &ofnSaveVirtualTree, 0, sizeof( OPENFILENAME));
  411. ofnSaveVirtualTree.lStructSize = sizeof(OPENFILENAME);
  412. ofnSaveVirtualTree.lpstrFilter = pFilters;
  413. ofnSaveVirtualTree.lpstrFile = chrChoosedFileName;
  414. ofnSaveVirtualTree.nMaxFile = 256;
  415. char strInitDir[ 256];
  416. strcpy( strInitDir, _fnmApplicationPath + pMainFrame->m_fnLastVirtualTree.FileDir());
  417. ofnSaveVirtualTree.lpstrInitialDir = strInitDir;
  418. ofnSaveVirtualTree.lpstrTitle = strTitle;
  419. ofnSaveVirtualTree.Flags = OFN_EXPLORER | OFN_ENABLEHOOK;
  420. ofnSaveVirtualTree.lpstrDefExt = "vrt";
  421. ofnSaveVirtualTree.hwndOwner = pMainFrame->m_hWnd;
  422. BOOL bResult=FALSE;
  423. if( bSave)
  424. {
  425. bResult=GetSaveFileNameA( &ofnSaveVirtualTree);
  426. }
  427. else
  428. {
  429. bResult=GetOpenFileNameA( &ofnSaveVirtualTree);
  430. }
  431. if( !bResult)
  432. {
  433. m_TreeCtrl.SetFocus();
  434. return CTString("");
  435. }
  436. CTFileName fnTree = CTString(chrChoosedFileName);
  437. try
  438. {
  439. fnTree.RemoveApplicationPath_t();
  440. }
  441. catch( char *str_err)
  442. {
  443. AfxMessageBox( CString(str_err));
  444. return CTString("");
  445. }
  446. return fnTree;
  447. }
  448. void CBrowser::SaveVirtualTree(CTFileName fnSave, CVirtualTreeNode *pvtn)
  449. {
  450. ASSERT(pvtn!=NULL);
  451. if(pvtn==NULL) return;
  452. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  453. CTFileStream File;
  454. try
  455. {
  456. File.Create_t( fnSave, CTStream::CM_BINARY);
  457. File.WriteID_t( CChunkID("VRTT"));
  458. File.WriteID_t( CChunkID(VIRTUAL_TREE_VERSION));
  459. pvtn->Write_t( &File); // This will recursivly save tree beneath given tree node
  460. // Now we will try to save selected item's path
  461. File.WriteID_t( CChunkID("SELC"));
  462. // write ID of virtual tree buffer
  463. File.WriteID_t( CChunkID("VTBF"));
  464. // obtain selected directpry's path
  465. CTString strArray[ 32];
  466. INDEX iSubDirsCt = GetSelectedDirectory( strArray);
  467. // write count of sub-directories
  468. File << iSubDirsCt;
  469. // write names of all subdirectories along path into file
  470. INDEX i=0;
  471. for( ; i<iSubDirsCt; i++)
  472. {
  473. File << strArray[ i];
  474. }
  475. // now save all of virtual tree buffers
  476. for( i=0; i<DIRECTORY_SHORTCT_CT; i++)
  477. {
  478. // write ID of virtual tree buffer
  479. File.WriteID_t( CChunkID("VTBF"));
  480. // write count of sub-directories
  481. INDEX iSubDirsCt = m_aiSubDirectoriesCt[ i];
  482. File << iSubDirsCt;
  483. // write names of all subdirectories along path into file
  484. for( INDEX j=0; j<iSubDirsCt; j++)
  485. {
  486. File << m_astrVTreeBuffer[i][j];
  487. }
  488. }
  489. // save marker for end of virtual tree
  490. File.WriteID_t( CChunkID("END_"));
  491. // close the file
  492. File.Close();
  493. }
  494. catch( char *str_err)
  495. {
  496. AfxMessageBox( CString(str_err));
  497. return;
  498. }
  499. m_TreeCtrl.SetFocus();
  500. m_bVirtualTreeChanged = FALSE;
  501. }
  502. void CBrowser::OnSaveVirtualTree()
  503. {
  504. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  505. // save whole virtual tree
  506. SaveVirtualTree(pMainFrame->m_fnLastVirtualTree, &m_VirtualTree);
  507. }
  508. void CBrowser::OnSaveAsVirtualTree()
  509. {
  510. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  511. CTFileName fnSave=GetIOFileName("Save virtual tree to file", TRUE);
  512. if( fnSave!="")
  513. {
  514. // remember choosed file name as last used
  515. pMainFrame->m_fnLastVirtualTree = fnSave;
  516. // save virtual tree
  517. SaveVirtualTree(fnSave, &m_VirtualTree);
  518. }
  519. }
  520. void CBrowser::OnLoadVirtualTree()
  521. {
  522. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  523. if( m_bVirtualTreeChanged)
  524. {
  525. if( ::MessageBoxA( this->m_hWnd, "Current virtual directory not saved. Do You want to continue anyway?",
  526. "Warning !", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1 |
  527. MB_TASKMODAL | MB_TOPMOST) != IDYES)
  528. {
  529. m_TreeCtrl.SetFocus();
  530. return;
  531. }
  532. }
  533. CTFileName fnOpen=GetIOFileName("Load virtual tree", FALSE);
  534. if( fnOpen!="")
  535. {
  536. // remember choosed file name as last used
  537. pMainFrame->m_fnLastVirtualTree = fnOpen;
  538. // open virtual tree branch
  539. OnLoadVirtualTreeInternal(fnOpen, NULL);
  540. }
  541. }
  542. void CBrowser::OnImportVirtualTree()
  543. {
  544. CTFileName fnImport=GetIOFileName("Import virtual tree", FALSE);
  545. if( fnImport!="")
  546. {
  547. HTREEITEM pSelectedItem = m_TreeCtrl.GetSelectedItem();
  548. if( pSelectedItem == NULL) return;
  549. CVirtualTreeNode *pVTN = (CVirtualTreeNode *)m_TreeCtrl.GetItemData( pSelectedItem);
  550. // open virtual tree branch
  551. OnLoadVirtualTreeInternal(fnImport, pVTN);
  552. }
  553. }
  554. void CBrowser::OnExportVirtualTree()
  555. {
  556. HTREEITEM pSelectedItem = m_TreeCtrl.GetSelectedItem();
  557. if( pSelectedItem == NULL) return;
  558. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  559. CTFileName fnExport=GetIOFileName("Export virtual tree", TRUE);
  560. if( fnExport!="")
  561. {
  562. CVirtualTreeNode *pVTN = (CVirtualTreeNode *)m_TreeCtrl.GetItemData( pSelectedItem);
  563. // save virtual tree branch
  564. SaveVirtualTree(fnExport, pVTN);
  565. }
  566. }
  567. void CBrowser::OnUpdateImportVirtualTree(CCmdUI* pCmdUI)
  568. {
  569. HTREEITEM pSelectedItem = m_TreeCtrl.GetSelectedItem();
  570. pCmdUI->Enable( pSelectedItem != NULL);
  571. }
  572. void CBrowser::OnUpdateExportVirtualTree(CCmdUI* pCmdUI)
  573. {
  574. HTREEITEM pSelectedItem = m_TreeCtrl.GetSelectedItem();
  575. pCmdUI->Enable( pSelectedItem != NULL);
  576. }
  577. void CBrowser::OnLoadVirtualTreeInternal(CTFileName fnVirtulTree, CVirtualTreeNode *pvtnRoot)
  578. {
  579. CloseSelectedDirectory();
  580. try
  581. {
  582. LoadVirtualTree_t( fnVirtulTree, pvtnRoot);
  583. }
  584. catch( char *strError)
  585. {
  586. AfxMessageBox( CString(strError));
  587. FORDELETELIST( CVirtualTreeNode, vtn_lnInDirectory, m_VirtualTree.vtn_lhChildren, litDel)
  588. {
  589. delete &litDel.Current();
  590. }
  591. return;
  592. }
  593. m_TreeCtrl.SetFocus();
  594. m_bVirtualTreeChanged = FALSE;
  595. OpenSelectedDirectory();
  596. }
  597. void CBrowser::LoadVirtualTree_t( CTFileName fnVirtulTree, CVirtualTreeNode *pvtnRoot)
  598. {
  599. if( pvtnRoot==NULL)
  600. {
  601. // If current tree is not empty, delete it
  602. if( m_TreeCtrl.GetCount() != 0)
  603. {
  604. FORDELETELIST( CVirtualTreeNode, vtn_lnInDirectory, m_VirtualTree.vtn_lhChildren, litDel)
  605. {
  606. delete &litDel.Current();
  607. }
  608. m_TreeCtrl.SelectItem( m_TreeCtrl.GetRootItem());
  609. DeleteDirectory();
  610. }
  611. }
  612. CTFileStream File;
  613. File.Open_t( fnVirtulTree, CTStream::OM_READ);
  614. if( !(CChunkID("VRTT") == File.GetID_t()))
  615. {
  616. throw( "This is not valid virtual tree file");
  617. }
  618. if( !(CChunkID(VIRTUAL_TREE_VERSION) == File.GetID_t()))
  619. {
  620. throw( "Invalid version of virtual tree file.");
  621. }
  622. if( pvtnRoot==NULL)
  623. {
  624. m_VirtualTree.Read_t( &File, NULL);
  625. }
  626. else
  627. {
  628. CVirtualTreeNode *pVTNNew = new CVirtualTreeNode;
  629. pVTNNew->Read_t( &File, pvtnRoot);
  630. }
  631. // delete all items
  632. m_TreeCtrl.DeleteAllItems();
  633. AddDirectoryRecursiv( &m_VirtualTree, TVI_ROOT); // Fill CTreeCtrl using recursion
  634. if( pvtnRoot!=NULL)
  635. {
  636. // don't read rest of data
  637. File.Close();
  638. return;
  639. }
  640. // Now we will try to load selected directory definition
  641. File.ExpectID_t( CChunkID("SELC"));
  642. // expect ID for virtual tree buffer
  643. File.ExpectID_t( CChunkID("VTBF"));
  644. INDEX iSubDirsCt;
  645. // read count of sub-directories
  646. File >> iSubDirsCt;
  647. // limited number of sub directories
  648. ASSERT( iSubDirsCt <= 32);
  649. // we will load selected directories from root up to finaly selected
  650. CTString strArray[ 32];
  651. // load as many subdirectory names as count says
  652. INDEX i=0;
  653. for( ; i<iSubDirsCt; i++)
  654. {
  655. File >> strArray[ i];
  656. }
  657. // try to select directory
  658. SelectVirtualDirectory( strArray, iSubDirsCt);
  659. // now read all four virtual tree buffers
  660. for( i=0; i<DIRECTORY_SHORTCT_CT; i++)
  661. {
  662. // expect ID for virtual tree buffer
  663. File.ExpectID_t( CChunkID("VTBF"));
  664. // read count of sub-directories
  665. File >> iSubDirsCt;
  666. // store it in array of counters
  667. m_aiSubDirectoriesCt[ i] = iSubDirsCt;
  668. // limited number of sub directories
  669. ASSERT( iSubDirsCt <= 32);
  670. // load as many subdirectory names as count says
  671. for( INDEX j=0; j<iSubDirsCt; j++)
  672. {
  673. File >> m_astrVTreeBuffer[i][j];
  674. }
  675. }
  676. File.ExpectID_t( CChunkID("END_"));
  677. File.Close();
  678. }
  679. void CBrowser::OnRenameDirectory()
  680. {
  681. if( m_TreeCtrl.GetCount() != 0)
  682. {
  683. HTREEITEM pSelectedItem = m_TreeCtrl.GetSelectedItem();
  684. if( pSelectedItem == NULL) return;
  685. CVirtualTreeNode *pVTN = (CVirtualTreeNode *)m_TreeCtrl.GetItemData( pSelectedItem);
  686. CDlgCreateVirtualDirectory dlg( pVTN->vtn_strName, CTString("Rename virtual directory") );
  687. if( dlg.DoModal() == IDOK)
  688. {
  689. pVTN->vtn_itIconType = dlg.m_iSelectedIconType;
  690. pVTN->vtn_strName = CTString( CStringA(dlg.m_strDirectoryName));
  691. m_TreeCtrl.SetItemImage( pSelectedItem, pVTN->vtn_itIconType,
  692. pVTN->vtn_itIconType + NO_OF_ICONS);
  693. m_TreeCtrl.SetItemText( pSelectedItem, CString(pVTN->vtn_strName));
  694. m_bVirtualTreeChanged = TRUE;
  695. }
  696. m_TreeCtrl.SetFocus();
  697. }
  698. }
  699. void CBrowser::OnContextMenu(CWnd* pWnd, CPoint point)
  700. {
  701. CRect rectBrowser;
  702. GetWindowRect( &rectBrowser);
  703. CPoint ptInBrowser = CPoint( point.x - rectBrowser.TopLeft().x,
  704. point.y - rectBrowser.TopLeft().y);
  705. PIXaabbox2D boxPoint = PIXaabbox2D( PIX2D(ptInBrowser.x, ptInBrowser.y) );
  706. if( (m_boxBrowseWnd & boxPoint) == boxPoint)
  707. {
  708. m_BrowseWindow.OnContextMenu( point);
  709. }
  710. else if( (m_boxTreeWnd & boxPoint) == boxPoint)
  711. {
  712. m_TreeCtrl.OnContextMenu( point);
  713. }
  714. }
  715. CVirtualTreeNode *CBrowser::GetSelectedDirectory(void)
  716. {
  717. if( m_TreeCtrl.GetCount() != 0)
  718. {
  719. HTREEITEM pSelectedItem = m_TreeCtrl.GetSelectedItem();
  720. if( pSelectedItem!=NULL)
  721. {
  722. return (CVirtualTreeNode *)m_TreeCtrl.GetItemData( pSelectedItem);
  723. }
  724. }
  725. return NULL;
  726. }
  727. void CBrowser::OpenSelectedDirectory(void)
  728. {
  729. CVirtualTreeNode *pVTN = GetSelectedDirectory();
  730. if( pVTN != NULL)
  731. {
  732. m_BrowseWindow.OpenDirectory( pVTN);
  733. }
  734. }
  735. void CBrowser::CloseSelectedDirectory(void)
  736. {
  737. CVirtualTreeNode *pVTN = GetSelectedDirectory();
  738. if( pVTN != NULL)
  739. {
  740. m_BrowseWindow.CloseDirectory( pVTN);
  741. }
  742. }
  743. void CBrowser::OnDumpVt()
  744. {
  745. CTFileName fnName = _EngineGUI.FileRequester( "Dump virtual tree as ...",
  746. "Text file\0*.txt\0" FILTER_ALL FILTER_END, "Dump virtual tree directory", "VirtualTrees\\");
  747. if( fnName == "") return;
  748. CTFileStream FileDump;
  749. try
  750. {
  751. FileDump.Create_t( fnName, CTStream::CM_TEXT);
  752. m_VirtualTree.Dump(&FileDump);
  753. FileDump.Close();
  754. }
  755. catch( char *str_err)
  756. {
  757. AfxMessageBox( CString(str_err));
  758. }
  759. }