//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ // //=============================================================================// // ModelCheckInDlg.cpp : implementation file // #include "stdafx.h" #include "ModelCheckIn.h" #include "ModelCheckInDlg.h" #include #include #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); }