375 lines
12 KiB
C++
375 lines
12 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/IncludeFilesDialog.cpp $Modtime:: $*
|
|
* *
|
|
* $Revision:: 3 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "leveledit.h"
|
|
#include "includefilesdialog.h"
|
|
#include "filemgr.h"
|
|
#include "icons.h"
|
|
#include "utils.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IncludeFilesDialogClass
|
|
//
|
|
IncludeFilesDialogClass::IncludeFilesDialogClass(CWnd* pParent /*=NULL*/)
|
|
: m_hGlobalFolder (NULL),
|
|
m_hLevelFolder (NULL),
|
|
m_CurrentItem (NULL),
|
|
CDialog(IncludeFilesDialogClass::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(IncludeFilesDialogClass)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DoDataExchange
|
|
//
|
|
void
|
|
IncludeFilesDialogClass::DoDataExchange (CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(IncludeFilesDialogClass)
|
|
DDX_Control(pDX, IDC_INCLUDE_TREE, m_IncludesTreeCtrl);
|
|
//}}AFX_DATA_MAP
|
|
return ;
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(IncludeFilesDialogClass, CDialog)
|
|
//{{AFX_MSG_MAP(IncludeFilesDialogClass)
|
|
ON_NOTIFY(TVN_SELCHANGED, IDC_INCLUDE_TREE, OnSelchangedIncludeTree)
|
|
ON_EN_CHANGE(IDC_SPEC_EDIT, OnChangeSpecEdit)
|
|
ON_BN_CLICKED(IDC_ADD_REMOVE_BUTTON, OnAddRemoveButton)
|
|
ON_WM_DESTROY()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OnInitDialog
|
|
//
|
|
BOOL
|
|
IncludeFilesDialogClass::OnInitDialog (void)
|
|
{
|
|
// Allow the base class to process this message
|
|
CDialog::OnInitDialog ();
|
|
|
|
// Insert the 2 main folders into the tree control
|
|
m_IncludesTreeCtrl.SetImageList (::Get_Global_Image_List (), TVSIL_NORMAL);
|
|
m_hGlobalFolder = m_IncludesTreeCtrl.InsertItem ("Global", FOLDER_ICON, FOLDER_ICON);
|
|
m_hLevelFolder = m_IncludesTreeCtrl.InsertItem ("Level Specific", FOLDER_ICON, FOLDER_ICON);
|
|
|
|
// Ensure the file manager has the latest and greatest
|
|
::Get_File_Mgr ()->Build_Global_Include_List ();
|
|
|
|
// Loop through all the global include files and add them to the tree control
|
|
DynamicVectorClass<CString> &global_list = ::Get_File_Mgr ()->Get_Global_Include_File_List ();
|
|
for (int index = 0; index < global_list.Count (); index ++) {
|
|
int icon_index = (::strpbrk (global_list[index], "*?") != NULL) ? FILES_ICON : FILE_ICON;
|
|
m_IncludesTreeCtrl.InsertItem (global_list[index], icon_index, icon_index, m_hGlobalFolder);
|
|
}
|
|
|
|
// Loop through all the level-specific include files and add them to the tree control
|
|
DynamicVectorClass<CString> &level_list = ::Get_File_Mgr ()->Get_Include_File_List ();
|
|
for (index = 0; index < level_list.Count (); index ++) {
|
|
int icon_index = (::strpbrk (level_list[index], "*?") != NULL) ? FILES_ICON : FILE_ICON;
|
|
m_IncludesTreeCtrl.InsertItem (level_list[index], icon_index, icon_index, m_hLevelFolder);
|
|
}
|
|
|
|
// Create the file picker control
|
|
CRect rect;
|
|
HWND hold_edit = ::GetDlgItem (m_hWnd, IDC_SPEC_EDIT);
|
|
::GetWindowRect (hold_edit, &rect);
|
|
ScreenToClient (&rect);
|
|
m_FilePicker.Create_Picker (WS_CHILD | WS_TABSTOP | WS_VISIBLE,
|
|
rect,
|
|
this,
|
|
IDC_SPEC_EDIT);
|
|
|
|
::SetWindowPos (m_FilePicker, ::GetDlgItem (m_hWnd, IDC_SPEC_STATIC), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER);
|
|
::DestroyWindow (hold_edit);
|
|
|
|
// Ensure the file specs are sorted
|
|
m_IncludesTreeCtrl.SortChildren (m_hGlobalFolder);
|
|
m_IncludesTreeCtrl.SortChildren (m_hLevelFolder);
|
|
m_IncludesTreeCtrl.SelectItem (m_hGlobalFolder);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OnOK
|
|
//
|
|
void
|
|
IncludeFilesDialogClass::OnOK (void)
|
|
{
|
|
DynamicVectorClass<CString> &global_list = ::Get_File_Mgr ()->Get_Global_Include_File_List ();
|
|
DynamicVectorClass<CString> &level_list = ::Get_File_Mgr ()->Get_Include_File_List ();
|
|
global_list.Delete_All ();
|
|
level_list.Delete_All ();
|
|
|
|
// Loop through all the children of the global folder
|
|
for (HTREEITEM hchild = m_IncludesTreeCtrl.GetChildItem (m_hGlobalFolder);
|
|
hchild != NULL;
|
|
hchild = m_IncludesTreeCtrl.GetNextSiblingItem (hchild)) {
|
|
|
|
// Add this filespec to the global list
|
|
CString child_text = m_IncludesTreeCtrl.GetItemText (hchild);
|
|
global_list.Add (child_text);
|
|
}
|
|
|
|
// Loop through all the children of the level-specific folder
|
|
for (hchild = m_IncludesTreeCtrl.GetChildItem (m_hLevelFolder);
|
|
hchild != NULL;
|
|
hchild = m_IncludesTreeCtrl.GetNextSiblingItem (hchild)) {
|
|
|
|
// Add this filespec to the local list
|
|
CString child_text = m_IncludesTreeCtrl.GetItemText (hchild);
|
|
level_list.Add (child_text);
|
|
}
|
|
|
|
// Check the latest copy of the global include file list into the VSS
|
|
::Get_File_Mgr ()->Update_Global_Include_File_List ();
|
|
|
|
// Allow the base class to process this message
|
|
CDialog::OnOK ();
|
|
return ;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OnSelchangedIncludeTree
|
|
//
|
|
void
|
|
IncludeFilesDialogClass::OnSelchangedIncludeTree
|
|
(
|
|
NMHDR *pNMHDR,
|
|
LRESULT *pResult
|
|
)
|
|
{
|
|
NM_TREEVIEW *pNMTreeView = (NM_TREEVIEW *)pNMHDR;
|
|
(*pResult) = 0;
|
|
|
|
// Change the text in the edit control to reflect the new selection
|
|
HTREEITEM hitem = m_IncludesTreeCtrl.GetSelectedItem ();
|
|
if (m_IncludesTreeCtrl.GetParentItem (hitem) != NULL) {
|
|
|
|
// Put the file spec into the edit control
|
|
CString path = m_IncludesTreeCtrl.GetItemText (hitem);
|
|
SetDlgItemText (IDC_SPEC_EDIT, path);
|
|
SetDlgItemText (IDC_ADD_REMOVE_BUTTON, "&Remove");
|
|
m_CurrentItem = hitem;
|
|
|
|
// Let the file picker know the full path to the file
|
|
path = ::Get_File_Mgr ()->Make_Full_Path (path);
|
|
m_FilePicker.Set_Default_Filename (path);
|
|
|
|
} else {
|
|
//SetDlgItemText (IDC_SPEC_EDIT, "");
|
|
SetDlgItemText (IDC_ADD_REMOVE_BUTTON, "&Add");
|
|
m_CurrentItem = NULL;
|
|
}
|
|
|
|
// Ensure the 'add/remove' button is correctly enabled/disabled
|
|
//::EnableWindow (::GetDlgItem (m_hWnd, IDC_ADD_REMOVE_BUTTON), enable_button);
|
|
|
|
// Refresh the state of the 'add/remove' button
|
|
//Update_Add_Remove_Button ();
|
|
return ;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Update_Add_Remove_Button
|
|
//
|
|
void
|
|
IncludeFilesDialogClass::Update_Add_Remove_Button (void)
|
|
{
|
|
CString filespec;
|
|
GetDlgItemText (IDC_SPEC_EDIT, filespec);
|
|
filespec = ::Get_File_Mgr ()->Make_Relative_Path (filespec);
|
|
|
|
// Determine which item to use as a parent
|
|
HTREEITEM hselected_item = m_IncludesTreeCtrl.GetSelectedItem ();
|
|
HTREEITEM hroot = hselected_item;
|
|
if (m_IncludesTreeCtrl.GetParentItem (hroot) != NULL) {
|
|
hroot = m_IncludesTreeCtrl.GetParentItem (hroot);
|
|
}
|
|
|
|
// Change the button text if the entry was found or not
|
|
m_CurrentItem = Find_Spec (filespec, hroot);
|
|
if (m_CurrentItem != NULL) {
|
|
SetDlgItemText (IDC_ADD_REMOVE_BUTTON, "&Remove");
|
|
|
|
// Ensure this item is selected in the tree control as well
|
|
if (hselected_item != m_CurrentItem) {
|
|
m_IncludesTreeCtrl.SelectItem (m_CurrentItem);
|
|
m_IncludesTreeCtrl.EnsureVisible (m_CurrentItem);
|
|
}
|
|
|
|
} else {
|
|
SetDlgItemText (IDC_ADD_REMOVE_BUTTON, "&Add");
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Find_Spec
|
|
//
|
|
HTREEITEM
|
|
IncludeFilesDialogClass::Find_Spec
|
|
(
|
|
LPCTSTR filespec,
|
|
HTREEITEM hroot
|
|
)
|
|
{
|
|
HTREEITEM hitem = NULL;
|
|
|
|
// Loop through all the children of the global folder
|
|
for (HTREEITEM hchild = m_IncludesTreeCtrl.GetChildItem (hroot);
|
|
(hchild != NULL) && (hitem == NULL);
|
|
hchild = m_IncludesTreeCtrl.GetNextSiblingItem (hchild)) {
|
|
|
|
// Is this the entry we are looking for?
|
|
CString child_text = m_IncludesTreeCtrl.GetItemText (hchild);
|
|
if (child_text.CompareNoCase (filespec) == 0) {
|
|
hitem = hchild;
|
|
}
|
|
}
|
|
|
|
// Return the tree item if we found the item
|
|
return hitem;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OnChangeSpecEdit
|
|
//
|
|
void
|
|
IncludeFilesDialogClass::OnChangeSpecEdit (void)
|
|
{
|
|
Update_Add_Remove_Button ();
|
|
return ;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OnAddRemoveButton
|
|
//
|
|
void
|
|
IncludeFilesDialogClass::OnAddRemoveButton (void)
|
|
{
|
|
// Are we adding or removing an entry from the tree control?
|
|
if (m_CurrentItem != NULL) {
|
|
HTREEITEM hnew_sel = m_IncludesTreeCtrl.GetPrevSiblingItem (m_CurrentItem);
|
|
hnew_sel = (hnew_sel != NULL) ? hnew_sel : m_hGlobalFolder;
|
|
m_IncludesTreeCtrl.DeleteItem (m_CurrentItem);
|
|
m_IncludesTreeCtrl.SelectItem (hnew_sel);
|
|
m_IncludesTreeCtrl.EnsureVisible (hnew_sel);
|
|
} else {
|
|
|
|
// Determine which item to use as a parent
|
|
HTREEITEM hitem = m_IncludesTreeCtrl.GetSelectedItem ();
|
|
if (m_IncludesTreeCtrl.GetParentItem (hitem) != NULL) {
|
|
hitem = m_IncludesTreeCtrl.GetParentItem (hitem);
|
|
}
|
|
|
|
// Get the text the user entered
|
|
CString filespec;
|
|
GetDlgItemText (IDC_SPEC_EDIT, filespec);
|
|
|
|
// Is the new path valid?
|
|
bool rel_path = ::Is_Path_Relative (filespec);
|
|
if ((rel_path == true) || ((rel_path == false) && ::Get_File_Mgr ()->Is_Path_Valid (filespec))) {
|
|
|
|
// Add this entry to the tree control
|
|
CString new_entry = ::Get_File_Mgr ()->Make_Relative_Path (filespec);
|
|
int icon_index = (::strpbrk (new_entry, "*?") != NULL) ? FILES_ICON : FILE_ICON;
|
|
HTREEITEM hnew_item = m_IncludesTreeCtrl.InsertItem (new_entry, icon_index, icon_index, hitem);
|
|
|
|
// Now select this new item...
|
|
m_IncludesTreeCtrl.SelectItem (hnew_item);
|
|
m_IncludesTreeCtrl.EnsureVisible (hnew_item);
|
|
|
|
} else {
|
|
|
|
// Let the user know this path is invalid
|
|
CString message;
|
|
CString title;
|
|
message.Format (IDS_INVALID_MODEL_PATH_MSG, (LPCTSTR)::Get_File_Mgr()->Get_Base_Path ());
|
|
title.LoadString (IDS_INVALID_MODEL_PATH_TITLE);
|
|
::MessageBox (m_hWnd, message, title, MB_ICONERROR | MB_OK);
|
|
}
|
|
}
|
|
|
|
// Ensure the file specs are sorted
|
|
m_IncludesTreeCtrl.SortChildren (m_hGlobalFolder);
|
|
m_IncludesTreeCtrl.SortChildren (m_hLevelFolder);
|
|
return ;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OnDestroy
|
|
//
|
|
void
|
|
IncludeFilesDialogClass::OnDestroy (void)
|
|
{
|
|
m_IncludesTreeCtrl.SetImageList (NULL, TVSIL_NORMAL);
|
|
CDialog::OnDestroy();
|
|
return ;
|
|
}
|