Team Fortress 2 Source Code as on 22/4/2020
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.

416 lines
8.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "project.h"
  8. #include "cmdlib.h"
  9. #include <KeyValues.h>
  10. #include "scene.h"
  11. #include "UtlBuffer.h"
  12. #include "vcdfile.h"
  13. #include "workspacemanager.h"
  14. #include "workspacebrowser.h"
  15. CProject::CProject( CWorkspace *ws, char const *filename ) : m_pOwner( ws )
  16. {
  17. Q_strncpy( m_szFile, filename, sizeof( m_szFile ) );
  18. // By default, name is the same as the filename
  19. Q_FileBase( m_szFile, m_szName, sizeof( m_szName ) );
  20. m_bDirty = false;
  21. m_pszComments = NULL;
  22. LoadFromFile();
  23. }
  24. CProject::~CProject()
  25. {
  26. while ( m_Scenes.Count() > 0 )
  27. {
  28. CScene *p = m_Scenes[ 0 ];
  29. m_Scenes.Remove( 0 );
  30. delete p;
  31. }
  32. delete[] m_pszComments;
  33. }
  34. CWorkspace *CProject::GetOwnerWorkspace()
  35. {
  36. return m_pOwner;
  37. }
  38. char const *CProject::GetName() const
  39. {
  40. return m_szName;
  41. }
  42. char const *CProject::GetFileName() const
  43. {
  44. return m_szFile;
  45. }
  46. bool CProject::IsDirty( void ) const
  47. {
  48. return m_bDirty;
  49. }
  50. void CProject::SetDirty( bool dirty )
  51. {
  52. m_bDirty = dirty;
  53. }
  54. void CProject::SetComments( char const *comments )
  55. {
  56. delete[] m_pszComments;
  57. m_pszComments = V_strdup( comments );
  58. SetDirty( true );
  59. }
  60. char const *CProject::GetComments() const
  61. {
  62. return m_pszComments ? m_pszComments : "";
  63. }
  64. int CProject::GetSceneCount() const
  65. {
  66. return m_Scenes.Count();
  67. }
  68. CScene *CProject::GetScene( int index ) const
  69. {
  70. if ( index < 0 || index >= m_Scenes.Count() )
  71. return NULL;
  72. return m_Scenes[ index ];
  73. }
  74. void CProject::AddScene( CScene *scene )
  75. {
  76. SetDirty( true );
  77. Assert( m_Scenes.Find( scene ) == m_Scenes.InvalidIndex() );
  78. m_Scenes.AddToTail( scene );
  79. }
  80. void CProject::RemoveScene( CScene *scene )
  81. {
  82. if ( m_Scenes.Find( scene ) == m_Scenes.InvalidIndex() )
  83. return;
  84. m_Scenes.FindAndRemove( scene );
  85. SetDirty( true );
  86. }
  87. void CProject::LoadFromFile()
  88. {
  89. KeyValues *kv = new KeyValues( m_szName );
  90. if ( kv->LoadFromFile( filesystem, m_szFile ) )
  91. {
  92. for ( KeyValues *s = kv->GetFirstSubKey(); s; s = s->GetNextKey() )
  93. {
  94. if ( !Q_stricmp( s->GetName(), "comments" ) )
  95. {
  96. SetComments( s->GetString() );
  97. continue;
  98. }
  99. // Add named scenes
  100. CScene *scene = new CScene( this, s->GetName() );
  101. for ( KeyValues *sub = s->GetFirstSubKey(); sub; sub = sub->GetNextKey() )
  102. {
  103. if ( !Q_stricmp( sub->GetName(), "comments" ) )
  104. {
  105. scene->SetComments( sub->GetString() );
  106. continue;
  107. }
  108. if ( !Q_stricmp( sub->GetName(), "expanded" ) )
  109. {
  110. scene->SetExpanded( sub->GetInt() ? true : false );
  111. continue;
  112. }
  113. if ( !Q_stricmp( sub->GetName(), "vcd" ) )
  114. {
  115. char filename[ 256 ];
  116. char comments[ 512 ];
  117. bool expanded = false;
  118. filename[ 0 ] = 0;
  119. comments[ 0 ] = 0;
  120. for ( KeyValues *vcdKeys = sub->GetFirstSubKey(); vcdKeys; vcdKeys = vcdKeys->GetNextKey() )
  121. {
  122. if ( !Q_stricmp( vcdKeys->GetName(), "expanded" ) )
  123. {
  124. expanded = vcdKeys->GetInt() ? true : false;
  125. continue;
  126. }
  127. else if ( !Q_stricmp( vcdKeys->GetName(), "file" ) )
  128. {
  129. Q_strncpy( filename, vcdKeys->GetString(), sizeof( filename ) );
  130. continue;
  131. }
  132. if ( !Q_stricmp( vcdKeys->GetName(), "comments" ) )
  133. {
  134. Q_strncpy( comments, vcdKeys->GetString(), sizeof( comments ) );
  135. continue;
  136. }
  137. Assert( 0 );
  138. }
  139. CVCDFile *file = new CVCDFile( scene, filename);
  140. file->SetExpanded( expanded );
  141. if ( comments[0] )
  142. {
  143. file->SetComments( comments );
  144. }
  145. scene->AddVCD( file );
  146. continue;
  147. }
  148. Assert( !va( "Unknown scene token %s\n", sub->GetName() ) );
  149. }
  150. m_Scenes.AddToTail( scene );
  151. }
  152. }
  153. kv->deleteThis();
  154. SetDirty( false );
  155. }
  156. void CProject::SaveToFile()
  157. {
  158. SetDirty( false );
  159. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  160. buf.Printf( "%s\n{\n", GetName() );
  161. if ( GetComments() && GetComments()[0] )
  162. {
  163. buf.Printf( "\t\"comments\"\t\"%s\"\n",
  164. GetComments() );
  165. }
  166. // walk projects
  167. int c = GetSceneCount();
  168. for ( int i = 0; i < c; i++ )
  169. {
  170. CScene *scene = GetScene( i );
  171. Assert( scene );
  172. buf.Printf( "\t\"%s\"\n", scene->GetName() );
  173. buf.Printf( "\t{\n" );
  174. buf.Printf( "\t\t\"expanded\"\t\"%i\"\n", scene->IsExpanded() ? 1 : 0 );
  175. if ( scene->GetComments() && scene->GetComments()[0] )
  176. {
  177. buf.Printf( "\t\t\"comments\"\t\"%s\"\n",
  178. scene->GetComments() );
  179. }
  180. int vcdcount = scene->GetVCDCount();
  181. for ( int j = 0; j < vcdcount; j++ )
  182. {
  183. CVCDFile *vcd = scene->GetVCD( j );
  184. Assert( vcd );
  185. buf.Printf( "\t\tvcd\n" );
  186. buf.Printf( "\t\t{\n" );
  187. buf.Printf( "\t\t\t\"expanded\"\t\"%i\"\n",
  188. vcd->IsExpanded() ? 1 : 0 );
  189. buf.Printf( "\t\t\t\"file\"\t\"%s\"\n",
  190. vcd->GetName() );
  191. if ( vcd->GetComments() && vcd->GetComments()[0] )
  192. {
  193. buf.Printf( "\t\t\t\"comments\"\t\"%s\"\n",
  194. vcd->GetComments() );
  195. }
  196. buf.Printf( "\t\t}\n" );
  197. }
  198. buf.Printf( "\t}\n" );
  199. if ( i != c - 1 )
  200. {
  201. buf.Printf( "\n" );
  202. }
  203. }
  204. buf.Printf( "}\n" );
  205. // Write it out baby
  206. FileHandle_t fh = filesystem->Open( m_szFile, "wt" );
  207. if (fh)
  208. {
  209. filesystem->Write( buf.Base(), buf.TellPut(), fh );
  210. filesystem->Close(fh);
  211. }
  212. else
  213. {
  214. Con_Printf( "CWorkspace::SaveToFile: Unable to write file %s!!!\n", m_szFile );
  215. }
  216. }
  217. void CProject::SaveChanges()
  218. {
  219. if ( !IsDirty() )
  220. return;
  221. SaveToFile();
  222. }
  223. void CProject::ValidateTree( mxTreeView *tree, mxTreeViewItem* parent )
  224. {
  225. CUtlVector< mxTreeViewItem * > m_KnownItems;
  226. int c = GetSceneCount();
  227. CScene *scene;
  228. for ( int i = 0; i < c; i++ )
  229. {
  230. scene = GetScene( i );
  231. if ( !scene )
  232. continue;
  233. char sz[ 256 ];
  234. if ( scene->GetComments() && scene->GetComments()[0] )
  235. {
  236. Q_snprintf( sz, sizeof( sz ) , "%s : %s", scene->GetName(), scene->GetComments() );
  237. }
  238. else
  239. {
  240. Q_snprintf( sz, sizeof( sz ) , "%s", scene->GetName() );
  241. }
  242. mxTreeViewItem *spot = scene->FindItem( tree, parent );
  243. if ( !spot )
  244. {
  245. spot = tree->add( parent, sz );
  246. }
  247. m_KnownItems.AddToTail( spot );
  248. scene->SetOrdinal( i );
  249. tree->setLabel( spot, sz );
  250. tree->setImages( spot, scene->GetIconIndex(), scene->GetIconIndex() );
  251. tree->setUserData( spot, scene );
  252. //tree->setOpen( spot, scene->IsExpanded() );
  253. scene->ValidateTree( tree, spot );
  254. }
  255. mxTreeViewItem *start = tree->getFirstChild( parent );
  256. while ( start )
  257. {
  258. mxTreeViewItem *next = tree->getNextChild( start );
  259. if ( m_KnownItems.Find( start ) == m_KnownItems.InvalidIndex() )
  260. {
  261. tree->remove( start );
  262. }
  263. start = next;
  264. }
  265. tree->sortTree( parent, true, CWorkspaceBrowser::CompareFunc, 0 );
  266. }
  267. void CProject::Checkout(bool updatestateicons /*= true*/)
  268. {
  269. VSS_Checkout( GetFileName(), updatestateicons );
  270. }
  271. void CProject::Checkin(bool updatestateicons /*= true*/)
  272. {
  273. VSS_Checkin( GetFileName(), updatestateicons );
  274. }
  275. bool CProject::IsCheckedOut() const
  276. {
  277. return filesystem->IsFileWritable( GetFileName() );
  278. }
  279. int CProject::GetIconIndex() const
  280. {
  281. if ( IsCheckedOut() )
  282. {
  283. return IMAGE_PROJECT_CHECKEDOUT;
  284. }
  285. else
  286. {
  287. return IMAGE_PROJECT;
  288. }
  289. }
  290. bool CProject::IsChildFirst( ITreeItem *child )
  291. {
  292. int idx = m_Scenes.Find( (CScene *)child );
  293. if ( idx == m_Scenes.InvalidIndex() )
  294. return false;
  295. if ( idx != 0 )
  296. return false;
  297. return true;
  298. }
  299. bool CProject::IsChildLast( ITreeItem *child )
  300. {
  301. int idx = m_Scenes.Find( (CScene *)child );
  302. if ( idx == m_Scenes.InvalidIndex() )
  303. return false;
  304. if ( idx != m_Scenes.Count() - 1 )
  305. return false;
  306. return true;
  307. }
  308. void CProject::MoveChildUp( ITreeItem *child )
  309. {
  310. int c = GetSceneCount();
  311. for ( int i = 1; i < c; i++ )
  312. {
  313. CScene *p = GetScene( i );
  314. if ( p != child )
  315. continue;
  316. CScene *prev = GetScene( i - 1 );
  317. // Swap
  318. m_Scenes[ i - 1 ] = p;
  319. m_Scenes[ i ] = prev;
  320. return;
  321. }
  322. }
  323. void CProject::MoveChildDown( ITreeItem *child )
  324. {
  325. int c = GetSceneCount();
  326. for ( int i = 0; i < c - 1; i++ )
  327. {
  328. CScene *p = GetScene( i );
  329. if ( p != child )
  330. continue;
  331. CScene *next = GetScene( i + 1 );
  332. // Swap
  333. m_Scenes[ i ] = next;
  334. m_Scenes[ i + 1 ] = p;
  335. return;
  336. }
  337. }