source-engine-2018-hl2_src/utils/modelcheckin/modelcheckindlg.cpp

491 lines
13 KiB
C++
Raw Normal View History

2020-04-23 00:56:21 +08:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// ModelCheckInDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ModelCheckIn.h"
#include "ModelCheckInDlg.h"
#include <direct.h>
#include <sys/stat.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CModelCheckInDlg dialog
CModelCheckInDlg::CModelCheckInDlg(CWnd* pParent /*=NULL*/)
: CDialog(CModelCheckInDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CModelCheckInDlg)
m_HL2GameDirectory = _T("");
m_TF2GameDirectory = _T("");
m_UserName = _T("");
m_HL2Radio = -1;
m_TF2Radio = -1;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CModelCheckInDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CModelCheckInDlg)
DDX_Text(pDX, IDC_EDIT_HL2_GAME_DIRECTORY, m_HL2GameDirectory);
DDX_Text(pDX, IDC_EDIT_TF2_GAME_DIRECTORY, m_TF2GameDirectory);
DDX_Text(pDX, IDC_EDIT_USERNAME, m_UserName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CModelCheckInDlg, CDialog)
//{{AFX_MSG_MAP(CModelCheckInDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_COMMAND(ID_FILE_CHECK_OUT, OnFileCheckOut)
ON_COMMAND(ID_FILE_CHECK_IN, OnFileCheckIn)
ON_COMMAND(ID_FILE_EXIT, OnFileExit)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CModelCheckInDlg message handlers
BOOL CModelCheckInDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Restore state
RestoreStateFromRegistry();
UpdateData( FALSE );
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CModelCheckInDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CModelCheckInDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//-----------------------------------------------------------------------------
// Resets our last used directory
//-----------------------------------------------------------------------------
void CModelCheckInDlg::ResetDirectoryEntry( CString &fullPath, char *pRegEntry )
{
// reset the last directory...
CString temp = fullPath;
int i = temp.ReverseFind( '\\' );
int j = temp.ReverseFind( '/' );
if (i < j) i = j;
temp.SetAt(i, 0);
AfxGetApp()->WriteProfileString( MDL_CHECKOUT_REG_CLASS, pRegEntry, temp );
}
//-----------------------------------------------------------------------------
// Stores state
//-----------------------------------------------------------------------------
void CModelCheckInDlg::StoreStateIntoRegistry( )
{
AfxGetApp()->WriteProfileString( MDL_CHECKOUT_REG_CLASS,
MDL_CHECKOUT_REG_USER, m_UserName );
AfxGetApp()->WriteProfileString( MDL_CHECKOUT_REG_CLASS,
MDL_CHECKOUT_REG_HL2_PATH, m_HL2GameDirectory );
AfxGetApp()->WriteProfileString( MDL_CHECKOUT_REG_CLASS,
MDL_CHECKOUT_REG_TF2_PATH, m_TF2GameDirectory );
}
//-----------------------------------------------------------------------------
// Restores state
//-----------------------------------------------------------------------------
void CModelCheckInDlg::RestoreStateFromRegistry( )
{
m_UserName = AfxGetApp()->GetProfileString( MDL_CHECKOUT_REG_CLASS,
MDL_CHECKOUT_REG_USER, "" );
m_HL2GameDirectory = AfxGetApp()->GetProfileString( MDL_CHECKOUT_REG_CLASS,
MDL_CHECKOUT_REG_HL2_PATH, "u:/hl2/hl2" );
m_TF2GameDirectory = AfxGetApp()->GetProfileString( MDL_CHECKOUT_REG_CLASS,
MDL_CHECKOUT_REG_TF2_PATH, "u:/hl2/tf2" );
}
//-----------------------------------------------------------------------------
// Extensions of all files related to the model file
//-----------------------------------------------------------------------------
static char* s_ppExtensions[] =
{
".dx7_2bone.vtx",
".dx80.vtx",
".phy",
".mdl",
""
};
static char* s_ppProjectDir[] =
{
"$/HL2/release/dev/hl2/",
"$/TF2/release/dev/tf2/"
};
//-----------------------------------------------------------------------------
// Checks it out/ checks it in baby
//-----------------------------------------------------------------------------
void CModelCheckInDlg::PerformCheckoutCommand( ProjectType_t project,
char const* pRelativeDir, char const* pDestPath, char const* pFileName )
{
char error[1024];
char buf[1024];
int len = 0;
int currExtension;
for ( currExtension = 0; s_ppExtensions[currExtension][0]; ++currExtension )
{
// Check for the existence of the file in source safe...
sprintf( buf, "ss filetype %s%s/%s%s -O- -y%s\n",
s_ppProjectDir[project], pRelativeDir, pFileName, s_ppExtensions[currExtension],
(char const*)m_UserName );
int retVal = system( buf );
if (retVal > 0)
continue;
// It's there, try to check it out
sprintf( buf, "ss checkout %s%s/%s%s -GL%s -GWA -O- -y%s\n",
s_ppProjectDir[project], pRelativeDir, pFileName, s_ppExtensions[currExtension],
pDestPath, (char const*)m_UserName );
retVal = system( buf );
if (retVal > 0)
{
len += sprintf( &error[len], "*** SourceSafe error attempting to check out \"%s%s\"\n",
pFileName, s_ppExtensions[currExtension] );
}
}
if (len > 0)
{
MessageBox( error, "Error!" );
}
}
//-----------------------------------------------------------------------------
// Checks it out/ checks it in baby
//-----------------------------------------------------------------------------
void CModelCheckInDlg::PerformCheckinCommand( ProjectType_t project,
char const* pRelativeDir, char const* pDestPath, char const* pFileName )
{
char buf[1024];
char error[1024];
int len = 0;
int currExtension;
for ( currExtension = 0; s_ppExtensions[currExtension][0]; ++currExtension )
{
// Check for the existence of the file on disk. If it's not there, don't bother
sprintf( buf, "%s/%s%s", pDestPath, pFileName, s_ppExtensions[currExtension] );
struct _stat statbuf;
int result = _stat( buf, &statbuf );
if (result != 0)
continue;
// Check for the existence of the file in source safe...
sprintf( buf, "ss filetype %s%s/%s%s -O- -y%s\n",
s_ppProjectDir[project], pRelativeDir, pFileName, s_ppExtensions[currExtension],
(char const*)m_UserName );
int retVal = system( buf );
if (retVal > 0)
{
// Try to add the file to source safe...
sprintf( buf, "ss add %s%s/%s%s -GL%s -O- -y%s\n",
s_ppProjectDir[project], pRelativeDir, pFileName, s_ppExtensions[currExtension],
pDestPath, (char const*)m_UserName );
int retVal = system( buf );
if (retVal > 0)
{
len += sprintf( &error[len], "SourceSafe error attempting to add \"%s%s\"\n",
pFileName, s_ppExtensions[currExtension] );
}
}
else
{
// It's there, just check it in
sprintf( buf, "ss checkin %s%s/%s%s -GL%s -O- -y%s\n",
s_ppProjectDir[project], pRelativeDir, pFileName, s_ppExtensions[currExtension],
pDestPath, (char const*)m_UserName );
retVal = system( buf );
if (retVal > 0)
{
len += sprintf( &error[len], "SourceSafe error attempting to check in \"%s%s\"\n",
pFileName, s_ppExtensions[currExtension] );
}
}
}
if (len > 0)
{
MessageBox( error, "Error!" );
}
}
//-----------------------------------------------------------------------------
// Fixes up a filename
//-----------------------------------------------------------------------------
static int FixupFileName( char const* pInFile, char* pOutBuf )
{
if (!pInFile)
{
*pOutBuf = '\0';
return 0;
}
int len = strlen(pInFile);
for (int i = 0; i <= len; ++i)
{
pOutBuf[i] = tolower( pInFile[i] );
if (pOutBuf[i] == '\\')
pOutBuf[i] = '/';
}
// Make sure no trailing '/'
if (pOutBuf[len - 1] == '/')
pOutBuf[--len] = '\0';
return len;
}
//-----------------------------------------------------------------------------
// Gets the relative file name
//-----------------------------------------------------------------------------
CModelCheckInDlg::ProjectType_t CModelCheckInDlg::ComputeRelativeFileName( char const* pInFile, char* pRelativeFile )
{
// Depending on which project is selected, strip out the game directory
char tempIn[MAX_PATH];
char tempPath[MAX_PATH];
FixupFileName( pInFile, tempIn );
int len;
if (!m_HL2GameDirectory.IsEmpty())
{
len = FixupFileName( m_HL2GameDirectory, tempPath );
if (!strncmp( tempIn, m_HL2GameDirectory, len ))
{
strcpy( pRelativeFile, &tempIn[len+1] );
return PROJECT_HL2;
}
}
if (!m_TF2GameDirectory.IsEmpty())
{
len = FixupFileName( m_TF2GameDirectory, tempPath );
if (!strncmp( tempIn, m_TF2GameDirectory, len ))
{
strcpy( pRelativeFile, &tempIn[len+1] );
return PROJECT_TF2;
}
}
return PROJECT_ERROR;
}
//-----------------------------------------------------------------------------
// Have we typed in anything for our user name?
//-----------------------------------------------------------------------------
bool CModelCheckInDlg::CheckInfo()
{
if (m_UserName.IsEmpty())
{
MessageBox( "Please enter your user name.\n", "Error!" );
return false;
}
if (m_HL2GameDirectory.IsEmpty() && m_TF2GameDirectory.IsEmpty())
{
MessageBox( "Please enter the game directories for HL2 and/or TF2.\n", "Error!" );
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Resets our last used directory
//-----------------------------------------------------------------------------
CModelCheckInDlg::ProjectType_t CModelCheckInDlg::GetFileNames( char const* pTitle,
char*& pRelativePath, char*& pFileName, char*& pDestPath )
{
UpdateData( TRUE );
StoreStateIntoRegistry();
if (!CheckInfo())
return PROJECT_ERROR;
CFileDialog dlg( TRUE, ".mdl", "*.mdl", OFN_HIDEREADONLY,
"Model Files (*.mdl)|*.mdl||" );
// Set up initial paths
char pCwd[MAX_PATH];
_getcwd( pCwd, MAX_PATH );
// Setup the title and initial directory
CString temp = AfxGetApp()->GetProfileString( MDL_CHECKOUT_REG_CLASS,
MDL_CHECKOUT_REG_LAST_PATH, pCwd );
dlg.m_ofn.lpstrInitialDir = temp;
dlg.m_ofn.lpstrTitle = pTitle;
// Grab the data from the dialog...
if (dlg.DoModal() != IDOK)
return PROJECT_ERROR;
// Get the relative file name
static char relativeFile[MAX_PATH];
ProjectType_t projectType = ComputeRelativeFileName( dlg.GetPathName(), relativeFile );
if (projectType == PROJECT_ERROR)
{
char buf[MAX_PATH];
sprintf( buf, "%s\nwas not found under either game directory!\n", dlg.GetPathName() );
MessageBox( buf, "Error!" );
return PROJECT_ERROR;
}
// reset the last directory...
ResetDirectoryEntry( dlg.GetPathName(), MDL_CHECKOUT_REG_LAST_PATH );
// Split into relative file + path...
char* pSlash = strrchr( relativeFile, '/' );
if (pSlash)
{
*pSlash = 0;
pRelativePath = relativeFile;
pFileName = pSlash + 1;
}
else
{
pFileName = relativeFile;
pRelativePath = "";
}
// Remove extension
char* pExt = strchr( pFileName, '.' );
if (pExt)
*pExt = 0;
static char destPath[MAX_PATH];
FixupFileName( dlg.GetPathName(), destPath );
pSlash = strrchr( destPath, '/' );
if (pSlash)
*pSlash = 0;
else
destPath[0] = 0;
pDestPath = destPath;
return projectType;
}
//-----------------------------------------------------------------------------
// Does checkout and check-in
//-----------------------------------------------------------------------------
void CModelCheckInDlg::OnFileCheckOut()
{
char* pRelativePath;
char* pFileName;
char* pDestPath;
ProjectType_t projectType;
projectType = GetFileNames( "Select MDL file to check out...", pRelativePath,
pFileName, pDestPath );
if (projectType != PROJECT_ERROR)
{
PerformCheckoutCommand( projectType, pRelativePath, pDestPath, pFileName );
}
}
void CModelCheckInDlg::OnFileCheckIn()
{
char* pRelativePath;
char* pFileName;
char* pDestPath;
ProjectType_t projectType;
projectType = GetFileNames( "Select MDL file to check in...", pRelativePath,
pFileName, pDestPath );
if (projectType != PROJECT_ERROR)
{
PerformCheckinCommand( projectType, pRelativePath, pDestPath, pFileName );
}
}
void CModelCheckInDlg::OnFileExit()
{
PostQuitMessage(0);
}