// // Copyright 1997 Nicholas J. Irias. All rights reserved. // // // Cmd_PrepBrowse.cpp #include "stdafx.h" #include "p4win.h" #include "cmd_prepbrowse.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNCREATE(CCmd_PrepBrowse, CP4Command) CCmd_PrepBrowse::CCmd_PrepBrowse(CGuiClient *client) : CP4Command(client) { m_ReplyMsg= WM_P4PREPBROWSE; m_TaskName= _T("PrepBrowse"); m_pOutputFile=NULL; m_Annotating = m_bP4a = m_NoFileAtRev = FALSE; m_FileRev = -1; m_Type = FST_CANTTELL; } CCmd_PrepBrowse::~CCmd_PrepBrowse() { if(m_pOutputFile != NULL) delete m_pOutputFile; } // Normal p4 print of file BOOL CCmd_PrepBrowse::Run(LPCTSTR fileSpec, CString &fileType, long fileRev, BOOL bForce2Binary) { ASSERT(fileSpec != NULL); if(!SetupPrint(fileSpec, fileType, fileRev, bForce2Binary)) return FALSE; // Assign properties to keep track of temp file retrieval m_ByteCount=0; // Set the arg list ClearArgs(); AddArg(_T("print")); if (GET_SERVERLEVEL() >= 10) { AddArg(_T("-o")); AddArg(m_TempName); } AddArg(_T("-q")); CString DepotName; if (fileRev < 0) DepotName = fileSpec; else DepotName.Format(_T("%s#%d"), fileSpec, fileRev); AddArg(DepotName); return CP4Command::Run(); } // p4 annotate BOOL CCmd_PrepBrowse::Run(BOOL bUseP4A, LPCTSTR fileSpec, CString &fileType, BOOL bAll/*=FALSE*/, BOOL bChg/*=FALSE*/, BOOL bNoHead/*=FALSE*/, long fileRev/*=-1*/, int whtSp/*=0*/, BOOL bIncInteg/*=FALSE*/) { if (GET_SERVERLEVEL() < 14) return FALSE; ASSERT(fileSpec != NULL); m_Annotating = TRUE; m_bP4a = bUseP4A; if(!SetupPrint(fileSpec, fileType, fileRev, TRUE)) return FALSE; // Assign properties to keep track of temp file retrieval m_ByteCount=0; // Set the arg list ClearArgs(); AddArg(_T("annotate")); if (bAll) AddArg(_T("-a")); if (bChg) AddArg(_T("-c")); if (bNoHead) AddArg(_T("-q")); CString DepotName; m_FileRev = fileRev; if (fileRev < 0 || m_bP4a) DepotName = fileSpec; else DepotName.Format(_T("%s#%d"), fileSpec, fileRev); if (GET_SERVERLEVEL() >= 20) // 2005.2 or later? { switch(whtSp) { case 1: AddArg(_T("-db")); break; case 2: AddArg(_T("-dw")); break; case 0: default: break; } if (bIncInteg) AddArg(_T("-i")); } AddArg(DepotName); return CP4Command::Run(); } void CCmd_PrepBrowse::OnOutputText(LPCTSTR data, int length) { // if server is 2000.2 or greater, // -o will take care of everything, // so just return unless we are annotating if (GET_SERVERLEVEL() >= 10 && !m_Annotating) return; ASSERT(lstrlen(data) == length); CString temp; StrBuf sptr; Error e; if(length > 0) { // TODO: handle error CString line; m_ByteCount+= length; if (m_Annotating) { line = data; line.TrimRight(); line += _T("\r\n"); data = line.GetBuffer(); length = lstrlen(data); } sptr.Set(const_cast<char*>((const char*)CharFromCString(data))); m_pOutputFile->Write( &sptr, &e); if(e.Test()) return; } if(length == 4096) { // Update the status text //::PostMessage(m_ReplyWnd, WM_P4STATUS, P4_PREPBROWSE, (LPARAM) m_KByteCount()); } if(length == 0) { // Clear the status box //::PostMessage(m_pP4->GetReplyWnd(), WM_P4STATUS, 0, 0); if(m_ByteCount > 9999) temp.Format(_T("Retrieved %s, %ld KB"), CharToCString(m_pOutputFile->Name()), m_ByteCount/1024); else temp.Format(_T("Retrieved %s, %ld bytes"), CharToCString(m_pOutputFile->Name()), m_ByteCount); TheApp()->StatusAdd(temp); // Dont delete the file before the viewer can see it! m_pOutputFile->ClearDeleteOnClose(); m_pOutputFile->Close(&e); } } // Internal function to set up args for printing a depot file to a temp file // Used by View() and Diff2() BOOL CCmd_PrepBrowse::SetupPrint(LPCTSTR fileSpec, CString &fileType, long fileRev, BOOL bForce2Binary) { // Get the file suffix as "filename.ext" CString FileName(fileSpec); CString Symbol=_T(""); int i; if ((i = FileName.Find(_T('@'))) != -1) { Symbol = FileName.Mid(i+1); FileName = FileName.Left(i); int len = Symbol.GetLength(); for (i=-1; ++i < len; ) { TCHAR c = Symbol.GetAt(i); if (!_istalpha(c) && !_istalnum(c)) Symbol.SetAt(i, _T('_')); } } else if (fileRev == 0x80000000) Symbol = _T("Head-Rev"); int begName=0; for(i = FileName.GetLength()-1; i>0; i--) { if(FileName[i]==_T('/') || FileName[i]==_T('\\')) { begName=i+1; break; } } ASSERT(i); if(i==0) { m_ErrorTxt.Format(_T("Invalid filespec:\n %s"), FileName); TheApp()->StatusAdd(m_ErrorTxt, SV_ERROR); m_FatalError=TRUE; return FALSE; } FileName=FileName.Mid(begName); // Check the file type int fType; int plus; if ((fileType.Find(_T("text")) != -1) && !bForce2Binary) { if ((plus = fileType.Find(_T("+"))) != -1) { if (fileType.Find(_T("x"), plus) == -1) fType = FST_TEXT; else fType = FST_XTEXT; } else { if ((fileType == _T("text")) || (fileType == _T("ktext")) || (fileType == _T("ltext")) || (fileType == _T("ctext"))) fType = FST_TEXT; else if ((fileType == _T("xtext")) || (fileType == _T("kxtext")) || (fileType == _T("cxtext"))) fType = FST_XTEXT; else fType=FST_BINARY; } } else if ((fileType.Find(_T("unicode")) != -1) && !bForce2Binary) { if (fileType.Find(_T("x")) != -1) fType=FST_XUNICODE; else fType=FST_UNICODE; } else if ((fileType.Find(_T("utf16")) != -1) && !bForce2Binary) { fType=FST_UTF16; } else { if ((fileType.Find(_T("binary")) != -1) && (fileType.Find(_T("x")) != -1)) fType=FST_XBINARY; else if (fileType == _T("xtempobj")) fType=FST_XBINARY; else fType=FST_BINARY; } m_pOutputFile= FileSys::Create( (enum FileSysType) fType ); CString TempPath= GET_P4REGPTR()->GetTempDir(); Error e; static int ctr = 0; for(i=ctr; ++i != ctr; ) { if (i >= 100) { i = 0; if (i == ctr) break; } e.Clear(); if (Symbol.IsEmpty()) m_TempName.Format(_T("%s\\ReadOnly-%d-Rev-%d-%s"), TempPath, i, fileRev, FileName); else m_TempName.Format(_T("%s\\ReadOnly-%d-%s-%s"), TempPath, i, Symbol, FileName); int j; while ((j = m_TempName.Find(':', 2)) != -1) m_TempName.SetAt(j, '_'); while ((j = m_TempName.FindOneOf(_T("/*?\"<>|"))) != -1) m_TempName.SetAt(j, '_'); m_pOutputFile->Set(CharFromCString(m_TempName)); if( !e.Test() ) // Prepare write (makes dir as required) m_pOutputFile->MkDir( &e ); if( !e.Test() ) { // Open it m_pOutputFile->Perms( m_Annotating && m_bP4a ? FPM_RW : FPM_RO ); m_pOutputFile->Open( FOM_WRITE, &e ); } if(!e.Test()) break; } ctr = i; if(e.Test()) { m_ErrorTxt.Format(_T("Error opening temporary file:\n %s"), m_TempName); TheApp()->StatusAdd(m_ErrorTxt, SV_ERROR); m_FatalError=TRUE; delete m_pOutputFile; m_pOutputFile=NULL; return FALSE; } // 2000.2 server will use print -o, // so we no longer need the file now that we know it can be created // (unless we are annotating) if (GET_SERVERLEVEL() >= 10 && !m_Annotating) m_pOutputFile->Close(&e); return TRUE; } void CCmd_PrepBrowse::OnOutputInfo(char level, LPCTSTR data, LPCTSTR msg) { if (m_Annotating && (CString(data)).Find(_T(" change")) > 0) { if (m_bP4a) OnOutputText(data, lstrlen(data)); else TheApp()->StatusAdd(msg); } else { if(APP_ABORTING() && m_Asynchronous) { ReleaseServerLock(); ExitThread(0); } TheApp()->StatusAdd(msg, SV_WARNING); } } BOOL CCmd_PrepBrowse::HandledCmdSpecificError(LPCTSTR errBuf, LPCTSTR errMsg ) { if ( StrStr(errBuf, _T(" - no file(s) at that revision")) || StrStr(errBuf, _T(" - no such file(s)")) ) m_NoFileAtRev = TRUE ; return ( FALSE ); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 11099 | brkarpala | Integrate p4win from //guest/perforce_software/p4win/...@8562 | ||
//guest/perforce_software/p4win/gui/p4api/Cmd_PrepBrowse.cpp | |||||
#1 | 8562 | Matt Attaway |
These feet never stop running. Initial commit of the P4Win source code. To the best of our knowledge this compiles and runs using the 2013.3 P4 API and VS 2010. Expect a few changes as we refine the build process. Please post any build issues to the forums. |