// Copyright 2000 (c) by Perforce Software, Inc. All rights reserved. // // p4wRunView: // A p4wView for the 'run' button. Basically, utility methods for // handling the posted form full of data. // ------------------------------------- // Includes // #include <stdio.h> #include <string.h> #include <p4wp4.h> #include "p4wStrBuf.h" #include "p4wHtml.h" #include "p4wMenuPane.h" #include "p4wRunView.h" // ------------------------------------- // Constructors and destructor. // p4wRunView::p4wRunView(p4wRequest & Request) : p4wView(Request), fRedisplay(0), fProtectP4Chars(0), fAddJobFix(0) { // Note this is the union of all types used. spec.Add("atVal"); spec.Add("changelistVal"); spec.Add("atChangeVal"); spec.Add("dirVal"); spec.Add("File")->type = SDT_LLIST; spec.Add("Files"); spec.Add("filetypeVal"); spec.Add("Option"); spec.Add("OptionChg"); spec.Add("OptionFt"); spec.Add("OptionUnch"); spec.Add("OptionSync"); spec.Add("Path"); spec.Add("LocalPath"); spec.Add("revVal"); spec.Add("CheckOption"); spec.Add("Change"); spec.Add("ByPath"); // // The following are only used for the // change filetype dialog which is used // on the open for edit, open for add, // and change filetype pages if( fRequest.GetCmd() != AC_FTYPEPROCESSOR && fRequest.GetCmd() != AC_EDITPROCESSOR && fRequest.GetCmd() != AC_ADDPROCESSOR ) return; spec.Add( "basicType" ); spec.Add( "fileRevs" ); spec.Add( "mmod" ); spec.Add( "wmod" ); spec.Add( "xmod" ); spec.Add( "kmod" ); spec.Add( "komod" ); spec.Add( "lmod" ); spec.Add( "Smod" ); } p4wRunView::~p4wRunView() { } void p4wRunView::ArgAndTitle(const StrRef &a) { fRequest.p4Arg(a); title << a << " "; } int p4wRunView::ProcessForm() { return fRequest.ProcessForm(spec, &specTable); } // // mbishop (8/30/00): // // I wanted a function that would process the form and give me the // file string that I needed to attach to the end of a P4 command. // AddFileArgs() was so tightly integrated (as everything seems to // be grrrr...) with rendering a page // StrBuf p4wRunView::GetFileArg() { // Process the files StrPtr *atchoice = specTable.GetVar("atVal"); StrPtr *changelistval = specTable.GetVar("changelistVal"); StrPtr *dirchoice = specTable.GetVar("dirVal"); StrPtr *filechoice = specTable.GetVar("Files"); StrPtr *option = specTable.GetVar("Option"); StrPtr *path = specTable.GetVar("Path"); StrPtr *localPath = specTable.GetVar("LocalPath"); StrPtr *revchoice = specTable.GetVar("revVal"); // The rev suffix for all files StrBuf optionsSuffix; StrBuf result; if( !option ) { // not set } else if( *option == "rev" ) { if( revchoice && ( *revchoice->Text() == '#' ) ) optionsSuffix << revchoice; else optionsSuffix << "#" << revchoice; } else if( *option == "at" ) { if( atchoice && ( *atchoice->Text() == '@' ) ) optionsSuffix << atchoice; else optionsSuffix << "@" << atchoice; } else if( *option == "have" ) { optionsSuffix << "#have"; } // Now the files, according to the file choice. if ( filechoice == NULL || *filechoice == "selected" ) { int j; StrPtr *file; StrRef fileVar( "File" ); for( j = 0; file = specTable.GetVar( fileVar, j ); j++ ) { if ( j ) result << " "; result << *file << optionsSuffix; } } else if ( *filechoice == "entered" && localPath ) { int j; int nAdded = 0; StrPtr *file; StrRef fileVar( "File" ); for( j = 0; file = specTable.GetVar( fileVar, j ); j++ ) { // Handle the blank lines we // get during adds. XXX. if( file->Length() ) { result << localPath << *file; } } } else if ( *filechoice == "all" ) { if( ( fRequest.GetCmd() == AC_REVERTPROCESSOR ) || ( fRequest.GetCmd() == AC_RESOLVEPROCESSOR ) ) { result.Set( "//..." ); result << optionsSuffix; } else if( optionsSuffix.Length() ) { result << optionsSuffix; } } else if ( *filechoice == "changelist" ) { result << "-c"; result << *changelistval; } else if ( *filechoice == "in" ) { result.Set( path ); if( *dirchoice == "and subdirectories" ) { result << "..."; } else { result << "*"; } result << optionsSuffix; } return result; } int p4wRunView::AddFileArgs() { // Process the files StrPtr *atchoice = specTable.GetVar("atVal"); StrPtr *changeVal = specTable.GetVar("atChangeVal"); StrPtr *changelistval = specTable.GetVar("changelistVal"); StrPtr *restrict = specTable.GetVar("OptionSync"); StrPtr *dirchoice = specTable.GetVar("dirVal"); StrPtr *filechoice = specTable.GetVar("Files"); StrPtr *option = specTable.GetVar("Option"); StrPtr *path = specTable.GetVar("Path"); StrPtr *localPath = specTable.GetVar("LocalPath"); StrPtr *revchoice = specTable.GetVar("revVal"); // The revision or at suffix with label/changelist/date/revision StrBuf optionsSuffix; if( !option ) { // not set } else if( *option == "rev" ) { if( revchoice && ( *revchoice->Text() == '#' ) ) optionsSuffix << revchoice; else optionsSuffix << "#" << revchoice; } else if( *option == "at" ) { if( atchoice && ( *atchoice->Text() == '@' ) ) optionsSuffix << atchoice; else optionsSuffix << "@" << atchoice; } else if( *option == "atChange" ) { if( changeVal && ( *changeVal->Text() == '@' ) ) optionsSuffix << changeVal; else optionsSuffix << "@" << changeVal; // // Ignore the restrict checkbox value if the // user typed in a range for the changelist value if( restrict && *restrict == "restricted" ) { if( changeVal && strchr( changeVal->Text(), ',' ) ) ; else optionsSuffix << "," << changeVal; } } else if( *option == "have" ) { optionsSuffix << "#have"; } else if( *option == "head" ) { optionsSuffix << "#head"; } // Now the files, according to the file choice. if( filechoice == NULL || *filechoice == "selected" ) { int j; int ff = 0; StrPtr *file; StrRef fileVar( "File" ); for( j = 0; file = specTable.GetVar(fileVar,j); j++ ) { argBuf.Clear(); // Strip leading and trailing blanks from the // file args of the labelsync form // just in case the values were cut & pasted // into the text box with whitespace. if( fRequest.GetCmd() == AC_LABSYNCPROCESSOR ) argBuf << p4wStrBuf().StripBlanks( *file ); else argBuf << *file; if( !argBuf.Length() ) continue; ++ff; argBuf << optionsSuffix; fRequest.p4Arg( argBuf ); // // Now build up the title if ( j ) title << " "; if( fRequest.GetCmd() == AC_LABSYNCPROCESSOR ) title << p4wStrBuf().StripBlanks( *file ); else title << *file; title << optionsSuffix; } // Return with error if no files were selected in the Selcct // Files case. Labelsync has a more specific error // message. static char *const lSyncErr = "You did not specify which files to labelsync. Please go back to the form and correct your entries under the 'Files' heading."; if( filechoice && !ff && fRequest.GetCmd() == AC_LABSYNCPROCESSOR ) { RenderError( lSyncErr ); return 0; } else if( filechoice && !ff ) { RenderError("Error: No files were selected."); return 0; } } else if( *filechoice == "entered" && localPath ) { int j; int nAdded = 0; StrPtr *file; StrRef fileVar( "File" ); for( j = 0; file = specTable.GetVar(fileVar,j); j++ ) { // Handle the blank lines we // get during adds. XXX. if( file->Length() ) { argBuf.Clear(); argBuf << localPath << *file; // // If server allows special characters in filenames // we must escape them for fstat since this file // is in local syntax if( fProtectP4Chars ) fRequest.p4Arg( p4wStrBuf().EscapeP4Chars( argBuf ) ); else fRequest.p4Arg( argBuf ); ++nAdded; } } title << "<i>entered files</i>"; // Return with error if no files were selected if( nAdded == 0 ) { RenderError("Error: No files were selected."); return 0; } } else if( *filechoice == "all" ) { if( ( fRequest.GetCmd() == AC_REVERTPROCESSOR ) || ( fRequest.GetCmd() == AC_RESOLVEPROCESSOR ) ) { argBuf.Set( "//..." ); argBuf << optionsSuffix; ArgAndTitle( argBuf ); } else if( optionsSuffix.Length() ) { ArgAndTitle( optionsSuffix ); } } else if( *filechoice == "changelist" ) { ArgAndTitle( "-c" ); ArgAndTitle( *changelistval ); } else if( *filechoice == "in" ) { argBuf.Set( path ); if( *dirchoice == "and subdirectories" ) { argBuf << "..."; } else { argBuf << "*"; } argBuf << optionsSuffix; ArgAndTitle( argBuf ); } else if( *filechoice == "inAdd" ) { int recurse; StrRef dir; dir.Set( localPath->Text() ); if( *dirchoice == "and subdirectories" ) recurse = 1; else recurse = 0; if( !GetDirList( dir, recurse ) ) { StrBuf errMsg; errMsg << "Error: no files available to add in " << localPath; RenderError( errMsg.Text() ); return 0; } } return 1; } int p4wRunView::GetDirList(StrPtr &dir, int recurse) { // // Add the list of files in this directory to // the argument list. If recurse is set, traverse // directories too. Error e; FileSys *f = FileSys::Create( FST_TEXT ); int nFiles = 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); // Reuse f now for each directory entry PathSys *p = PathSys::Create(); for( int i = 0; i < files->Count(); i++ ) { p->SetLocal( dir, *files->Get(i) ); f->Set( *p ); int statResult = f->Stat(); if( statResult & FSF_DIRECTORY ) { if( recurse ) nFiles += GetDirList( *p, recurse ); } else { if ( !(statResult & FSF_HIDDEN) ) { // // If server allows special characters // in filenames, we must escape them // for fstat (since this is local format) if( fProtectP4Chars ) ArgAndTitle( p4wStrBuf().EscapeP4Chars( StrRef(f->Name()) ) ); else ArgAndTitle( f->Name() ); ++nFiles; } } } delete files; delete f; delete p; return nFiles; } void p4wRunView::RenderMenu() { // // Draw the menu bar p4wMenuPane menuPane(*this, fRequest, "result"); menuPane.Render(NULL); } void p4wRunView::RenderError(char *data) { p4wHtml htm; // // Span the error over several columns htm.beginTRow(); htm.beginCol( NULL, NULL, "6", NULL, NULL, NULL, NULL, 1 ); htm.text( p4wStrBuf().EscapeHTML(StrRef(data), fRequest.GetUnicode()).Text(), NULL, NULL, "red" ); htm.endCol(); htm.endTRow(); fRequest << htm; } void p4wRunView::Render() { // // Either parse the form and issue the command, or // just redisplay the page with files checked/unchecked if( fAddJobFix ) { AddJobFix(); } else if( !fRedisplay ) { p4wView::Render(); } else { RedisplayForm(); } } void p4wRunView::AddJobFix() { StrBuf url; StrBufDict args; StrBuf location; p4wURL urlMaker; if( !ProcessForm() ) { RenderError("Requested URL is invalid in this context."); return; } StrPtr *change = specTable.GetVar("Change"); args.SetVar( "pcl", change ); args.SetVar( "mx", "25" ); urlMaker.ConstructLocationURL( url, NULL, fAc, &args, fRequest.GetUnicode() ); location << p4wStrBuf().NormalizeBase( fRequest.GetBase(), fRequest.GetUnicode() ); location << url; fRequest.DoLocation( location.Text() ); } void p4wRunView::RedisplayForm() { // // Send a LOCATION directive to redisplay the form // using files unchecked or files checked option as necessary StrBuf url; StrBufDict args; StrBuf location; p4wURL urlMaker; if( !ProcessForm() ) { RenderError("Requested URL is invalid in this context."); return; } StrPtr *uch = specTable.GetVar("CheckOption"); StrPtr *change = specTable.GetVar("Change"); StrPtr *bp = specTable.GetVar("ByPath"); const StrPtr *sr = fRequest.GetDynArg( "sr" ); // // Insure uch is set whenever the redisplay button // was pushed. The value determines whether files // will be checked or unchecked. if( uch && *uch == "unchecked" ) args.SetVar( "uch", "1" ); else args.SetVar( "uch", "0" ); if( bp && *bp == "checked" ) args.SetVar( "bp", "1" ); if( change && *change != "new" ) args.SetVar( "arg", change->Text() ); if( sr ) args.SetVar( "sr", sr->Text() ); urlMaker.ConstructLocationURL( url, NULL, fAc, &args, fRequest.GetUnicode() ); // // If we are in workspace mode, construct a new BASE // for the url because some browsers corrupt the base path // if it contains anything but forward slashes. if( fRequest.GetViewMode() == VM_WORKSPACE ) { StrBuf nb; fRequest.UseNewBase( nb, NULL, "path", fRequest.GetPath().Text() ); location << p4wStrBuf().NormalizeBase( nb, fRequest.GetUnicode() ); } else { location << p4wStrBuf().NormalizeBase( fRequest.GetBase(), fRequest.GetUnicode() ); } location << url; fRequest.DoLocation( location.Text() ); } void p4wRunView::ProcessFormAction() { // // Set flags based on the formAction chosen from form Spec spec; StrBufDict actionTable; SpecElem * se = spec.Add("formActions"); se->type = SDT_LLIST; if( !fRequest.ProcessForm(spec, &actionTable) ) { return; } // // Determine which action was chosen StrPtr * chosenAction = NULL; StrPtr * action = NULL; for( int curAction = 0; (action = actionTable.GetVar(StrRef("formActions"), curAction)) != NULL; curAction++ ) { // See if this action is the one that was selected. Spec actionItemSpec; StrBufDict actionItemTable; actionItemSpec.Add(*action); (void)fRequest.ProcessForm(actionItemSpec, &actionItemTable); chosenAction = actionItemTable.GetVar(action->Text()); if( chosenAction != NULL ) { chosenAction = action; break; } } if( *chosenAction == "redisplay" ) fRedisplay = 1; else if( *chosenAction == "preview" ) fPreview = 1; } void p4wRunView::GetFileType( StrBuf &fileType ) { // // Parse the form's radio buttons, checkboxes and // text box and construct a filetype argument // for open for add, edit or change filetype const StrPtr *basicType = specTable.GetVar( "basicType" ); const StrPtr *fileRevs = specTable.GetVar( "fileRevs" ); const StrPtr *mmod = specTable.GetVar( "mmod" ); const StrPtr *wmod = specTable.GetVar( "wmod" ); const StrPtr *xmod = specTable.GetVar( "xmod" ); const StrPtr *kmod = specTable.GetVar( "kmod" ); const StrPtr *komod = specTable.GetVar( "komod" ); const StrPtr *lmod = specTable.GetVar( "lmod" ); const StrPtr *Smod = specTable.GetVar( "Smod" ); const StrPtr *NbrRevs = specTable.GetVar( "NbrRevs" ); fileType.Set( basicType ); if( fileRevs && *fileRevs != "def" ) fileType << fileRevs; else if( mmod || wmod || xmod || kmod || komod || lmod || Smod ) fileType << "+"; if( mmod ) fileType << mmod; if( wmod ) fileType << wmod; if( xmod ) fileType << xmod; if( kmod && !komod ) fileType << kmod; if( komod ) fileType << komod; if( lmod ) fileType << lmod; if( Smod ) { fileType << Smod; if (NbrRevs) fileType << NbrRevs; } }
# | 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/p4wRunView.cpp | |||||
#1 | 8914 | Matt Attaway | Initial add of the P4Web source code |