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.

360 lines
8.8 KiB

  1. //====== Copyright c 1996-2007, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "stdafx.h"
  9. #include "hammer.h"
  10. #include "filesystem.h"
  11. #include "mapclass.h"
  12. #include "mapentity.h"
  13. #include "history.h"
  14. #include "dlglistmanage.h"
  15. // memdbgon must be the last include file in a .cpp file!!!
  16. #include <tier0/memdbgon.h>
  17. BEGIN_MESSAGE_MAP( CDlgListManage, CDialog )
  18. ON_WM_SIZE()
  19. ON_WM_GETMINMAXINFO()
  20. ON_BN_CLICKED(IDC_SCRIPT_LIST_ADD, &CDlgListManage::OnBnClickedScriptListAdd)
  21. ON_BN_CLICKED(IDC_SCRIPT_LIST_REMOVE, &CDlgListManage::OnBnClickedScriptListRemove)
  22. ON_BN_CLICKED(IDC_SCRIPT_LIST_EDIT, &CDlgListManage::OnBnClickedScriptListEdit)
  23. END_MESSAGE_MAP()
  24. CDlgListManage::CDlgListManage(CWnd *pParent, IDlgListManageBrowse *pBrowseImpl, const CMapObjectList *pObjectList)
  25. : CDialog(CDlgListManage::IDD, pParent)
  26. {
  27. m_pBrowseImpl = pBrowseImpl;
  28. m_rcDialog.SetRectEmpty();
  29. m_pObjectList = pObjectList;
  30. }
  31. static bool StringLessFunc( CString const &a, CString const &b )
  32. {
  33. return (a < b);
  34. }
  35. void CDlgListManage::PopulateScriptList( void )
  36. {
  37. // Clear us out!
  38. m_ScriptList.ResetContent();
  39. // Populate the list
  40. CUtlMap<CString, int> mapStrings( StringLessFunc ); // A map of strings to their counts
  41. // Iterate through all map objects currently being edited
  42. FOR_EACH_OBJ( *m_pObjectList, pos )
  43. {
  44. const CMapClass *pObject = m_pObjectList->Element( pos );
  45. if ( (pObject != NULL) && (pObject->IsMapClass(MAPCLASS_TYPE(CMapEntity))) )
  46. {
  47. CMapEntity *pEntity = (CMapEntity *)pObject;
  48. CString strScriptName = pEntity->GetKeyValue( "vscripts" );
  49. // Only consider this if we have strings here!
  50. if ( strScriptName.IsEmpty() )
  51. continue;
  52. int nStart = 0;
  53. CString strToken = strScriptName.Tokenize( " ", nStart );
  54. // Now, iterate through all the listed scripts in the entity and check their counts
  55. while( strToken != "" )
  56. {
  57. // If we've removed this, filter it out
  58. if ( m_vSubtractions.Find( strToken ) != m_vSubtractions.InvalidIndex() )
  59. {
  60. strToken = strScriptName.Tokenize( " ", nStart );
  61. continue;
  62. }
  63. // Also, keep a map into the global scripts we're adding for later!
  64. int nIndex = mapStrings.Find( strToken );
  65. if ( nIndex != mapStrings.InvalidIndex() )
  66. {
  67. mapStrings[nIndex]++;
  68. }
  69. else
  70. {
  71. int nIndex = mapStrings.Insert( strToken );
  72. mapStrings[nIndex] = 1;
  73. }
  74. // Continue to the next token
  75. strToken = strScriptName.Tokenize( " ", nStart );
  76. }
  77. }
  78. }
  79. // Include new additions
  80. FOR_EACH_VEC( m_vAdditions, itr )
  81. {
  82. int nIndex = mapStrings.Insert( m_vAdditions[itr] );
  83. mapStrings[nIndex] = m_pObjectList->Count(); // Always added to all edited members
  84. }
  85. // Now go through and add things to the list with proper coloring
  86. FOR_EACH_MAP( mapStrings, itr )
  87. {
  88. // If it's the same for every object, it's bold
  89. if ( mapStrings[itr] == m_pObjectList->Count() )
  90. {
  91. if ( m_pObjectList->Count() == 1 )
  92. {
  93. // Normal (single instance)
  94. m_ScriptList.AddItemText( mapStrings.Key( itr ), LISTFONT_NORMAL );
  95. }
  96. else
  97. {
  98. // Bold (multiple instances)
  99. m_ScriptList.AddItemText( mapStrings.Key( itr ), LISTFONT_BOLD );
  100. }
  101. }
  102. else
  103. {
  104. // Red (different)
  105. m_ScriptList.AddItemText( mapStrings.Key( itr ), LISTFONT_DUPLICATE );
  106. }
  107. }
  108. }
  109. void CDlgListManage::UpdateScriptChanges( void )
  110. {
  111. // Nothing to do currently!
  112. }
  113. void CDlgListManage::SaveScriptChanges( void )
  114. {
  115. GetHistory()->MarkUndoPosition( NULL, "VScript update" );
  116. // Iterate through all map objects currently being edited
  117. FOR_EACH_OBJ( *m_pObjectList, pos )
  118. {
  119. const CMapClass *pObject = m_pObjectList->Element( pos );
  120. if ( (pObject != NULL) && (pObject->IsMapClass(MAPCLASS_TYPE(CMapEntity))) )
  121. {
  122. CMapEntity *pEntity = (CMapEntity *)pObject;
  123. CString strScriptName = pEntity->GetKeyValue( "vscripts" );
  124. GetHistory()->Keep( pEntity );
  125. // Add in all new additions
  126. FOR_EACH_VEC( m_vAdditions, itr )
  127. {
  128. // Do we already have this in the list somehow?
  129. if ( strScriptName.Find( m_vAdditions[itr], 0 ) != -1 )
  130. continue;
  131. // Append it
  132. strScriptName += " " + m_vAdditions[itr];
  133. }
  134. // Subtract things we deleted
  135. FOR_EACH_VEC( m_vSubtractions, itr )
  136. {
  137. // Find an occurence of this string in our base strings
  138. int nIndex = strScriptName.Find( m_vSubtractions[itr], 0 );
  139. if ( nIndex == -1 )
  140. continue;
  141. // Kill it!
  142. int nEndIndex = strScriptName.Find( ' ', nIndex );
  143. if ( nEndIndex == -1 )
  144. {
  145. nEndIndex = strlen( strScriptName ); // Really? You can't ask a CString its length?
  146. }
  147. strScriptName.Delete( nIndex, (nEndIndex-nIndex) );
  148. }
  149. // Done!
  150. pEntity->SetKeyValue( "vscripts", strScriptName );
  151. }
  152. }
  153. // Clear it
  154. m_vAdditions.RemoveAll();
  155. m_vSubtractions.RemoveAll();
  156. }
  157. void CDlgListManage::DoDataExchange( CDataExchange* pDX )
  158. {
  159. DDX_Control( pDX, IDC_SCRIPT_LIST, m_ScriptList );
  160. CDialog::DoDataExchange(pDX);
  161. if ( pDX->m_bSaveAndValidate )
  162. {
  163. UpdateScriptChanges();
  164. }
  165. else
  166. {
  167. PopulateScriptList();
  168. }
  169. }
  170. BOOL CDlgListManage::OnInitDialog()
  171. {
  172. BOOL bResult = CDialog::OnInitDialog();
  173. GetWindowRect( m_rcDialog );
  174. int arrCtlIds[] = { IDOK, IDCANCEL, IDC_SCRIPT_LIST, IDC_BROWSE };
  175. int riFlags[] = { ResizeInfo_t::RI_TOP_AND_LEFT, ResizeInfo_t::RI_TOP_AND_LEFT, ResizeInfo_t::RI_WIDTH_AND_HEIGHT, ResizeInfo_t::RI_TOP };
  176. for ( int k = 0; k < ARRAYSIZE( arrCtlIds ); ++ k )
  177. {
  178. CWnd *pWnd = GetDlgItem( arrCtlIds[ k ] );
  179. if ( !pWnd )
  180. continue;
  181. ResizeInfo_t ri;
  182. ri.flags = riFlags[k];
  183. pWnd->GetWindowRect( ri.rc );
  184. this->ScreenToClient( ri.rc );
  185. m_ctlInfo[ arrCtlIds[ k ] ] = ri;
  186. }
  187. if ( !m_pBrowseImpl )
  188. {
  189. if ( CWnd *pWnd = GetDlgItem( IDC_BROWSE ) )
  190. pWnd->ShowWindow( SW_HIDE );
  191. }
  192. return bResult;
  193. }
  194. void CDlgListManage::OnSize(UINT nType, int cx, int cy)
  195. {
  196. CDialog::OnSize( nType, cx, cy );
  197. CRect rcDialog;
  198. GetWindowRect( rcDialog );
  199. int dx = rcDialog.Width() - m_rcDialog.Width();
  200. int dy = rcDialog.Height() - m_rcDialog.Height();
  201. for ( POSITION pos = m_ctlInfo.GetStartPosition(); pos; )
  202. {
  203. int ctlId;
  204. ResizeInfo_t ri;
  205. m_ctlInfo.GetNextAssoc( pos, ctlId, ri );
  206. CWnd *pWnd = GetDlgItem( ctlId );
  207. if ( !pWnd )
  208. continue;
  209. CRect rcWnd = ri.rc;
  210. if ( ri.flags & ResizeInfo_t::RI_HEIGHT )
  211. rcWnd.bottom += dy;
  212. if ( ri.flags & ResizeInfo_t::RI_WIDTH )
  213. rcWnd.right += dx;
  214. if ( ri.flags & ResizeInfo_t::RI_LEFT )
  215. rcWnd.OffsetRect( dx, 0 );
  216. if ( ri.flags & ResizeInfo_t::RI_TOP )
  217. rcWnd.OffsetRect( 0, dy );
  218. pWnd->MoveWindow( rcWnd );
  219. }
  220. }
  221. void CDlgListManage::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
  222. {
  223. CDialog::OnGetMinMaxInfo( lpMMI );
  224. if ( !m_rcDialog.IsRectEmpty() )
  225. {
  226. lpMMI->ptMinTrackSize.x = m_rcDialog.Width();
  227. lpMMI->ptMinTrackSize.y = m_rcDialog.Height();
  228. }
  229. }
  230. void CDlgListManage::OnBnClickedScriptListAdd()
  231. {
  232. // Launch a browse window
  233. CStringList lstBrowse;
  234. if ( m_pBrowseImpl == NULL || m_pBrowseImpl->HandleBrowse( lstBrowse ) == false )
  235. return;
  236. // Nothing was added!
  237. if ( lstBrowse.IsEmpty() )
  238. return;
  239. // Operate on all strings we got back from the browser
  240. for ( POSITION pos = lstBrowse.GetHeadPosition(); pos; )
  241. {
  242. const CString &strTemp = lstBrowse.GetNext( pos );
  243. // Update our change lists
  244. m_vSubtractions.FindAndRemove( strTemp );
  245. // Don't add twice!
  246. if ( m_vAdditions.Find( strTemp ) == -1 )
  247. {
  248. m_vAdditions.AddToTail( strTemp );
  249. }
  250. }
  251. UpdateData();
  252. UpdateData( FALSE );
  253. }
  254. void CDlgListManage::OnBnClickedScriptListRemove()
  255. {
  256. // Remove the current selection
  257. int nSelectedItem = m_ScriptList.GetCurSel();
  258. if ( nSelectedItem != LB_ERR )
  259. {
  260. CString strOldText;
  261. m_ScriptList.GetText( nSelectedItem, strOldText );
  262. // Update our change lists
  263. m_vAdditions.FindAndRemove( strOldText );
  264. // Don't add twice!
  265. if ( m_vSubtractions.Find( strOldText ) == -1 )
  266. {
  267. m_vSubtractions.AddToTail( strOldText );
  268. }
  269. // Kill the line
  270. m_ScriptList.DeleteString( nSelectedItem );
  271. // Move our current selection around based on where we are in the list
  272. if ( nSelectedItem >= m_ScriptList.GetCount() )
  273. {
  274. nSelectedItem = m_ScriptList.GetCount() - 1;
  275. }
  276. m_ScriptList.SetCurSel( nSelectedItem ); // Don't lose selection (annoying for multi-delete)
  277. }
  278. // Now update to reflect the change
  279. UpdateData();
  280. }
  281. void CDlgListManage::OnBnClickedScriptListEdit()
  282. {
  283. // Get what they've currently selected
  284. int nSelectedItem = m_ScriptList.GetCurSel();
  285. if ( nSelectedItem == LB_ERR )
  286. return;
  287. // Get the file they've selected
  288. CString strSelectedText;
  289. m_ScriptList.GetText( nSelectedItem, strSelectedText );
  290. // Cobble together a complete filename
  291. CString strFilename = "scripts\\vscripts\\" + strSelectedText;
  292. char pFullPath[MAX_PATH];
  293. if ( g_pFullFileSystem->GetLocalPath( strFilename, pFullPath, MAX_PATH ) )
  294. {
  295. ShellExecute( NULL, "open", pFullPath, NULL, NULL, SW_SHOWNORMAL );
  296. }
  297. }