This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Tools/LevelEdit/UpdatePresetDialog.cpp

334 lines
10 KiB
C++

/*
** 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 <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** 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 ;
}