/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** 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 *** *********************************************************************************************** * * * Project Name : LevelEdit * * * * $Archive:: /Commando/Code/Tools/LevelEdit/UpdatePresetDialog.cpp $Modtime:: $* * * * $Revision:: 6 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "stdafx.h" #include "leveledit.h" #include "updatepresetdialog.h" #include "utils.h" #include "filemgr.h" #include "filelocations.h" #include "editorini.h" #include "_assetmgr.h" #include "editorassetmgr.h" #include "ffactory.h" #include "regkeys.h" #include "specsheet.h" #include "preset.h" #include "parameter.h" #include "definitionutils.h" #include "assetdatabase.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // // UpdatePresetDialogClass // ///////////////////////////////////////////////////////////////////////////// UpdatePresetDialogClass::UpdatePresetDialogClass ( PresetClass * preset, CWnd * parent ) : m_Preset (preset), CDialog (UpdatePresetDialogClass::IDD, parent) { //{{AFX_DATA_INIT(UpdatePresetDialogClass) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT return ; } ///////////////////////////////////////////////////////////////////////////// // // UpdatePresetDialogClass // ///////////////////////////////////////////////////////////////////////////// void UpdatePresetDialogClass::DoDataExchange (CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(UpdatePresetDialogClass) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP return ; } BEGIN_MESSAGE_MAP(UpdatePresetDialogClass, CDialog) //{{AFX_MSG_MAP(UpdatePresetDialogClass) ON_BN_CLICKED(IDC_BROWSE, OnBrowse) ON_EN_CHANGE(IDC_FILENAME_EDIT, OnChangeFilenameEdit) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // // OnInitDialog // ///////////////////////////////////////////////////////////////////////////// BOOL UpdatePresetDialogClass::OnInitDialog (void) { CDialog::OnInitDialog (); SANITY_CHECK (m_Preset != NULL && m_Preset->Get_Definition () != NULL) { return TRUE; } // // Lookup the model-definition for this preset // DefinitionClass *definition = ::Find_Physics_Definition (m_Preset->Get_Definition ()); if (definition == NULL) { definition = m_Preset->Get_Definition (); } // // Get the rectangle where we will be creating the 'spec-sheet'. // CRect rect; ::GetWindowRect (::GetDlgItem (m_hWnd, IDC_FILE_GROUP), &rect); ScreenToClient (&rect); rect.top += 12; rect.bottom -= 5; rect.left += 10; rect.right -= 10; // // Create the spec-sheet that lists only file parameters // m_ParamSheet = new SpecSheetClass (definition); m_ParamSheet->Show_File_Only (true); m_ParamSheet->Set_Asset_Tree_Only (false); m_ParamSheet->Create ("static", "", WS_CHILD | WS_VISIBLE, rect, this, 101); // // Build a list of local filenames // int count = m_ParamSheet->Get_Parameter_Count (); for (int index = 0; index < count; index ++) { ParameterClass *parameter = m_ParamSheet->Get_Parameter (index); if (parameter != NULL) { m_LocalFileList.Add (((StringParameterClass *)parameter)->Get_String ()); } } // // Provide some default comments // CString comments; comments.Format ("Modified preset: %s.", m_Preset->Get_Name ()); SetDlgItemText (IDC_COMMENTS_EDIT, comments); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // // OnBrowse // ///////////////////////////////////////////////////////////////////////////// void UpdatePresetDialogClass::OnBrowse (void) { return ; } ///////////////////////////////////////////////////////////////////////////// // // OnChangeFilenameEdit // ///////////////////////////////////////////////////////////////////////////// void UpdatePresetDialogClass::OnChangeFilenameEdit (void) { return ; } ///////////////////////////////////////////////////////////////////////////// // // OnOK // ///////////////////////////////////////////////////////////////////////////// void UpdatePresetDialogClass::OnOK (void) { int count = m_ParamSheet->Get_Parameter_Count (); for (int index = 0; index < count; index ++) { // // Get the original and new filenames // CString orig_full_path = ::Get_File_Mgr ()->Make_Full_Path (m_LocalFileList[index]); CString orig_path = ::Strip_Filename_From_Path (orig_full_path); CString new_path; m_ParamSheet->Get_Current_Filename_Value (index, new_path); new_path = ::Get_File_Mgr ()->Make_Full_Path (new_path); // // Only update // CString orig_filename = ::Get_Filename_From_Path (orig_full_path); CString new_filename = ::Get_Filename_From_Path (new_path); if (orig_filename.CompareNoCase (new_filename) == 0) { // // If the user changed the path, then ask the file manager to // update the file. // if (orig_full_path.CompareNoCase (new_path) != 0) { ::Get_File_Mgr ()->Update_Model (orig_path, new_path); // // Update the INI file so it 'knows' about this latest update // CString rel_folder = ::Get_File_Mgr ()->Make_Relative_Path (orig_path); Update_INI (rel_folder); } } else { // // Warn the user that we cannot do this operation... // ParameterClass *parameter = m_ParamSheet->Get_Parameter (index); CString message; message.Format ("Cannot update %s, new filename MUST match original filename.", parameter->Get_Name ()); MessageBox (message, "Invalid Entry", MB_ICONEXCLAMATION | MB_OK); } } CDialog::OnOK (); return ; } ///////////////////////////////////////////////////////////////////////////// // // Update_INI // ///////////////////////////////////////////////////////////////////////////// void UpdatePresetDialogClass::Update_INI (LPCTSTR rel_folder) { // // Attempt to check out the INI file // CString path = ::Get_File_Mgr ()->Make_Full_Path (UPDATE_INI_PATH); AssetDatabaseClass &asset_db = ::Get_File_Mgr ()->Get_Database_Interface (); if (asset_db.Retry_Check_Out (path, 10, 1000)) { // // Get a pointer to the INI file from the asset manager // EditorINIClass *pini = _pThe3DAssetManager->Get_INI (path); ASSERT (pini != NULL); if (pini != NULL) { // // Update the current update ID in the INI file // int curr_update_id = pini->Get_Int ("General", "ID"); curr_update_id ++; pini->Put_Int ("General", "ID", curr_update_id); // // Write the (relative) folder name of the updated asset out to the INI. // CString number_string; number_string.Format ("%d", curr_update_id); pini->Put_String ("Details", number_string, rel_folder); // // Update the current time/date in the INI file // CTime current_time = CTime::GetCurrentTime (); CString time_string = current_time.Format ("%I:%M%p"); CString date_string = current_time.Format ("%A, %B %d, %Y"); pini->Put_String ("General", "Time", time_string); pini->Put_String ("General", "Date", date_string); // // Update the comments in the INI file // TCHAR comments[512]; GetDlgItemText (IDC_COMMENTS_EDIT, comments, sizeof (comments)); for (LPSTR newline = ::strchr (comments, '\r'); newline != NULL; newline = ::strchr (newline, '\r')) { newline[0] = '|'; newline[1] = '|'; } pini->Put_TextBlock ("Comments", comments); // // Save the INI file // FileClass *pini_file = _TheFileFactory->Get_File (path); if (pini_file) { pini->Save (*pini_file); _TheFileFactory->Return_File (pini_file); } // // If the user was up-to-date before this operation, then write // his new update ID in the registry. // int update_id = theApp.GetProfileInt (CONFIG_KEY, LAST_UPDATE_VALUE, 0); if (update_id == (curr_update_id - 1)) { theApp.WriteProfileInt (CONFIG_KEY, LAST_UPDATE_VALUE, curr_update_id); } // Free the INI object SAFE_DELETE (pini); } // Now try to check in the file asset_db.Retry_Check_In (path, 10, 250); } return ; }