// // Copyright 2001 Perforce Software. All rights reserved. // // This file is part of Perforce - the FAST SCM System. // // p4wCmdPane: // Generates a result pane containing the result of a simple // command or a spec -i command. #include <p4wp4.h> #include "p4wStrBuf.h" #include "p4wHtml.h" #include "p4wMenuPane.h" #include "p4wPane.h" #include "p4wCmdPane.h" p4wCmdPane::p4wCmdPane( p4wView & ParentView, p4wRequest & Request, const char *title ) : p4wPane( ParentView, Request ), fSeenBegin(0), fFunctionCount(0), fSkipEnd(0), fReplaceField(0) { fTitle.Set( title ); fFirstErrorOnly = 0; } // // Special constructor used only if we intend to replace a // field in a form p4wCmdPane::p4wCmdPane( p4wView & ParentView, p4wRequest & Request, const char *title, const char *field, const char *val ) : p4wPane( ParentView, Request ), fSeenBegin(0), fFunctionCount(0), fSkipEnd(0), fReplaceField(1) { fTitle.Set( title ); fFirstErrorOnly = 0; fField.Set( field ); fVal.Set( val ); } p4wCmdPane::~p4wCmdPane() { } void p4wCmdPane::Begin() { p4wHtml htm; p4wURL urlMaker; StrBuf title; // // Only process ::Begin() at the beginning of the function list. if( fSeenBegin ) return; // // Construct the title doTitle( title ); // // Begin the pane. fSeenBegin = 1; // // Draw the contents header htm.comment( "BEGIN STATUS PANE" ); if (fRequest.fSave4Later) { StrBuf clearIcon; urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); htm.beginTRow(); htm.beginCol(); htm.icon( clearIcon.Text(), "10", "1", "", 1 ); htm.endCol(); htm.endTRow(); htm.beginTRow(); htm.beginCol(); htm.beginTable(); htm.beginCol(); htm.icon( clearIcon.Text(), "1", "10", "", 1 ); htm.endCol(); } else { // // Used to generate a line underneath the title StrBuf grayIcon; urlMaker.ConstructURL( grayIcon, "/grayPixelIcon", AC_ICON, NULL ); htm.beginTRow(); htm.beginCol(); htm.beginSpan( "title" ); htm << title; htm.endSpan(); htm.endCol(); htm.endTRow(); htm.beginTRow(); htm.beginCol( "top" ); htm.icon( grayIcon.Text(), "1", "100%", "", 1, "0", "0" ); htm.endCol(); htm.endTRow(); fRequest << htm; htm.Clear(); // // Generate a linkified path for some commands doDirHeader(); htm.beginTRow(); } htm.beginCol(); const StrPtr *mu = fRequest.GetDynArg("mu"); const StrPtr *lac = fRequest.GetDynArg( "lac" ); if (mu || fRequest.GetLastReturnType() == AC_BROWSEFILE) { int show = mu ? atoi(mu->Text()) : -1; htm.SetRequest(&fRequest); htm.RenderFileMenu(show ? show : -1); htm << "<script language=javascript>" << crlf; htm << "setmushow("; htm << show; htm << ");" << crlf; htm << "</script>" << crlf; } else if (fRequest.GetCmd() == AC_CHANGECMD || (lac && lac->Atoi() == AC_SYNCCHANGE)) { fRequest << htm; htm.Clear(); p4wMenuPane::renderSubChgMenu( &fRequest, NULL ); } htm.beginDList(); htm.dListTag(); htm.text( "Command:", "b" ); htm.dListVal(); htm.text( p4wStrBuf().EscapeHTML( fTitle, Unicode() ).Text() ); htm.dListTag(); htm.text( "Result:", "b" ); fRequest << htm; } void p4wCmdPane::RenderInfo( char *data, char level ) { char *p; char *q; p4wHtml htm(1); htm.dListVal(); StrBuf line; if (fRequest.GetCmd() == AC_CHANGEORSUBMITCMD) { p4wURL urlMaker; StrBuf url; StrBuf baseWPath; StrBufDict args; p = strstr(data, " created with "); if (p && !strncmp(data, "Change ", sizeof("Change ")-1)) { q = data + sizeof("Change ")-1; *p++ = '\0'; htm << "Change "; fRequest.UseNewBase( baseWPath, NULL, "path", fRequest.GetPath().Text() ); args.SetVar( "arg", q ); urlMaker.ConstructURL( url, baseWPath.Text(), AC_CHANGEPENDINGEDIT, &args, fRequest.GetUnicode() ); htm.beginLink( url.Text() ); htm << q; htm.endLink(); htm << " " << p; line << htm; htm.Clear(); } else { p = strstr(data, " - must resolve "); if (p && *data == '/' && *(data+1) == '/') { *p = '\0'; fRequest.UseNewBase( baseWPath, NULL, "path", data ); urlMaker.ConstructURL( url, baseWPath.Text(), AC_BROWSEFILE, NULL, fRequest.GetUnicode() ); htm.beginLink( url.Text() ); htm << data; htm.endLink(); htm << " - must "; urlMaker.ConstructURL( url, baseWPath.Text(), AC_RESOLVEFILEFRM, NULL, fRequest.GetUnicode() ); htm.beginLink( url.Text() ); htm << "resolve"; htm.endLink(); p += sizeof(" - must resolve ")-2; htm << p; line << htm; htm.Clear(); } else line << p4wStrBuf().EscapeHTML( StrRef(data), Unicode() ).Text(); } } else line << p4wStrBuf().EscapeHTML( StrRef(data), Unicode() ).Text(); int lgth; if ((lgth = fLastLine.Length()) && !strncmp( line.Text(), fLastLine.Text(), lgth )) { StrBuf temp; temp.Set("... "); temp << line; line.Set(temp); } htm.text( line.Text() ); if (*(line.Text()) == '/' && (p = strchr( line.Text(), '#' ))) { *p = '\0'; line.SetLength(); fLastLine.Set(line); fLastLine << " "; } fRequest << htm; if (fRequest.GetCmd() == AC_ADDPROCESSOR) { p = strstr(data, " - opened for add"); if (p) { p = strchr(data, '#'); if (p) { *p = '\0'; fAddedFilename.Set(data); } else fAddedFilename.Clear(); } else { p = strstr(data, " - missing, assuming "); if (p) { p4wURL urlMaker; StrBuf url; StrBuf baseWPath; *p = '\0'; p += sizeof(" - missing, assuming ")-1; htm.Clear(); htm.linebreak(); q = p + strlen(p); while (!isalpha(*--q)) *q = '\0'; htm << "If <b>" << p << "</b> is not the correct file type, you must "; if (fRequest.GetViewMode() == VM_WORKSPACE) fAddedFilename.Set(data); if (fAddedFilename.Length()) { fRequest.UseNewBase( baseWPath, NULL, "path", fAddedFilename.Text() ); urlMaker.ConstructURL( url, baseWPath.Text(), AC_FILETYPEFILEFRM, NULL, fRequest.GetUnicode() ); htm.beginLink( url.Text() ); } htm << "change the file type"; if (fAddedFilename.Length()) htm.endLink(); htm << "."; if (!fRequest.isLocalRequest() && fAddedFilename.Length()) { htm.linebreak(); htm << "If the file type is correct, you can now "; urlMaker.ConstructURL( url, baseWPath.Text(), AC_UPLOADTOLOCAL, NULL, fRequest.GetUnicode() ); htm.beginLink( url.Text() ); htm << "upload the file"; htm.endLink(); htm << "."; } fRequest << htm; } } } } void p4wCmdPane::RenderError( char *data, int escapeHTML ) { RenderErrorList( data, escapeHTML ); } void p4wCmdPane::End() { // // Only process ::End() after we have seen all of the functions. // Or if we had a fatal error if( fSkipEnd ) { fSkipEnd = 0; if( !fHadFatalError ) return; } if( !fHadFatalError && fFunctionCount && --fFunctionCount ) return; p4wHtml htm; htm.endDList(); htm.endCol(); htm.endTRow(); htm.comment( "END STATUS PANE" ); fRequest << htm; } void p4wCmdPane::InputData( StrBuf * strbuf, Error * e ) { // // Call parent class InputData, and do additional // form processing as needed. p4wPane::InputData( strbuf, e ); // // Some specs may need a field replaced, (ie label // create spec may use a new view). if( fReplaceField ) { StrBuf f; f << "\n" << fField << ":"; char *e = strstr( strbuf->Text(), f.Text() ); StrBuf *r = new StrBuf(); if( e ) r->Set( strbuf->Text(), e - strbuf->Text() ); else r->Set( strbuf->Text() ); *r << f << "\n\t" << fVal.Text() << "\n"; *strbuf = *r; delete r; } } // // HandleError() - Override default error handler so that we can replace // specific p4 error messages with more friendly errors. void p4wCmdPane::HandleError( Error *e ) { // // Replace labelsync's "empty string" error with a more // specific error message. static char *const lSyncErr = "You did not specify which files to labelsync.<BR>Please go back to the form and correct your entries under the 'Files' heading."; if( fRequest.GetCmd() == AC_LABSYNCPROCESSOR && e->GetSeverity() == E_FAILED && e->GetGeneric() == EV_USAGE ) { StrBuf errMsg; e->Fmt( &errMsg ); if( strstr( errMsg.Text(), "empty string is not allowed" ) ) { if( !fSeenBegin ) Begin(); RenderError( lSyncErr, 0 ); return; } } // // Handle all other errors using the default p4 error messages DoHandleError( e, 0 ); } // // CmdPane-specification functions. void p4wCmdPane::AdditionalFunction() { fFunctionCount++; } void p4wCmdPane::doDirHeader() { // // Generate a linkified path for status pages underneath // the Files tab AllCommands lac = fRequest.GetLastReturnType(); StrBuf path; path.Set( fRequest.GetReturnURL( lac ).Text() ); int isFileBrowser = lac != AC_PATHBROWSER; int isDepot = fRequest.GetViewMode() != VM_WORKSPACE; p4wHtml htm; StrBuf clearIcon; p4wURL urlMaker; urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); // // Integrate using branch, sync to changelist and sync to label // do not display the path. Jump through some hoops to see // if this is one of the commands to exclude. AllCommands ac = fRequest.GetCmd(); const StrPtr *lc = fRequest.GetDynArg( "lac" ); const StrPtr *bv = fRequest.GetDynArg( "bv" ); if( lc ) ac = (AllCommands) lc->Atoi(); if( bv ) ac = AC_INTEGRATEBRANCH; switch( ac ) { case AC_SYNCCMD: case AC_SYNCREV: case AC_SYNCFILE: case AC_SYNCPROCESSOR: case AC_REMOVEFRM: case AC_REMOVEFILEFRM: case AC_EDITPROCESSOR: case AC_EDITFILE: case AC_ADDFILE: case AC_DELETEPROCESSOR: case AC_DELETEFILE: case AC_ADDPROCESSOR: case AC_REVERTPROCESSOR: case AC_REVERTCMD: case AC_REVERTUNCHANGEDFILEFRM: case AC_REVERTFILE: case AC_FTYPEPROCESSOR: case AC_INTEGPROCESSOR: case AC_RESOLVEPROCESSOR: case AC_RESOLVEIAPROCESSOR: case AC_RESOLVECMD: case AC_LOCKPROCESSOR: case AC_LOCKFILEFRM: case AC_LOCKCMD: case AC_LOCKFILE: case AC_UNLOCKPROCESSOR: case AC_UNLOCKFILEFRM: case AC_UNLOCKCMD: case AC_UNLOCKFILE: htm.beginTRow(); htm.beginCol(); htm.beginSpan( "path" ); htm << " "; fRequest << htm; htm.Clear(); (void)OutputDirectoryHeader( path.Text(), isFileBrowser, 1, isDepot ); htm.endSpan(); htm.endCol(); htm.endTRow(); htm.beginTRow(); htm.beginCol(); htm.icon( clearIcon.Text(), "10", "0", "", 1 ); htm.endCol(); htm.endTRow(); fRequest << htm; break; default: break; } } void p4wCmdPane::doTitle( StrBuf &title ) { // // Generate a title for the page. Usually this involves // getting the default page title, and appending // "Status:" to that string. There are some // exceptions based on command, hence this method. StrBuf cmd; const StrPtr *lac = fRequest.GetDynArg( "lac" ); const StrPtr *bv = fRequest.GetDynArg( "bv" ); int ac = 0; if( lac ) ac = (AllCommands) lac->Atoi(); // // Get the default title associated with this command cmd.Set( p4wMenuPane::GetMenuTitle( fRequest.GetCmd() ) ); // // Preview commands are labeled "Preview <Operation>:. Otherwise // the generate format is <Operation> Status: if( fView.IsPreviewCmd() ) title << "Preview "; if( fRequest.GetCmd() == AC_SYNCPROCESSOR && lac ) { if( ac == AC_SYNCCHANGE ) title << "Sync to Changelist"; else if( ac == AC_SYNCLABEL ) title << "Sync Workspace to Label"; else if( ac == AC_REMOVEFRM || ac == AC_REMOVEFILEFRM ) title << "Remove from Workspace"; else title << "Sync"; } else if( fRequest.GetCmd() == AC_BRANCHCMD ) { if( fRequest.GetURL().Length() ) title << "Edit Branch"; else title << "Create Branch"; } else if( fRequest.GetCmd() == AC_LABELCMD ) { if( fRequest.GetURL().Length() ) title << "Edit Label"; else if( lac && ac == AC_CREATELABELTMP ) title << "Use Label as Template"; else title << "Create Label"; } else if( fRequest.GetCmd() == AC_INTEGPROCESSOR && bv ) { title << "Integrate Using Branch"; } else { title << cmd; } if( fView.IsPreviewCmd() ) title << ":"; else title << " Status:"; }
# | 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/Panes/p4wCmdPane.cpp | |||||
#1 | 8914 | Matt Attaway | Initial add of the P4Web source code |