UpdatePresetDialog.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : LevelEdit *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/LevelEdit/UpdatePresetDialog.cpp $Modtime:: $*
  25. * *
  26. * $Revision:: 6 $*
  27. * *
  28. *---------------------------------------------------------------------------------------------*
  29. * Functions: *
  30. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  31. #include "stdafx.h"
  32. #include "leveledit.h"
  33. #include "updatepresetdialog.h"
  34. #include "utils.h"
  35. #include "filemgr.h"
  36. #include "filelocations.h"
  37. #include "editorini.h"
  38. #include "_assetmgr.h"
  39. #include "editorassetmgr.h"
  40. #include "ffactory.h"
  41. #include "regkeys.h"
  42. #include "specsheet.h"
  43. #include "preset.h"
  44. #include "parameter.h"
  45. #include "definitionutils.h"
  46. #include "assetdatabase.h"
  47. #ifdef _DEBUG
  48. #define new DEBUG_NEW
  49. #undef THIS_FILE
  50. static char THIS_FILE[] = __FILE__;
  51. #endif
  52. /////////////////////////////////////////////////////////////////////////////
  53. //
  54. // UpdatePresetDialogClass
  55. //
  56. /////////////////////////////////////////////////////////////////////////////
  57. UpdatePresetDialogClass::UpdatePresetDialogClass
  58. (
  59. PresetClass * preset,
  60. CWnd * parent
  61. )
  62. : m_Preset (preset),
  63. CDialog (UpdatePresetDialogClass::IDD, parent)
  64. {
  65. //{{AFX_DATA_INIT(UpdatePresetDialogClass)
  66. // NOTE: the ClassWizard will add member initialization here
  67. //}}AFX_DATA_INIT
  68. return ;
  69. }
  70. /////////////////////////////////////////////////////////////////////////////
  71. //
  72. // UpdatePresetDialogClass
  73. //
  74. /////////////////////////////////////////////////////////////////////////////
  75. void
  76. UpdatePresetDialogClass::DoDataExchange (CDataExchange* pDX)
  77. {
  78. CDialog::DoDataExchange(pDX);
  79. //{{AFX_DATA_MAP(UpdatePresetDialogClass)
  80. // NOTE: the ClassWizard will add DDX and DDV calls here
  81. //}}AFX_DATA_MAP
  82. return ;
  83. }
  84. BEGIN_MESSAGE_MAP(UpdatePresetDialogClass, CDialog)
  85. //{{AFX_MSG_MAP(UpdatePresetDialogClass)
  86. ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
  87. ON_EN_CHANGE(IDC_FILENAME_EDIT, OnChangeFilenameEdit)
  88. //}}AFX_MSG_MAP
  89. END_MESSAGE_MAP()
  90. /////////////////////////////////////////////////////////////////////////////
  91. //
  92. // OnInitDialog
  93. //
  94. /////////////////////////////////////////////////////////////////////////////
  95. BOOL
  96. UpdatePresetDialogClass::OnInitDialog (void)
  97. {
  98. CDialog::OnInitDialog ();
  99. SANITY_CHECK (m_Preset != NULL && m_Preset->Get_Definition () != NULL) {
  100. return TRUE;
  101. }
  102. //
  103. // Lookup the model-definition for this preset
  104. //
  105. DefinitionClass *definition = ::Find_Physics_Definition (m_Preset->Get_Definition ());
  106. if (definition == NULL) {
  107. definition = m_Preset->Get_Definition ();
  108. }
  109. //
  110. // Get the rectangle where we will be creating the 'spec-sheet'.
  111. //
  112. CRect rect;
  113. ::GetWindowRect (::GetDlgItem (m_hWnd, IDC_FILE_GROUP), &rect);
  114. ScreenToClient (&rect);
  115. rect.top += 12;
  116. rect.bottom -= 5;
  117. rect.left += 10;
  118. rect.right -= 10;
  119. //
  120. // Create the spec-sheet that lists only file parameters
  121. //
  122. m_ParamSheet = new SpecSheetClass (definition);
  123. m_ParamSheet->Show_File_Only (true);
  124. m_ParamSheet->Set_Asset_Tree_Only (false);
  125. m_ParamSheet->Create ("static", "", WS_CHILD | WS_VISIBLE, rect, this, 101);
  126. //
  127. // Build a list of local filenames
  128. //
  129. int count = m_ParamSheet->Get_Parameter_Count ();
  130. for (int index = 0; index < count; index ++) {
  131. ParameterClass *parameter = m_ParamSheet->Get_Parameter (index);
  132. if (parameter != NULL) {
  133. m_LocalFileList.Add (((StringParameterClass *)parameter)->Get_String ());
  134. }
  135. }
  136. //
  137. // Provide some default comments
  138. //
  139. CString comments;
  140. comments.Format ("Modified preset: %s.", m_Preset->Get_Name ());
  141. SetDlgItemText (IDC_COMMENTS_EDIT, comments);
  142. return TRUE;
  143. }
  144. /////////////////////////////////////////////////////////////////////////////
  145. //
  146. // OnBrowse
  147. //
  148. /////////////////////////////////////////////////////////////////////////////
  149. void
  150. UpdatePresetDialogClass::OnBrowse (void)
  151. {
  152. return ;
  153. }
  154. /////////////////////////////////////////////////////////////////////////////
  155. //
  156. // OnChangeFilenameEdit
  157. //
  158. /////////////////////////////////////////////////////////////////////////////
  159. void
  160. UpdatePresetDialogClass::OnChangeFilenameEdit (void)
  161. {
  162. return ;
  163. }
  164. /////////////////////////////////////////////////////////////////////////////
  165. //
  166. // OnOK
  167. //
  168. /////////////////////////////////////////////////////////////////////////////
  169. void
  170. UpdatePresetDialogClass::OnOK (void)
  171. {
  172. int count = m_ParamSheet->Get_Parameter_Count ();
  173. for (int index = 0; index < count; index ++) {
  174. //
  175. // Get the original and new filenames
  176. //
  177. CString orig_full_path = ::Get_File_Mgr ()->Make_Full_Path (m_LocalFileList[index]);
  178. CString orig_path = ::Strip_Filename_From_Path (orig_full_path);
  179. CString new_path;
  180. m_ParamSheet->Get_Current_Filename_Value (index, new_path);
  181. new_path = ::Get_File_Mgr ()->Make_Full_Path (new_path);
  182. //
  183. // Only update
  184. //
  185. CString orig_filename = ::Get_Filename_From_Path (orig_full_path);
  186. CString new_filename = ::Get_Filename_From_Path (new_path);
  187. if (orig_filename.CompareNoCase (new_filename) == 0) {
  188. //
  189. // If the user changed the path, then ask the file manager to
  190. // update the file.
  191. //
  192. if (orig_full_path.CompareNoCase (new_path) != 0) {
  193. ::Get_File_Mgr ()->Update_Model (orig_path, new_path);
  194. //
  195. // Update the INI file so it 'knows' about this latest update
  196. //
  197. CString rel_folder = ::Get_File_Mgr ()->Make_Relative_Path (orig_path);
  198. Update_INI (rel_folder);
  199. }
  200. } else {
  201. //
  202. // Warn the user that we cannot do this operation...
  203. //
  204. ParameterClass *parameter = m_ParamSheet->Get_Parameter (index);
  205. CString message;
  206. message.Format ("Cannot update %s, new filename MUST match original filename.", parameter->Get_Name ());
  207. MessageBox (message, "Invalid Entry", MB_ICONEXCLAMATION | MB_OK);
  208. }
  209. }
  210. CDialog::OnOK ();
  211. return ;
  212. }
  213. /////////////////////////////////////////////////////////////////////////////
  214. //
  215. // Update_INI
  216. //
  217. /////////////////////////////////////////////////////////////////////////////
  218. void
  219. UpdatePresetDialogClass::Update_INI (LPCTSTR rel_folder)
  220. {
  221. //
  222. // Attempt to check out the INI file
  223. //
  224. CString path = ::Get_File_Mgr ()->Make_Full_Path (UPDATE_INI_PATH);
  225. AssetDatabaseClass &asset_db = ::Get_File_Mgr ()->Get_Database_Interface ();
  226. if (asset_db.Retry_Check_Out (path, 10, 1000)) {
  227. //
  228. // Get a pointer to the INI file from the asset manager
  229. //
  230. EditorINIClass *pini = _pThe3DAssetManager->Get_INI (path);
  231. ASSERT (pini != NULL);
  232. if (pini != NULL) {
  233. //
  234. // Update the current update ID in the INI file
  235. //
  236. int curr_update_id = pini->Get_Int ("General", "ID");
  237. curr_update_id ++;
  238. pini->Put_Int ("General", "ID", curr_update_id);
  239. //
  240. // Write the (relative) folder name of the updated asset out to the INI.
  241. //
  242. CString number_string;
  243. number_string.Format ("%d", curr_update_id);
  244. pini->Put_String ("Details", number_string, rel_folder);
  245. //
  246. // Update the current time/date in the INI file
  247. //
  248. CTime current_time = CTime::GetCurrentTime ();
  249. CString time_string = current_time.Format ("%I:%M%p");
  250. CString date_string = current_time.Format ("%A, %B %d, %Y");
  251. pini->Put_String ("General", "Time", time_string);
  252. pini->Put_String ("General", "Date", date_string);
  253. //
  254. // Update the comments in the INI file
  255. //
  256. TCHAR comments[512];
  257. GetDlgItemText (IDC_COMMENTS_EDIT, comments, sizeof (comments));
  258. for (LPSTR newline = ::strchr (comments, '\r');
  259. newline != NULL;
  260. newline = ::strchr (newline, '\r'))
  261. {
  262. newline[0] = '|';
  263. newline[1] = '|';
  264. }
  265. pini->Put_TextBlock ("Comments", comments);
  266. //
  267. // Save the INI file
  268. //
  269. FileClass *pini_file = _TheFileFactory->Get_File (path);
  270. if (pini_file) {
  271. pini->Save (*pini_file);
  272. _TheFileFactory->Return_File (pini_file);
  273. }
  274. //
  275. // If the user was up-to-date before this operation, then write
  276. // his new update ID in the registry.
  277. //
  278. int update_id = theApp.GetProfileInt (CONFIG_KEY, LAST_UPDATE_VALUE, 0);
  279. if (update_id == (curr_update_id - 1)) {
  280. theApp.WriteProfileInt (CONFIG_KEY, LAST_UPDATE_VALUE, curr_update_id);
  281. }
  282. // Free the INI object
  283. SAFE_DELETE (pini);
  284. }
  285. // Now try to check in the file
  286. asset_db.Retry_Check_In (path, 10, 250);
  287. }
  288. return ;
  289. }