// // Copyright 2000 Perforce Software. All rights reserved. // // This file is part of Perforce - the FAST SCM System. // // p4wPathBrowserView: // Issues p4 command for generating the Path Browser (using p4wFilePane) // ------------------------------------- // Includes // #include <stdlib.h> #include <string.h> #include <p4wp4.h> #include "p4wStrBuf.h" #include "p4wView.h" #include "p4wPathBrowserView.h" #include "p4wInfoPane.h" #include "p4wPasswdTestPane.h" #include "changeshelper.h" #include "p4wUpdatePane.h" #include "p4wMenuPane.h" #include "p4wDepotPane.h" #include "p4wDiff2FilesPane.h" // // ------------------------------------- // Constructors and destructor. // p4wPathBrowserView::p4wPathBrowserView(p4wRequest & Request, AllCommands command) : p4wView(Request) { const StrPtr *pb = fRequest.GetStateArg( "pb" ); fIsFromFileBrowser = 0; fRequest.ReplaceBase( "cd", fRequest.GetDepotPath().Text() ); if( fRequest.GetStateArg( "cdf" ) ) { fRequest.ReplaceBase( "cdf", NULL ); } if( command == AC_CLIENT ) { fRequest.ReplaceBase( "md", "c" ); } else if( command == AC_DEPOT ) { fRequest.ReplaceBase( "md", "d" ); } if( command == AC_CLIENT || command == AC_DEPOT ) { fRequest.ReplaceBase( "wr", NULL ); } // // Set the short and the long versions of the title fShortTitle.Set( "Files" ); fFullTitle.Set( strcmp(fRequest.GetPath().Text(), "//") ? fRequest.GetPath().Text() : "Files" ); if( pb ) fCommand = (AllCommands)atoi( pb->Text() ); else fCommand = command; } p4wPathBrowserView::~p4wPathBrowserView() { } // ------------------------------------- // Render this view. // int p4wPathBrowserView::RenderUpdateOK() { // // Create and send the update pane containing last five changes StrBuf path; path = fRequest.GetPath().Text(); if ( !fIsFromFileBrowser ) { path << "..."; } if( !fRequest.HideRecentChanges() ) { p4wUpdatePane updatePane(*this, fRequest, path); updatePane.DrawPane(); } return 1; } void p4wPathBrowserView::RenderContent() { if (fRequest.GetCmd() == AC_DIFF2DIRS) { p4wDiff2FilesPane diff2PaneFiles( *this, fRequest ); diff2PaneFiles.Begin(); diff2PaneFiles.RenderContent(); diff2PaneFiles.End(); return; } StrBuf path; StrBuf path2; int checkedFirstCommand = 0; int bFilesFound = 1; const StrPtr *srev = fRequest.GetDynArg( "sr" ); const StrPtr *srevState = fRequest.GetStateArg( "sr" ); const StrPtr *pattern = fRequest.GetStateArg( "pat" ); const StrPtr *subfolders = fRequest.GetStateArg( "is" ); AllCommands ac; // // Create and send the file pane. p4wFilePane filePane(*this, fRequest, fCommand); // If both dynamic and state variables for sr are set, dynamic // is used. Set srev to the value to be used. Dynamic sr is // used for ala mode browsing. if( !srev && srevState ) srev = srevState; // // Issue command to get the directories. Usually this is a dirs command, // with the following notable exceptions: // 1) We are at the root directory in CLIENT or DEPOT mode. In this // case we issue the depots command instead. If we're in client // mode, also issue the where command to find out which depots // are not mapped to our client. // 2) We are in workspace mode. In this case we will peruse our local // directory using pathsys and filesys commands instead. path.Clear(); path << fRequest.GetPath() << "*"; if( srev ) path << "@" << srev; if( fRequest.GetPath() != "//" || ( fRequest.GetViewMode() == VM_WORKSPACE ) ) { if (!fRequest.HideDetails()) { p4wDepotPane depotPane(*this, fRequest); fRequest.p4("depots", 0, 0, &depotPane); fRequest.p4Wait(); if( !depotPane.FatalError() && depotPane.RemoteList.Count() ) { const StrPtr *depot; int id = -1; while( depot = depotPane.RemoteList.Get( ++id ) ) { StrBuf *newRmt = filePane.RemoteList.Put(); *newRmt << depot; } } } } if( fRequest.GetPath() == "//" && ( fRequest.GetViewMode() != VM_WORKSPACE ) ) { fRequest.p4("depots", 0, 0, &filePane); fRequest.p4Wait(); if( filePane.FatalError() ) return; ++checkedFirstCommand; if( fRequest.GetViewMode() == VM_CLIENT ) { int id = -1; const StrPtr *d; StrBuf wherePath; while( d = filePane.DepotList.Get( ++id ) ) { wherePath.Set("//"); wherePath << d << "..."; fRequest.p4Arg( wherePath.Text() ); } if( filePane.DepotList.Count() ) { fRequest.p4("where", 0, 0, &filePane); fRequest.p4Wait(); } } } else if( fRequest.GetViewMode() == VM_DEPOT ) { if( !fRequest.HideDeletedFiles() ) fRequest.p4Arg("-D"); fRequest.p4Arg(path.Text()); } else if( fRequest.GetViewMode() == VM_WORKSPACE ) { (void)sendWSFiles( &filePane, 0 ); if( filePane.FatalError() ) return; } else { fRequest.p4Arg("-C"); if( !fRequest.HideDeletedFiles() ) fRequest.p4Arg("-D"); fRequest.p4Arg(path.Text()); } if( fRequest.GetPath() != "//" && ( fRequest.GetViewMode() != VM_WORKSPACE ) ) { fRequest.p4("dirs", 0, 0, &filePane); if( !checkedFirstCommand) { fRequest.p4Wait(); if( filePane.FatalError() ) return; } } // // If we are in browse-only mode, only FILESMATCHING and OPENEDFILESALL // are available. if( fRequest.GetBrowseMode() && fCommand != AC_FILESMATCHING && fCommand != AC_OPENEDFILESALL && fCommand != AC_PATHBROWSER && fCommand != AC_DEPOT && fCommand != AC_CLIENT ) { fRequest.p4Wait(); return; } // // Issue the specified command. In some instances run the output // through fstat (ie unsynced, unresolved, etc) // // Presence of a pattern state argument implies we need to // match the pattern if( !pattern ) ac = fCommand; else ac = AC_FILESMATCHING; switch( ac ) { case AC_UNSYNCED: { path.Clear(); path << fRequest.GetPath() << "..."; if( srev ) path << "@" << srev; const char *syncArgs[] = { "-n", path.Text() }; fRequest.p4("sync", 2, syncArgs, &filePane); fRequest.p4Wait(); filePane.SetfState(p4wFilePane::gettingOpened); fstatFileList(&filePane, fRequest.GetViewMode() != VM_DEPOT); if( !filePane.FileList.Get(0) ) bFilesFound = 0; } break; case AC_UNRESOLVED: { path.Clear(); path << fRequest.GetPath() << "..."; const StrPtr *server = fRequest.GetProtocol( "server2" ); // // If server supports it, use fstat -Ru instead of // resolve -n, followed by fstats of each file found if( server && server->Atoi() > 17 ) { if ( !fRequest.HideDetails() && server && server->Atoi() > 18 ) // 2005.1 or later fRequest.p4Arg( "-Ol" ); fRequest.p4Arg( "-Ru" ); if( fRequest.GetViewMode() != AC_DEPOT ) fRequest.p4Arg( "-C" ); fRequest.p4Arg( path.Text() ); fRequest.p4( "fstat", 0, 0, &filePane ); fRequest.p4Wait(); } else { const char *resolveArgs[] = { "-n", path.Text() }; fRequest.p4("resolve", 2, resolveArgs, &filePane); fRequest.p4Wait(); fstatFileList(&filePane, fRequest.GetViewMode() != VM_DEPOT); if( !filePane.FileList.Get(0) ) bFilesFound = 0; } } break; case AC_MISSING: { path.Clear(); path << fRequest.GetPath() << "..."; if( srev ) path << "@" << srev; const char *diffArgs[] = { "-sd", path.Text() }; fRequest.p4("diff", 2, diffArgs, &filePane); fRequest.p4Wait(); fstatFileList(&filePane, fRequest.GetViewMode() != VM_DEPOT); if( !filePane.FileList.Get(0) ) bFilesFound = 0; } break; case AC_OPENEDUNCHANGED: { path.Clear(); path << fRequest.GetPath() << "..."; if( srev ) path << "@" << srev; const char *diffArgs[] = { "-sr", path.Text() }; fRequest.p4("diff", 2, diffArgs, &filePane); fRequest.p4Wait(); fstatFileList(&filePane, fRequest.GetViewMode() != VM_DEPOT ); } break; case AC_CHANGESUNOPENED: { path.Clear(); path << fRequest.GetPath() << "..."; if( srev ) path << "@" << srev; const char *diffArgs[] = { "-se", path.Text() }; fRequest.p4("diff", 2, diffArgs, &filePane); fRequest.p4Wait(); fstatFileList(&filePane, fRequest.GetViewMode() != VM_DEPOT ); if( !filePane.FileList.Get(0) ) bFilesFound = 0; } break; case AC_FILESMATCHING: { if( !pattern || *pattern == "" ) { RenderError("No file matching pattern was entered."); return; } path.Clear(); path << fRequest.GetPath(); if ( !strncmp( pattern->Text(), "...", 3 ) ) path << "*" << pattern->Text() + 3; else path << pattern; if( srev ) path << "@" << srev; if ( !fRequest.HideDetails() ) { const StrPtr *server = fRequest.GetProtocol( "server2" ); if ( server && server->Atoi() > 18 ) // 2005.1 or later fRequest.p4Arg( "-Ol" ); } if( fRequest.GetViewMode() == VM_CLIENT ) fRequest.p4Arg( "-C" ); fRequest.p4Arg( path.Text() ); if( subfolders ) { path2 << fRequest.GetPath() << ".../"; path2 << pattern; if( srev ) path2 << "@" << srev; fRequest.p4Arg( path2.Text() ); } fRequest.p4("fstat", 0, 0, &filePane); fRequest.p4Wait(); } break; case AC_OPENEDFILESALL: { path.Clear(); path << fRequest.GetPath() << "..."; const char *openedArgs[] = { "-a", path.Text() }; fRequest.p4("opened", 2, openedArgs, &filePane); fRequest.p4Wait(); fstatFileList(&filePane, 0); if( !filePane.FileList.Get(0) ) bFilesFound = 0; } break; case AC_PATHBROWSER: case AC_CLIENT: case AC_DEPOT: default: { // // If Hide Opened Files is in // effect, don't show opened files // in the path browser. if( !fRequest.HideOpenedFiles() && !fRequest.GetBrowseMode() ) { // // fstat to get opened files in directories. int nargs = 0; path.Clear(); path << fRequest.GetPath() << "*/..."; if( srev ) path << "@" << srev; const char *filePaneOpenedArgs[] = { NULL, NULL, NULL, NULL }; if ( !fRequest.HideDetails() ) { const StrPtr *server = fRequest.GetProtocol( "server2" ); if ( server && server->Atoi() > 18 ) // 2005.1 or later filePaneOpenedArgs[nargs++] = "-Ol"; } if( fRequest.GetViewMode() == VM_DEPOT ) { filePaneOpenedArgs[nargs++] = "-W"; filePaneOpenedArgs[nargs++] = path.Text(); } else { filePaneOpenedArgs[nargs++] = "-C"; filePaneOpenedArgs[nargs++] = "-W"; filePaneOpenedArgs[nargs++] = path.Text(); } fRequest.p4("fstat", nargs, filePaneOpenedArgs, &filePane); fRequest.p4Wait(); } // // fstat on the files just in this directory path.Clear(); path << fRequest.GetPath() << "*"; if( srev ) path << "@" << srev; if( fRequest.GetViewMode() == VM_WORKSPACE ) { (void) sendWSFiles( &filePane, 1 ); } else if( strncmp( path.Text(), "//*", 3 ) ) { if ( !fRequest.HideDetails() ) { const StrPtr *server = fRequest.GetProtocol( "server2" ); if ( server && server->Atoi() > 18 ) // 2005.1 or later fRequest.p4Arg( "-Ol" ); } if( fRequest.GetViewMode() == VM_DEPOT ) fRequest.p4Arg( path.Text() ); else { fRequest.p4Arg( "-C" ); fRequest.p4Arg( path.Text() ); } fRequest.p4( "fstat", 0, 0, &filePane ); fRequest.p4Wait(); } } break; } // // if theumbnails were requested, get them now if ( !fRequest.HideThumbnails() && bFilesFound ) { const StrPtr *server; int protocol = 0; server = fRequest.GetProtocol( "server2" ); if( server ) protocol = server->Atoi(); if( protocol > 19 && strcmp("//*", path.Text()) ) { fRequest.p4Wait(); int lgth = path.Length(); if( lgth > 3 && !strcmp(path.Text()+lgth-3, "...")) { strcpy(path.Text()+lgth-3, "*"); path.SetLength(); } if( fRequest.GetViewMode() != VM_DEPOT ) fRequest.p4Arg( "-C" ); fRequest.p4Arg( "-Oaeh" ); fRequest.p4Arg( "-A" ); fRequest.p4Arg( "thumb" ); fRequest.p4Arg( path.Text() ); if (subfolders && ac == AC_FILESMATCHING) fRequest.p4Arg( path2.Text() ); fRequest.p4( "fstat", 0, 0, &filePane ); fRequest.p4Wait(); } } // // // // Wait for all of the panes to draw. // fRequest.p4Wait(); // // Make sure we ended the filePane page filePane.End(); } void p4wPathBrowserView::RenderMenu() { // // Draw the full menu bar. p4wMenuPane menuPane(*this, fRequest, "pathbrowser"); menuPane.Render(NULL); } void p4wPathBrowserView::fstatFileList(p4wFilePane *filePane, int useClientView) { // // Get the list of files needing sync and fstat them if( !filePane->FileList.Get(0) ) return; if ( !fRequest.HideDetails() ) { const StrPtr *server = fRequest.GetProtocol( "server2" ); if ( server && server->Atoi() > 18 ) // 2005.1 or later fRequest.p4Arg( "-Ol" ); } if( useClientView ) fRequest.p4Arg( "-C" ); for( int i = 0; filePane->FileList.Get(i); i++ ) fRequest.p4Arg( *filePane->FileList.Get(i) ); fRequest.p4( "fstat", 0, 0, filePane ); fRequest.p4Wait(); } int p4wPathBrowserView::sendWSFiles(p4wFilePane *filePane, int sendFiles) { // // Make sure the path we are talking about is under the client's root StrPtr *dir = (StrPtr *)&fRequest.GetPath(); if (strncmp(dir->Text(), fRequest.GetClientRoot().Text(), strlen(fRequest.GetClientRoot().Text()))) { filePane->SetfState(p4wFilePane::hasFatalError); return 0; } // // Traverse the workspace tree to send files or directories to the pane. // If sendFiles is set, send fstat for all files in current path. // Otherwise send a list of the directories to the filePane. Error e; FileSys *f = FileSys::Create( FST_TEXT ); int nSent = 0; f->Set( dir->Text() ); StrArray *files = f->ScanDir( &e ); // Even if the directory doesn't exist, we want to // show the path so we can navigate. // Clear the error and if we got a strarray back, // great. If not, just make an empty one. // e.Clear(); if ( !files ) files = new StrArray(); files->Sort(0); PathSys *p = PathSys::Create(); int ps = 0; StrArray fileArgs; for( int i = 0; i < files->Count(); i++ ) { p->SetLocal( *dir, *files->Get(i) ); f->Set( *p ); if( sendFiles ) { if( !( f->Stat() & FSF_DIRECTORY ) ) { if( !nSent ) { Error e; StrBuf errorMsg; fRequest.p4Init( &e ); if( e.Test() ) { e.Fmt( &errorMsg ); filePane->RenderError( errorMsg.Text(), 1 ); return 0; } // // Check whether server allows // protected chars in filenames. If // so, we'll have to escape them // prior to issuing fstat. const StrPtr *server = fRequest.GetProtocol( "server2" ); if (!server) { p4wPasswdTestPane d( *this, fRequest ); fRequest.p4( "info", 0, 0, &d ); fRequest.p4Wait(); server = fRequest.GetProtocol( "server2" ); } if( server && server->Atoi() > 17 ) ++ps; if ( !fRequest.HideDetails() ) { const StrPtr *server = fRequest.GetProtocol( "server2" ); if ( server && server->Atoi() > 18 ) // 2005.1 or later fRequest.p4Arg( "-Ol" ); } fRequest.p4Arg( "-C" ); ++nSent; } if( ps ) { fRequest.p4Arg( p4wStrBuf().EscapeP4Chars( StrRef(f->Name()) ) ); fP4CharsProtected = 1; if ( !fRequest.HideThumbnails() ) fileArgs.Put()->Set( p4wStrBuf().EscapeP4Chars( StrRef(f->Name()) ) ); } else { fRequest.p4Arg( f->Name() ); if ( !fRequest.HideThumbnails() ) fileArgs.Put()->Set( f->Name() ); } } } else { if( f->Stat() & FSF_DIRECTORY ) { ++nSent; StrBufDict dirs; dirs.SetVar( "dir", f->Name() ); filePane->Render( &dirs ); } } } delete files; delete f; delete p; if( sendFiles && nSent ) { fRequest.p4( "fstat", 0, 0, filePane); if ( !fRequest.HideThumbnails() ) { const StrPtr *server; int protocol = 0; server = fRequest.GetProtocol( "server2" ); if( server ) protocol = server->Atoi(); if( protocol > 19 ) { fRequest.p4Wait(); fRequest.p4Arg( "-Oae" ); fRequest.p4Arg( "-A" ); fRequest.p4Arg( "thumb" ); for( int j = 0; j < fileArgs.Count(); j++ ) fRequest.p4Arg( *fileArgs.Get( j ) ); fRequest.p4( "fstat", 0, 0, filePane ); fRequest.p4Wait(); } } } else { if( sendFiles ) filePane->Begin(); filePane->End(); } return nSent; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 12234 | Matt Attaway |
Rejigger P4Web project in preparation for official sunsetting The bin directory contains the last official builds of P4Web from the Perforce download site. P4Web is soon to be completely sunsetted; these builds are here for folks who don't want to build their own. To better handle the archived builds the source code has been moved into a separate src directory. |
||
//guest/perforce_software/p4web/Views/p4wPathBrowserView.cpp | |||||
#1 | 8914 | Matt Attaway | Initial add of the P4Web source code |