You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
490 lines
13 KiB
490 lines
13 KiB
//========= 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); |
|
}
|
|
|