// // Copyright 2000 Perforce Software. All rights reserved. // // This file is part of Perforce - the FAST SCM System. // // p4wMenuPane: // Generates the menu bar and icons #include <p4wp4.h> #include "p4wAllCommands.h" #include "p4wStrBuf.h" #include "p4wHtml.h" #include "p4wJs.h" #include "p4wPane.h" #include "p4wMenuPane.h" #include "p4wPasswdTestPane.h" // // Unset the server cancel flag if we're displaying the // cancel page because the cancel wasn't meant to apply // to this page, but only to the command that preceded it. extern int globalCancel; // // Options for the Files tab for a directory static char *const fileDirText[] = { "Display tree view", "Diff two folders...", "Sync to head revisions", "Sync...", "Remove from workspace...", "Open for edit...", "Open for add...", "Open for delete...", "Revert unchanged files", "Revert...", "Integrate...", "Resolve...", "Change filetype...", "Lock...", "Unlock..." }; static char *const fileDirHead[] = { "Depot Tree", "Diff Two Folders", "Sync to Head Revisions", "Sync", "Remove from Workspace", "Open for Edit", "Open for Add", "Open for Delete", "Revert Unchanged Files", "Revert", "Integrate", "Resolve", "Change Filetype", "Lock", "Unlock" }; static AllCommands fileDirVal[] = { AC_PATHBROWSER, AC_DIFF2DIRS, AC_SYNCCMD, AC_SYNCFRM, AC_REMOVEFRM, AC_EDITFRM, AC_ADDFRM, AC_DELETEFRM, AC_REVERTCMD, AC_REVERTFRM, AC_INTEGRATEFRM, AC_RESOLVEFRM, AC_FILETYPEFRM, AC_LOCKFRM, AC_UNLOCKFRM }; // // Options for the Files tab for a file static char *const fileFileText[] = { "Revision history", "Open head revision in browser", "Sync...", "Remove from workspace", "Open for edit...", "Open for add...", "Open for delete...", "Revert unchanged", "Revert...", "View workspace file text", "View head revision text", "View annotated file text", "Diff synced rev vs. workspace file", "Diff synced rev vs. head rev", "Diff head rev vs. workspace file", "Diff two depot files...", "Edit workspace file in default editor", "Edit workspace file in P4Web", "Integrate...", "Resolve...", "Change filetype...", "Lock", "Unlock", "Download file from workspace", "Upload file to workspace", }; static char *const fileFileHead[] = { "Revision History", "Open Head Revision in Browser", "Sync", "Remove from Workspace", "Open for Edit", "Open for Add", "Open for Delete", "Revert Unchanged", "Revert", "View Workspace File Text", "View File Revision Text", "View Annotated File Text", "Diff Synced Revision vs. Workspace File", "Diff Synced Revision vs. Head Revision", "Diff Head Revision vs. Workspace File", "Diff Two Depot Files", "Open Workspace File in Editor", "Edit Workspace File", "Integrate", "Resolve", "Change Filetype", "Lock", "Unlock", "Download File from Workspace", "Upload File to Workspace", }; static AllCommands fileFileVal[] = { AC_BROWSEFILE, AC_MIMECONTENT, AC_SYNCFILEFRM, AC_REMOVEFILEFRM, AC_EDITFILEFRM, AC_ADDFILEFRM, AC_DELETEFILEFRM, AC_REVERTUNCHANGEDFILEFRM, AC_REVERTCONFIRM, AC_FILETEXTLOCAL, AC_FILETEXTDEPOT, AC_ANNOTATE, AC_DIFFWVC, AC_DIFFCVH, AC_DIFFWVH, AC_DIFF2FILES, AC_LAUNCHEDITOR, AC_EDITTEXTLOCAL, AC_INTEGRATEFILEFRM, AC_RESOLVEFILEFRM, AC_FILETYPEFILEFRM, AC_LOCKFILEFRM, AC_UNLOCKFILEFRM, AC_DOWNLOADTOLOCAL, AC_UPLOADTOLOCAL, }; // // Options for the submitted changelist subnavigation menu static char *const changeSubOptsText[] = { "View submitted changelists", "View changelist", "Edit changelist...", "Add job to changelist...", "Sync to changelist...", }; static char *const changeSubOptsHead[] = { "View Submitted Changelists", "View Changelist", "Edit Changelist", "Add Job to Changelist", "Sync to Changelist", }; static AllCommands changeSubVal[] = { AC_SUBMITTEDCHANGELISTS, AC_DESCRIBE, AC_EDITCHANGE, AC_GETJOB, AC_SYNCCHANGE, }; // // Options for the branch subnavigation menu static char *const branchSubOptsText[] = { "View branches", "Create branch spec...", "View branch spec", "Edit branch spec...", "Delete branch spec", "Integrate using branch spec...", "Compare branched files" }; static char *const branchSubOptsHead[] = { "View Branches", "Create Branch Spec", "View Branch Spec", "Edit Branch Spec", "Delete Branch Spec", "Integrate Using Branch Spec", "Compare Branched Files" }; static AllCommands branchSubVal[] = { AC_BRANCHES, AC_CREATEBRANCH, AC_BRANCHVIEW, AC_EDITBRANCH, AC_DELETEBRANCHCONFIRM, AC_INTEGRATEBRANCH, AC_BRANCHDIFF }; // // Options for the label subnavigation menu static char *const labelSubOptsText[] = { "View labels", "Create label spec...", "View label spec", "Edit label spec...", "Delete label spec", "Use label as template...", "View files in label", "View files in label as text", "Add/Replace files...", "Sync workspace to label...", }; static char *const labelSubOptsHead[] = { "View Labels", "Create Label Spec", "View Label Spec", "Edit Label Spec", "Delete Label Spec", "Use Label as Template", "View Files in Label", "View Files in Label as Text", "Add/Replace Files", "Sync Workspace to Label", }; static AllCommands labelSubVal[] = { AC_LABELS, AC_CREATELABEL, AC_LABELVIEW, AC_EDITLABEL, AC_DELETELABELCONFIRM, AC_CREATELABELTMP, AC_LABELFILES, AC_LABELFILESTEXT, AC_REPLACELABEL, AC_SYNCLABEL, }; // // Options for the job subnavigation menu static char *const jobSubOptsText[] = { "View jobs", "Create job...", "View job", "Edit job...", "Delete job", "Add job to a pending changelist...", "Add job to a submitted changelist...", "View fixes for job", "View field descriptions" }; static char *const jobSubOptsHead[] = { "View Jobs", "Create Job", "View Job", "Edit Job", "Delete Job", "Add Job to a Pending Changelist", "Add Job to a Submitted Changelist", "View Fixes for Job", "View Field Descriptions" }; static AllCommands jobSubVal[] = { AC_JOBS, AC_CREATEJOB, AC_JOBVIEW, AC_EDITJOB, AC_DELETEJOBCONFIRM, AC_FIXPENDING, AC_FIXSUBMITTED, AC_FIXESJOB, AC_JOBFIELDS }; // // Options for the clients subnavigation menu static char *const clientsSubOptsText[] = { "Edit current client...", "Choose client...", }; static char *const clientsSubOptsHead[] = { "Edit Current Client", "Choose Client", }; static AllCommands clientsSubVal[] = { AC_EDITCLIENT, AC_MULTIUSER, }; // // Options for the client context menu static char *const clientSubOptsText[] = { "View client", "Edit client...", "Switch to Client", }; static char *const clientSubOptsHead[] = { "View Client", "Edit Client", "Switch to Client", }; static AllCommands clientSubVal[] = { AC_CLIENTVIEW, AC_EDITCLIENT, AC_CLIENTSWITCH, }; // // Options not in menus that may still need a title // associated with them, such as tabs static char *const miscOptsText[] = { "Submitted changelists", "Submitted changelists", "Pending changelists", "Settings", "File state", "View labels", "Diff - ", "Diff - ", "Diff - ", "Create label", "Run P4 Command", "Choose client", "View annotated file text", "View annotated file text", "View annotated file text", "Hide listview columns", "Fix submitted changelist", "Diff two folders", }; static char *const miscOptsHead[] = { "Submitted Changelists", "Submitted Changelists", "Pending Changelists", "Settings", "File State", "View Labels", "Diff ", "Diff ", "Diff ", "Create Label", "Run P4 Command", "Choose Client", "View Annotated File Text", "View Annotated File Text", "View Annotated File Text", "Hide Listview Columns", "Fix Submitted Changelist", "Diff Two Folders", }; static AllCommands miscVal[] = { AC_SUBMITTEDCHANGELISTS, AC_SUBMITTEDCHANGELISTSFILE, AC_PENDINGCHANGELISTS, AC_CONFIGURATION, AC_FILESTATE, AC_LABELSPATH, AC_DIFF2, AC_DIFF21, AC_DIFF22, AC_CREATELABEL, AC_P4CMDPANE, AC_MULTIUSER, AC_FULLANNOTATE, AC_CHGLISTANNOTATE, AC_CHGLISTFULLANNOTATE, AC_SHOWHIDECOLUMNS, AC_FIXSUBMITTED, AC_DIFF2DIRSOUTPUT, }; p4wMenuPane::p4wMenuPane( p4wView & ParentView, p4wRequest & Request, char *help ) : p4wPane( ParentView, Request ) { fHelpText.Set( help ); } p4wMenuPane::~p4wMenuPane() { } void p4wMenuPane::Render( StrDict * varList ) { // // Begin the pane. fRequest << "<!-- BEGIN MENU BAR PANE -->" << crlf; AllCommands ac; p4wJs js; // // Output a javascript method to allow users to select // from a select box without hitting a button // and a method to auto select a radio button js.beginJs( "1.2" ); js.goSelected(); js.setCheckedValue(); js.endJs(); fRequest << js; // // For some commands, like cancel, we should use the // previous command as the basis for generating the // highlighted tab and the subnavigation menus. If the // dynamic argument "lac" is set, use it. Cancel ALWAYS // must use lac: if it is unset, we will highlight no tab. const StrPtr *lac = fRequest.GetDynArg( "lac" ); const StrPtr *bv = fRequest.GetDynArg( "bv" ); if( fRequest.GetCmd() == AC_CANCELCMD ) { if( lac ) ac = (AllCommands) lac->Atoi(); else ac = (AllCommands) 0; } else if( lac ) { ac = (AllCommands) lac->Atoi(); } else if( bv ) { ac = AC_INTEGRATEBRANCH; } else { ac = fRequest.GetCmd(); } // // Generate the tabs and subnavigation menu if (fRequest.GetScreenChunks() & SCRN_TABS) doTabs( ac ); doSubNav( ac ); // // End the pane fRequest << "<!-- END MENU BAR PANE -->" << crlf; } void p4wMenuPane::GetAction( StrBuf & actionURL ) { // // Constructs url used for the form ACTION value StrBuf path; StrBuf fixedPath; // // Determine the path part of the action. // // Help and cancel links need to have the return path // instead of the current path. if( fRequest.GetCmd() == AC_HELP || fRequest.GetCmd() == AC_ABOUT || fRequest.GetCmd() == AC_CANCELCMD ) { AllCommands lac = fRequest.GetLastReturnType(); fRequest.UseNewBase( path, NULL, "path", fRequest.GetReturnURL( lac ).Text() ); // // Sync to change or label needs to get the change or // label in the url instead of the path } else if( fRequest.GetCmd() == AC_SYNCCHANGE || fRequest.GetCmd() == AC_SYNCLABEL ) { const StrPtr *sr = fRequest.GetDynArg( "sr" );; fRequest.UseNewBase( path, NULL, "path", "//" ); if (sr) path << sr; // // Integrate using branch needs to get the branch name // in the label instead of the path } else if( fRequest.GetCmd() == AC_INTEGRATEBRANCH ) { const StrPtr *bv = fRequest.GetDynArg( "bv" ); fRequest.UseNewBase( path, NULL, "path", "//" ); if (bv) path << bv; // // Workspace mode requires entire path in the action // in order to work around browser bugs with the base // directive when used with a local syntax. Also, if // the "path" entity has a leading '/', we'll need to // use the absolute path so that the resulting url won't // be truncated. } else if( fRequest.GetViewMode() == VM_WORKSPACE || ( fRequest.GetURL().Length() && *fRequest.GetURL().Text() == '/' ) ) { fRequest.UseNewBase( path, NULL, "path", fRequest.GetPath().Text() ); // // Default is to use the current path } else { path << fRequest.GetURL(); } // // Filter out trailing ... if present char *e = strstr( path.Text(), "..." ); if( e ) fixedPath.Set( path.Text(), e - path.Text() ); else fixedPath.Set( path.Text() ); fRequest.ConstructSafeURL( actionURL, fixedPath.Text(), AC_MENUPROCESSOR, NULL ); } char * p4wMenuPane::GetMenuItem( AllCommands cmd, int browseOnly ) { // // Return the menu string corresponding to the cmd int i; for( i = 0; i < NFILEDIROPTS; i++ ) { if( fileDirVal[i] == cmd ) return fileDirText[i]; } for( i = 0; i < NFILEFILEOPTS; i++ ) { if( fileFileVal[i] == cmd ) return fileFileText[i]; } for( i = 0; i < NCHANGESUBOPTS; i++ ) { if( changeSubVal[i] == cmd ) return changeSubOptsText[i]; } for( i = 0; i < NBRANCHSUBOPTS; i++ ) { if( branchSubVal[i] == cmd ) return branchSubOptsText[i]; } for( i = 0; i < NLABELSUBOPTS; i++ ) { if( labelSubVal[i] == cmd ) return labelSubOptsText[i]; } for( i = 0; i < NJOBSUBOPTS; i++ ) { if( jobSubVal[i] == cmd ) return jobSubOptsText[i]; } for( i = 0; i < NMISCOPTS; i++ ) { if( miscVal[i] == cmd ) return miscOptsText[i]; } return "Unknown command"; } char * p4wMenuPane::GetMenuTitle( AllCommands cmd ) { // // Return the page title corresponding to the cmd int i; for( i = 0; i < NFILEDIROPTS; i++ ) { if( fileDirVal[i] == cmd ) return fileDirHead[i]; } for( i = 0; i < NFILEFILEOPTS; i++ ) { if( fileFileVal[i] == cmd ) return fileFileHead[i]; } for( i = 0; i < NCHANGESUBOPTS; i++ ) { if( changeSubVal[i] == cmd ) return changeSubOptsHead[i]; } for( i = 0; i < NBRANCHSUBOPTS; i++ ) { if( branchSubVal[i] == cmd ) return branchSubOptsHead[i]; } for( i = 0; i < NLABELSUBOPTS; i++ ) { if( labelSubVal[i] == cmd ) return labelSubOptsHead[i]; } for( i = 0; i < NJOBSUBOPTS; i++ ) { if( jobSubVal[i] == cmd ) return jobSubOptsHead[i]; } for( i = 0; i < NMISCOPTS; i++ ) { if( miscVal[i] == cmd ) return miscOptsHead[i]; } // // Return titles for pages that are not necessarily from // the menus switch( cmd ) { case AC_ADDFILE: case AC_ADDPROCESSOR: return "Open for Add"; break; case AC_DELETEPROCESSOR: case AC_DELETEFILE: return "Open for Delete"; break; case AC_DIFFRVW: return "Diff - Revision vs. Workspace File"; break; case AC_EDITPROCESSOR: case AC_EDITFILE: return "Open for Edit"; break; case AC_FTYPEPROCESSOR: return "Change File Type"; break; case AC_INTEGPROCESSOR: return "Integrate"; break; case AC_LABSYNCPROCESSOR: return "Add/Replace Files"; break; case AC_LOCKPROCESSOR: case AC_LOCKCMD: case AC_LOCKFILE: return "Lock"; break; case AC_RESOLVEPROCESSOR: return "Resolve"; break; case AC_RESOLVEIAPROCESSOR: return "Resolve Status"; break; case AC_REVERTPROCESSOR: case AC_REVERTCMD: case AC_REVERTFILE: case AC_REVERTFILEFRM: return "Revert"; break; case AC_SYNCPROCESSOR: case AC_SYNCFILE: case AC_SYNCCMD: case AC_SYNCREV: return "Sync"; break; case AC_SYNCCHANGERNG: return "Sync to Changelist"; break; case AC_UNLOCKPROCESSOR: case AC_UNLOCKCMD: case AC_UNLOCKFILE: return "Unlock"; break; case AC_CLIENTCMD: return "Edit Client"; break; case AC_USERCMD: return "Edit User"; break; case AC_CHANGECMD: return "Submitted Changelist"; break; case AC_CHANGEORSUBMITCMD: case AC_SUBMITFILEFRM: case AC_SUBMITFRM: return "Pending Changelist"; break; case AC_LABELCMD: return "Label"; break; case AC_BRANCHCMD: return "Branch"; break; case AC_DELETELABEL: return "Delete Label"; break; case AC_CREATELABEL: return "Create Label"; break; case AC_DELETEBRANCH: return "Delete Branch"; break; case AC_DELETEJOB: return "Delete Job"; break; case AC_LOGOUT: case AC_LOGOUT2: return "Logout"; break; default: break; } return "Unknown command"; } int p4wMenuPane::FromFileBrowser( AllCommands cmd ) { // // Return 1 only if cmd is verifiably from a file browser int cmdFromFileBrowser; switch(cmd) { case AC_SYNCFILEFRM: case AC_SUBMITFILEFRM: case AC_EDITFILEFRM: case AC_DELETEFILEFRM: case AC_FILETYPEFILEFRM: case AC_REMOVEFILEFRM: case AC_INTEGRATEFILEFRM: case AC_RESOLVEFILEFRM: case AC_LOCKFILEFRM: case AC_UNLOCKFILEFRM: case AC_REVERTUNCHANGEDFILEFRM: case AC_REVERTFILEFRM: case AC_FILETEXTDEPOT: case AC_MIMECONTENT: case AC_FILETEXTLOCAL: case AC_EDITTEXTLOCAL: case AC_EDITTEXTLOCALPROCESSOR: case AC_UPLOADTOLOCAL: case AC_UPLOADTOLOCALPROCESSOR: case AC_DOWNLOADTOLOCAL: case AC_DIFFWVC: case AC_DIFFCVH: case AC_DIFFWVH: case AC_DIFFRVW: case AC_DIFF2FILES: case AC_SUBMITTEDCHANGELISTSFILE: case AC_LAUNCHEDITOR: case AC_ADDFILEFRM: case AC_GENERALANNOTATE: case AC_ANNOTATE: case AC_FULLANNOTATE: case AC_CHGLISTANNOTATE: case AC_CHGLISTFULLANNOTATE: cmdFromFileBrowser = 1; break; default: cmdFromFileBrowser = 0; break; } return cmdFromFileBrowser; } TabType p4wMenuPane::getTab( AllCommands ac ) { // // Returns the current tab value based on the current // ac code // // This could be an error page: if so, set this to NOTAB if( fView.IsErrorPage() ) return TT_NOTAB; return p4wAllCommands::GetTab( ac ); } void p4wMenuPane::doTabs( AllCommands ac ) { // // Generate the row of tabs with the current tab highlighted. p4wHtml htm(1); p4wURL urlMaker; StrBuf icon; StrBuf url; StrBuf baseWPath; StrBuf baseNoPath; AllCommands lac = fRequest.GetLastReturnType(); TabType tab = getTab( ac ); StrBuf clearIcon; urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); char * iconSz = "25"; const StrPtr *X = fRequest.GetStateArg( "X" ); // undoc eXperimental flags if (X) { if (strchr(X->Text(), '3')) iconSz = "37"; else if (strchr(X->Text(), '4')) iconSz = "50"; else if (strchr(X->Text(), '6')) iconSz = "75"; else if (strchr(X->Text(), '8')) iconSz = "100"; } // // Construct base used to construct the url. Some links // require the path, and others have the path cleared out. fRequest.UseNewBase( baseWPath, NULL, "path", fRequest.GetReturnURL( lac ).Text() ); fRequest.UseNewBase( baseNoPath, NULL, "path", "//" ); // // Begin the table used to display the tabs htm.comment( "BEGIN TABS" ); htm.beginTable( "0", "100%", "0", "0" ); htm.beginTRow(); htm.beginCol(); htm.beginTable( "0", "100%", "0", "0" ); htm.beginTRow( NULL, NULL, "#C4C3C3" ); htm.beginCol(); htm.beginForm(); htm.endCol(); // // Generate the tabs. The current tab is highlighted and is not // a link // // The File tab if (strchr(fRequest.GetTabs().Text(), 'f') || tab == TT_FILE) { // // Determine the current path. if( lac == AC_PATHBROWSER ) urlMaker.ConstructURL( url, baseWPath.Text(), AC_PATHBROWSER, NULL, fRequest.GetUnicode() ); else urlMaker.ConstructURL( url, baseWPath.Text(), AC_BROWSEFILE, NULL, fRequest.GetUnicode() ); urlMaker.ConstructURL( icon, "/fileIcon", AC_ICON, NULL ); if( tab != TT_FILE ) htm.beginCol( NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, "tabs" ); else htm.beginCol( NULL, NULL, NULL, NULL, "#EEEEEE", NULL, NULL, 1, "actab" ); htm.beginLink( url.Text(), NULL, "tab" ); htm.icon( icon.Text(), iconSz, iconSz, "", 1, NULL, NULL, "absmiddle" ); if (!X || !strchr(X->Text(), 't')) htm << "Files"; htm.endLink(); if( fRequest.GetJavascriptMode() != 2 ) // not IE htm << " "; htm.endCol(); } // // The pending changelist tab. Don't show this tab if browse-only // mode, or back-in-time browsing. if( !fRequest.GetBrowseMode() && fRequest.GetBITBRev().Length() == 0 && strchr(fRequest.GetTabs().Text(), 'p')) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_PENDINGCHANGELISTS, NULL, fRequest.GetUnicode() ); urlMaker.ConstructURL( icon, "/pendingChangelistIcon", AC_ICON, NULL ); if( tab != TT_PENDING ) htm.beginCol( NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, "tabs" ); else htm.beginCol( NULL, NULL, NULL, NULL, "#EEEEEE", NULL, NULL, 1, "actab" ); htm.beginLink( url.Text(), NULL, "tab" ); htm.icon( icon.Text(), iconSz, iconSz, "", 1, NULL, NULL, "absmiddle" ); if (!X || !strchr(X->Text(), 't')) htm << "Pending"; htm.endLink(); if( fRequest.GetJavascriptMode() != 2 ) // not IE htm << " "; htm.endCol(); } // // The submitted changelist tab if (strchr(fRequest.GetTabs().Text(), 's') || tab == TT_SUBMITTED) { StrBufDict subArgs; subArgs.SetVar( "mx", "50" ); if( lac == AC_PATHBROWSER ) urlMaker.ConstructURL( url, baseWPath.Text(), AC_SUBMITTEDCHANGELISTS, &subArgs, fRequest.GetUnicode() ); else urlMaker.ConstructURL( url, baseWPath.Text(), AC_SUBMITTEDCHANGELISTSFILE, &subArgs, fRequest.GetUnicode() ); urlMaker.ConstructURL( icon, "/submittedChangelistIcon", AC_ICON, NULL ); if( tab != TT_SUBMITTED ) htm.beginCol( NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, "tabs" ); else htm.beginCol( NULL, NULL, NULL, NULL, "#EEEEEE", NULL, NULL, 1, "actab" ); htm.beginLink( url.Text(), NULL, "tab" ); htm.icon( icon.Text(), iconSz, iconSz, "", 1, NULL, NULL, "absmiddle" ); if (!X || !strchr(X->Text(), 't')) htm << "Submitted"; htm.endLink(); if( fRequest.GetJavascriptMode() != 2 ) // not IE htm << " "; htm.endCol(); } // // The branch tab if (strchr(fRequest.GetTabs().Text(), 'b') || tab == TT_BRANCH) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_BRANCHES, NULL, fRequest.GetUnicode() ); urlMaker.ConstructURL( icon, "/branchesIcon", AC_ICON, NULL ); if( tab != TT_BRANCH ) htm.beginCol( NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, "tabs" ); else htm.beginCol( NULL, NULL, NULL, NULL, "#EEEEEE", NULL, NULL, 1, "actab" ); htm.beginLink( url.Text(), NULL, "tab" ); htm.icon( icon.Text(), iconSz, iconSz, "", 1, NULL, NULL, "absmiddle" ); if (!X || !strchr(X->Text(), 't')) htm << "Branches"; htm.endLink(); if( fRequest.GetJavascriptMode() != 2 ) // not IE htm << " "; htm.endCol(); } // // The Label tab if (strchr(fRequest.GetTabs().Text(), 'l') || tab == TT_LABEL) { urlMaker.ConstructURL( url, baseWPath.Text(), AC_LABELS, NULL, fRequest.GetUnicode() ); urlMaker.ConstructURL( icon, "/labelIcon", AC_ICON, NULL ); if( tab != TT_LABEL ) htm.beginCol( NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, "tabs" ); else htm.beginCol( NULL, NULL, NULL, NULL, "#EEEEEE", NULL, NULL, 1, "actab" ); htm.beginLink( url.Text(), NULL, "tab" ); htm.icon( icon.Text(), iconSz, iconSz, "", 1, NULL, NULL, "absmiddle" ); if (!X || !strchr(X->Text(), 't')) htm << "Labels"; htm.endLink(); if( fRequest.GetJavascriptMode() != 2 ) // not IE htm << " "; htm.endCol(); } // // The Client tab if (strchr(fRequest.GetTabs().Text(), 'c') || tab == TT_CLIENT) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_CLIENTS, NULL, fRequest.GetUnicode() ); urlMaker.ConstructURL( icon, "/clientIcon", AC_ICON, NULL ); if( tab != TT_CLIENT ) htm.beginCol( NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, "tabs" ); else htm.beginCol( NULL, NULL, NULL, NULL, "#EEEEEE", NULL, NULL, 1, "actab" ); htm.beginLink( url.Text(), NULL, "tab" ); htm.icon( icon.Text(), iconSz, iconSz, "", 1, NULL, NULL, "absmiddle" ); if (!X || !strchr(X->Text(), 't')) htm << "Clients"; htm.endLink(); if( fRequest.GetJavascriptMode() != 2 ) // not IE htm << " "; htm.endCol(); } // // The User tab if (strchr(fRequest.GetTabs().Text(), 'u') || tab == TT_USER) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_USERS, NULL, fRequest.GetUnicode() ); urlMaker.ConstructURL( icon, "/userIcon", AC_ICON, NULL ); if( tab != TT_USER ) htm.beginCol( NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, "tabs" ); else htm.beginCol( NULL, NULL, NULL, NULL, "#EEEEEE", NULL, NULL, 1, "actab" ); htm.beginLink( url.Text(), NULL, "tab" ); htm.icon( icon.Text(), iconSz, iconSz, "", 1, NULL, NULL, "absmiddle" ); if (!X || !strchr(X->Text(), 't')) htm << "Users"; htm.endLink(); if( fRequest.GetJavascriptMode() != 2 ) // not IE htm << " "; htm.endCol(); } // // The Job tab if (strchr(fRequest.GetTabs().Text(), 'j') || tab == TT_JOB) { StrBufDict jobArgs; jobArgs.SetVar( "mx", "25" ); urlMaker.ConstructURL( url, baseWPath.Text(), AC_JOBS, &jobArgs, fRequest.GetUnicode() ); urlMaker.ConstructURL( icon, "/jobIcon", AC_ICON, NULL ); if( tab != TT_JOB ) htm.beginCol( NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, "tabs" ); else htm.beginCol( NULL, NULL, NULL, NULL, "#EEEEEE", NULL, NULL, 1, "actab" ); htm.beginLink( url.Text(), NULL, "tab" ); htm.icon( icon.Text(), iconSz, iconSz, "", 1, NULL, NULL, "absmiddle" ); if (!X || !strchr(X->Text(), 't')) htm << "Jobs"; htm.endLink(); if( fRequest.GetJavascriptMode() != 2 ) // not IE htm << " "; htm.endCol(); } // // The Settings tab urlMaker.ConstructURL( url, baseNoPath.Text(), AC_CONFIGURATION, NULL, fRequest.GetUnicode() ); urlMaker.ConstructURL( icon, "/settingsIcon", AC_ICON, NULL ); if( tab != TT_SETTINGS ) htm.beginCol( NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, "tabs" ); else htm.beginCol( NULL, NULL, NULL, NULL, "#EEEEEE", NULL, NULL, 1, "actab" ); htm.beginLink( url.Text(), NULL, "tab" ); htm.icon( icon.Text(), iconSz, iconSz, "", 1, NULL, NULL, "absmiddle" ); if (!X || !strchr(X->Text(), 't')) htm << "Settings"; htm.endLink(); if( fRequest.GetJavascriptMode() != 2 ) // not IE htm << " "; htm.endCol(); int tabsspr = 0; if (!(fRequest.GetScreenChunks() & SCRN_TOOLBAR)) tabsspr = 1; int bt = (X && strchr(X->Text(), 't')) ? 1 : 0; // iPhone support: no text on tabs if( (!bt || fRequest.GetJavascriptMode() == 2) && !tabsspr ) // MSIE or no text & spr not req? htm.beginCol(); else { htm.beginCol(0,0,0,0,0,"100%",0,1, "tabsspr"); htm.icon( clearIcon.Text(), iconSz, "100%", "", 1 ); } htm.endForm(); htm.endCol(); htm.endTRow(); htm.endTable(); htm.endCol(); if( !bt || fRequest.GetJavascriptMode() == 2 ) // MSIE or no text? { htm.beginCol(0,0,0,0,0,"100%"); htm.beginTable(0, "100%", "0", "0"); htm.beginTRow(0,0, "#C4C3C3"); htm.beginCol(0,0,0,0,0,"100%",0,1, "tabsspr"); htm.icon( clearIcon.Text(), iconSz, "100%", "", 1 ); htm.endCol(); htm.endTRow(); htm.endTable(); htm.endCol(); } htm.endTRow(); htm.comment( "END TABS" ); fRequest << htm; } void p4wMenuPane::doSubNav( AllCommands ac ) { // // Issue a dummy request to the server in order // to test protocol level. if (!fRequest.GetP4Init()) { Error e; fRequest.p4Init( &e ); } if (fRequest.GetP4Init()) { p4wPasswdTestPane dummyCmd( fView, fRequest ); dummyCmd.SetTestClient(1); fRequest.p4( "info", 0, 0, &dummyCmd ); fRequest.p4Wait(); StrBuf cliroot; cliroot = dummyCmd.GetClientRoot(); fRequest.SetClientRoot( &cliroot ); fRequest.fUnknownClient = dummyCmd.IsUnknownClient(); } // // Generates the subnavigation pane p4wHtml htm; p4wHtml htmmenu; p4wURL urlMaker; StrBuf clearIcon; StrBuf grayIcon; StrBuf url; StrBuf helpBase; StrBuf recentBase; StrBuf rawCmdBase; StrBuf gotoBase; StrBuf helpUrl; StrBuf aboutUrl; StrBuf recentUrl; StrBuf rawCmdUrl; StrBuf gotoUrl; StrBuf baseWPath; StrBuf baseNoPath; StrBuf baseNonePath; StrBuf path; StrBuf locUrl; StrBuf icon; int selected; const StrPtr *server; int protocol = 0; server = fRequest.GetProtocol( "server2" ); if( server ) protocol = server->Atoi(); AllCommands lac = fRequest.GetLastReturnType(); TabType tab = getTab( ac ); int i; StrBuf actionURL; GetAction( actionURL ); int iconSz = 25; int bUseIcon = 0; const StrPtr *X = fRequest.GetStateArg( "X" ); // undoc eXperimental flags if (X) { if (strchr(X->Text(), '3')) iconSz = 37; else if (strchr(X->Text(), '4')) iconSz = 50; else if (strchr(X->Text(), '6')) iconSz = 75; else if (strchr(X->Text(), '8')) iconSz = 100; if (strchr(X->Text(), 't')) bUseIcon = 1; } // // Generate the help url fRequest.UseNewBaseDoCache( helpBase, NULL, "path", "/" ); helpBase << fHelpText; urlMaker.ConstructURL( helpUrl, helpBase.Text(), AC_HELP, NULL, fRequest.GetUnicode() ); // // Construct some frequently used icons urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); urlMaker.ConstructURL( grayIcon, "/grayPixelIcon", AC_ICON, NULL ); // // Construct commonly used bases used to construct urls. // Filter out a trailing ... if present char *e = strstr( fRequest.GetReturnURL( lac ).Text(), "/..." ); if( e ) { path.Set( fRequest.GetReturnURL( lac ).Text(), e - fRequest.GetReturnURL( lac ).Text() + 1 ); } else { path.Set( fRequest.GetReturnURL( lac ).Text() ); } fRequest.UseNewBase( baseWPath, NULL, "path", path.Text() ); fRequest.UseNewBase( baseNoPath, NULL, "path", "//" ); fRequest.UseNewBase( baseNonePath, NULL, "path", NULL ); // // Generate the about url urlMaker.ConstructURL( aboutUrl, baseNoPath.Text(), AC_ABOUT, NULL, fRequest.GetUnicode() ); // // Generate the toggle recent activity url if( fRequest.HideRecentChanges() ) fRequest.UseNewBase( recentBase, NULL, "ra", "s" ); else fRequest.UseNewBase( recentBase, NULL, "ra", NULL ); if( p4wAllCommands::NodeNotFile( ac ) ) fRequest.UseNewBase( recentBase, recentBase.Text(), "path", NULL ); recentUrl << recentBase << fRequest.GetURL() << fRequest.GetDynURL(); recentUrl.Set( p4wStrBuf().EscapeURL( recentUrl, fRequest.GetUnicode() ) ); // // Generate the toggle raw P4 commands url if( fRequest.HideRawP4Cmds() ) fRequest.UseNewBase( rawCmdBase, NULL, "rc", "s" ); else fRequest.UseNewBase( rawCmdBase, NULL, "rc", NULL ); if( p4wAllCommands::NodeNotFile( ac ) ) fRequest.UseNewBase( rawCmdBase, rawCmdBase.Text(), "path", NULL ); rawCmdUrl << rawCmdBase << fRequest.GetURL() << fRequest.GetDynURL(); rawCmdUrl.Set( p4wStrBuf().EscapeURL( rawCmdUrl, fRequest.GetUnicode() ) ); // // Generate the toggle goto url if( fRequest.HideGoTo() ) { StrBuf val; switch(getTab( ac )) { case TT_BRANCH: val << "b"; break; case TT_LABEL: val << "l"; break; case TT_CLIENT: val << "c"; break; case TT_USER: val << "u"; break; case TT_JOB: val << "j"; break; default: val << "s"; break; } fRequest.UseNewBase( gotoBase, NULL, "rg", val.Text() ); } else fRequest.UseNewBase( gotoBase, NULL, "rg", NULL ); if( p4wAllCommands::NodeNotFile( ac ) ) fRequest.UseNewBase( gotoBase, gotoBase.Text(), "path", NULL ); gotoUrl << gotoBase << fRequest.GetURL() << fRequest.GetDynURL(); gotoUrl.Set( p4wStrBuf().EscapeURL( gotoUrl, fRequest.GetUnicode() ) ); // // Begin the table used to display the tabs htm.comment( "BEGIN SUBNAVIGATION" ); htm.beginTRow( NULL, NULL, "#EEEEEE" ); htm.beginCol(); if (!(fRequest.GetScreenChunks() & SCRN_TABS) && !(fRequest.GetScreenChunks() & SCRN_HEADER)) htm.beginTable( "0", 0, "0", "0", "#EEEEEE" ); else htm.beginTable( "0", 0, "0", "0" ); htm.beginTRow(); const StrPtr *thx = fRequest.GetStateArg( "thx" ); int bGenMenu = 0; if (!thx) { switch(tab) { case TT_SUBMITTED: if (fRequest.GetBrowseMode()) break; case TT_FILE: case TT_BRANCH: case TT_LABEL: case TT_CLIENT: case TT_JOB: bGenMenu = 1; htmmenu.SetSepNeeded(1); break; default: break; } } if (!(fRequest.GetScreenChunks() & SCRN_TOOLBAR)) { if (tab == TT_FILE) htm.beginCol(); fRequest << htm; htm.Clear(); } else { htm.beginCol( NULL, NULL, NULL, NULL, NULL, "10" ); htm.icon( clearIcon.Text(), "30", "10", "", 1 ); htm.endCol(); if (bGenMenu && fRequest.GetBrowseMode() && ac == AC_PATHBROWSER) htm << "</noscript>" << crlf; } switch( tab ) { case TT_FILE: if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginCol(); htm.beginForm( actionURL.Text() ); htm.endCol(); if( bGenMenu ) htm << "</noscript>" << crlf; htm.beginCol( NULL, NULL, NULL, NULL, NULL, "1" ); if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginSelect( "viewValue", 1, 0, "go( this )" ); if( bGenMenu ) htm << "</noscript>" << crlf; if( lac == AC_PATHBROWSER ) { // // Generate the path browser menu + path browser icons if (bGenMenu) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<a href='javascript:showMenu(\\\""; p4wStrBuf curFi; curFi.EscapeURLAllChars(fRequest.GetURL(), fRequest.GetUnicode()); if (strchr(curFi.Text(), '%')) { p4wStrBuf curFi2; curFi2.EscapeURLAllChars(curFi, fRequest.GetUnicode()); htm << curFi2.Text(); } else htm << curFi.Text(); htm << "\\\",\\\"a1\\\",\\\"path\\\","; htm.endJSActionsLink(iconSz, bUseIcon); htm << "</script>" << crlf; htm << "<noscript>" << crlf; } for (i = 0; i < NFILEDIROPTS; i++) { // // Don't present some options if this // is browse-only or back-in-time mode if( ( fRequest.GetBrowseMode() || fRequest.GetBITBRev().Length() ) && !p4wAllCommands::CanBrowse( fileDirVal[i] ) ) continue; // // Some commands don't work well with // back-in-time browsing so disable them if( fRequest.GetBITBRev().Length() && ( fileDirVal[i] == AC_UNRESOLVED || fileDirVal[i] == AC_OPENEDFILESALL || fileDirVal[i] == AC_OPENEDUNCHANGED || fileDirVal[i] == AC_CHANGESUNOPENED ) ) continue; // // Generate entire location url redirectUrl( fileDirVal[i], locUrl, &fRequest ); if( fRequest.GetCmd() == AC_SYNCCMD || fRequest.GetCmd() != fileDirVal[i] ) selected = 0; else selected = 1; htm.selectOpt( selected, locUrl.Text() ); htm.text( fileDirText[i] ); } htm.endSelect(); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "3" ); htm.icon( clearIcon.Text(), "30", "3", "", 1 ); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "40" ); htm.button( "view", "Go" ); htm.endCol(); htm.beginCol(); htm.endForm(); htm.endCol(); } else { // // Need to check the server protocol level as some // features are not supported by older servers. // // Cancel & revert confirmation pages need p4 init(). // Also, // we need to cancel the server cancel because // in this case we need to issue a server cmd // to check the protocol to fill in the subnav // menu options. if( fRequest.GetCmd() == AC_CANCELCMD || fRequest.GetCmd() == AC_REVERTCONFIRM ) { globalCancel = 0; Error e; fRequest.p4Init( &e ); } const StrPtr *server = fRequest.GetProtocol( "server2" ); // // Generate the file browser menu + file browser icons if (bGenMenu) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<a href='javascript:showMenu(\\\""; p4wStrBuf curFi; curFi.EscapeURLAllChars(fRequest.GetURL(), fRequest.GetUnicode()); if (strchr(curFi.Text(), '%')) { p4wStrBuf curFi2; curFi2.EscapeURLAllChars(curFi, fRequest.GetUnicode()); htm << curFi2.Text(); } else htm << curFi.Text(); htm << "\\\",\\\"a1\\\",\\\"file\\\","; htm.endJSActionsLink(iconSz, bUseIcon); htm << "</script>" << crlf; htm << "<noscript>" << crlf; } for (i = 0; i < NFILEFILEOPTS; i++) { // // Don't present some options if this // is browse-only or back-in-time mode if( ( fRequest.GetBrowseMode() || fRequest.GetBITBRev().Length() ) && !p4wAllCommands::CanBrowse( fileFileVal[i] ) ) continue; // // Annotate is only supported with // 2002.2+ servers if( fileFileVal[i] == AC_FULLANNOTATE || fileFileVal[i] == AC_CHGLISTANNOTATE || fileFileVal[i] == AC_CHGLISTFULLANNOTATE || fileFileVal[i] == AC_ANNOTATE ) { if( server && server->Atoi() < 14 ) continue; } // // Generate complete location url redirectUrl( fileFileVal[i], locUrl, &fRequest ); if( fRequest.GetCmd() == AC_SYNCCMD || fRequest.GetCmd() == AC_REMOVEFILEFRM || fRequest.GetCmd() == AC_REVERTUNCHANGEDFILEFRM || fRequest.GetCmd() == AC_LOCKFILEFRM || fRequest.GetCmd() == AC_UNLOCKFILEFRM || fRequest.GetCmd() != fileFileVal[i] ) selected = 0; else selected = 1; htm.selectOpt( selected, locUrl.Text() ); htm.text( fileFileText[i] ); } htm.endSelect(); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "3" ); htm.icon( clearIcon.Text(), "30", "3", "", 1 ); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "40" ); htm.button( "view", "Go" ); htm.endCol(); htm.beginCol(); htm.endForm(); htm.endCol(); } if (bGenMenu) htm << "</noscript>" << crlf; break; case TT_PENDING: // // Pending changelist just has return to changelists link if( fRequest.GetCmd() == AC_CANCELCMD || ( ac != AC_PENDINGCHANGELISTS && ac != AC_CHANGES && ac != AC_FIXPENDING ) ) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_PENDINGCHANGELISTS, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "View pending changelists"; htm.endNobreak(); htm.endLink(); htm.endCol(); } break; case TT_SUBMITTED: { // // List of changelists has no subnavigation menu. The // changelist does have a subnavigation menu. if( fRequest.GetCmd() == AC_CANCELCMD ) { StrBufDict subArgs; subArgs.SetVar( "mx", "50" ); if( lac == AC_PATHBROWSER ) urlMaker.ConstructURL( url, baseWPath.Text(), AC_SUBMITTEDCHANGELISTS, &subArgs, fRequest.GetUnicode() ); else urlMaker.ConstructURL( url, baseWPath.Text(), AC_SUBMITTEDCHANGELISTSFILE, &subArgs, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "View submitted changelists"; htm.endNobreak(); htm.endLink(); htm.endCol(); bGenMenu = 0; } else if( ac != AC_SUBMITTEDCHANGELISTS && ac != AC_SUBMITTEDCHANGELISTSFILE && ac != AC_FIXSUBMITTED ) { if( fRequest.GetBrowseMode() ) { htm.beginCol(0,0,0,0,0,0,0,1); AllCommands act = changeSubVal[0]; // // Need to determine if the list of // submitted changelists is from file or // path browser in order to determine correct // ac code to pass. if( act == AC_SUBMITTEDCHANGELISTS ) { AllCommands rt = fRequest.GetLastReturnType(); if( rt == AC_PATHBROWSER ) act = AC_SUBMITTEDCHANGELISTS; else act = AC_SUBMITTEDCHANGELISTSFILE; } redirectUrl( act, locUrl, &fRequest ); if (*(locUrl.Text()) == '\"') { char *p = locUrl.Text(); strcpy(p, p+1); if (*(p + strlen(p) - 1) == '\"') *(p + strlen(p) - 1) = '\0'; locUrl.SetLength(); } htm.beginLink(locUrl.Text()); htm.text( changeSubOptsText[0] ); htm.endLink(); htm.endCol(); } else { if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginCol(); htm.beginForm( actionURL.Text() ); htm.endCol(); if( bGenMenu ) htm << "</noscript>" << crlf; htm.beginCol( NULL, NULL, NULL, NULL, NULL, "1" ); if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginSelect( "viewValue", 1, 0, "go( this )" ); if( bGenMenu ) htm << "</noscript>" << crlf; // // Generate the submitted chg menu if (bGenMenu) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<a href='javascript:showMenu(\\\""; // any filename would go here htm << "\\\",\\\"a1\\\",\\\"subchg\\\","; htm.endJSActionsLink(iconSz, bUseIcon); htm << "</script>" << crlf; htm << "<noscript>" << crlf; } int sel = 0; int act; for (i = 0; i < NCHANGESUBOPTS; i++) { // // Don't present some options if this // is browse-only or back-in-time mode if( ( fRequest.GetBrowseMode() || fRequest.GetBITBRev().Length() ) && !p4wAllCommands::CanBrowse( changeSubVal[i] ) ) continue; if ( changeSubVal[i] == AC_EDITCHANGE ) continue; // // Is this the current command? Then it will // be highlighted. sel = ( fRequest.GetCmd() == changeSubVal[i] ); // // Get the current action to pass back act = changeSubVal[i]; // // Need to determine if the list of // submitted changelists is from file or // path browser in order to determine correct // ac code to pass. if( changeSubVal[i] == AC_SUBMITTEDCHANGELISTS ) { AllCommands rt = fRequest.GetLastReturnType(); if( rt == AC_PATHBROWSER ) act = AC_SUBMITTEDCHANGELISTS; else act = AC_SUBMITTEDCHANGELISTSFILE; } // // Construct complete location url redirectUrl( (AllCommands)act, locUrl, &fRequest ); htm.selectOpt( sel, locUrl.Text() ); htm.text( changeSubOptsText[i] ); } htm.endSelect(); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "3" ); htm.icon( clearIcon.Text(), "30", "3", "", 1 ); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "40" ); htm.button( "view", "Go" ); htm.endCol(); htm.beginCol(); htm.endForm(); htm.endCol(); } } else { htm.beginCol(); htm.beginUrlMenu(&fRequest, "menu_subchg"); fRequest << htm; htm.Clear(); renderSubChgMenuItem(AC_DESCRIBE, &fRequest, 1); if( protocol >= 23 ) // 2007.2 or later? renderSubChgMenuItem(AC_EDITCHANGE, &fRequest, 1); htm.SetSepNeeded(1); htm.RenderMenuItem("subchg", AC_CHANGES, 0, 1 << NCHANGESUBOPTS); fRequest << htm; htm.Clear(); renderSubChgMenuItem(AC_GETJOB, &fRequest, 2); renderSubChgMenuItem(AC_SYNCCHANGE, &fRequest, 2); htm.endUrlMenu(); htm.endCol(); fRequest << htm; htm.Clear(); bGenMenu = 0; // nothing more to do here for context menus } if (bGenMenu) htm << "</noscript>" << crlf; break; } case TT_BRANCH: { // // Branch detail has a subnavigation menu. The Branch list // only has a label to create a new branch, and create // branch only has a link to return to branches. if( ac == AC_CREATEBRANCH || fRequest.GetCmd() == AC_BRANCHCMD || fRequest.GetCmd() == AC_DELETEBRANCH || fRequest.GetCmd() == AC_CANCELCMD ) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_BRANCHES, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "View branches"; htm.endNobreak(); htm.endLink(); htm.endCol(); bGenMenu = 0; } else if( ac == AC_BRANCHES ) { // // Don't present some options if this // is browse-only or back-in-time mode if( !fRequest.GetBrowseMode() && (fRequest.GetBITBRev().Length() == 0) && (fRequest.GetScreenChunks() & SCRN_TOOLBAR)) { urlMaker.ConstructURL( url, baseNonePath.Text(), AC_CREATEBRANCH, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "Create branch spec"; htm.endNobreak(); htm.endLink(); htm.endCol(); } htm.beginCol(); htm.beginUrlMenu(&fRequest, "menu_branch"); fRequest << htm; htm.Clear(); renderBranchMenuItem(AC_BRANCHVIEW, &fRequest, 1); renderBranchMenuItem(AC_EDITBRANCH, &fRequest, 1); renderBranchMenuItem(AC_DELETEBRANCHCONFIRM, &fRequest, 1); if (!fRequest.GetBrowseMode()) { htm.SetSepNeeded(1); htm.RenderMenuItem("branch", AC_BRANCHES, 0, 1 << NBRANCHSUBOPTS); fRequest << htm; htm.Clear(); } renderBranchMenuItem(AC_INTEGRATEBRANCH, &fRequest, 2); renderBranchMenuItem(AC_BRANCHDIFF, &fRequest, 1); htm.endUrlMenu(); htm.endCol(); fRequest << htm; htm.Clear(); bGenMenu = 0; } else { if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginCol(); htm.beginForm( actionURL.Text() ); htm.endCol(); if( bGenMenu ) htm << "</noscript>" << crlf; htm.beginCol( NULL, NULL, NULL, NULL, NULL, "1" ); if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginSelect( "viewValue", 1, 0, "go( this )" ); if( bGenMenu ) htm << "</noscript>" << crlf; // // Generate the branch menu if (bGenMenu) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<a href='javascript:showMenu(\\\""; // any filename would go here htm << "\\\",\\\"a1\\\",\\\"branch\\\","; htm.endJSActionsLink(iconSz, bUseIcon); htm << "</script>" << crlf; htm << "<noscript>" << crlf; htmmenu.beginUrlMenu(&fRequest, "menu_branch"); } int sl; int action; int j = 0; for (i = 0; i < NBRANCHSUBOPTS; i++) { // // Don't present some options if this // is browse-only or back-in-time mode if( ( fRequest.GetBrowseMode() || fRequest.GetBITBRev().Length() ) && !p4wAllCommands::CanBrowse( branchSubVal[i] ) ) continue; // // Is this the current command? Then it will // be highlighted. sl = ( fRequest.GetCmd() == branchSubVal[i] ); // // Generate complete location url redirectUrl( branchSubVal[i], locUrl, &fRequest ); htm.selectOpt( sl, locUrl.Text() ); htm.text( branchSubOptsText[i] ); if (bGenMenu) htmmenu.renderUrlMenuItem( "branch", i, branchSubVal[i], locUrl.Text(), branchSubOptsHead[i], strstr(branchSubOptsText[i], "...") ? 1 : 0); switch(branchSubVal[i]) { case AC_BRANCHES: case AC_DELETEBRANCHCONFIRM: htmmenu.SetSepNeeded(1); htmmenu.RenderMenuItem("branch", AC_BRANCHES, 0, 1 << (NBRANCHSUBOPTS + j++)); break; } } if (bGenMenu) htmmenu.endUrlMenu(); htm.endSelect(); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "3" ); htm.icon( clearIcon.Text(), "30", "3", "", 1 ); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "40" ); htm.button( "view", "Go" ); htm.endCol(); htm.beginCol(); htm.endForm(); htm.endCol(); } if (bGenMenu) htm << "</noscript>" << crlf; break; } case TT_LABEL: // Label detail has a subnavigation menu. The Label list // only has a link to create a new label, and create // label also only has a link to return to labels. if( ac == AC_CREATELABEL || fRequest.GetCmd() == AC_CREATELABELTMP || fRequest.GetCmd() == AC_LABELCMD || fRequest.GetCmd() == AC_DELETELABEL || fRequest.GetCmd() == AC_CANCELCMD ) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_LABELS, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "View labels"; htm.endNobreak(); htm.endLink(); htm.endCol(); bGenMenu = 0; } else if( ac == AC_LABELS || ac == AC_LABELSPATH ) { // // Generate a new label link unless this // is browse-only or back-in-time mode if( !fRequest.GetBrowseMode() && (fRequest.GetBITBRev().Length() == 0) && (fRequest.GetScreenChunks() & SCRN_TOOLBAR)) { urlMaker.ConstructURL( url, baseNonePath.Text(), AC_CREATELABEL, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "Create label spec"; htm.endNobreak(); htm.endLink(); htm.endCol(); } htm.beginCol(); htm.beginUrlMenu(&fRequest, "menu_label"); fRequest << htm; htm.Clear(); renderLabelMenuItem(AC_LABELVIEW, &fRequest, 1); renderLabelMenuItem(AC_EDITLABEL, &fRequest, 1); renderLabelMenuItem(AC_DELETELABELCONFIRM, &fRequest, 1); renderLabelMenuItem(AC_CREATELABELTMP, &fRequest, 1); // if (!fRequest.GetBrowseMode()) { htm.SetSepNeeded(1); htm.RenderMenuItem("label", AC_LABELS, 0, 1 << NLABELSUBOPTS); fRequest << htm; htm.Clear(); } renderLabelMenuItem(AC_LABELFILES, &fRequest, 1); const StrPtr *X = fRequest.GetStateArg("X"); if (X && strchr(X->Text(), 'l')) renderLabelMenuItem(AC_LABELFILESTEXT, &fRequest, 1); renderLabelMenuItem(AC_REPLACELABEL, &fRequest, 1); renderLabelMenuItem(AC_SYNCLABEL, &fRequest, 2); htm.endUrlMenu(); htm.endCol(); fRequest << htm; htm.Clear(); bGenMenu = 0; } else { if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginCol(); htm.beginForm( actionURL.Text() ); htm.endCol(); if( bGenMenu ) htm << "</noscript>" << crlf; htm.beginCol( NULL, NULL, NULL, NULL, NULL, "1" ); if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginSelect( "viewValue", 1, 0, "go( this )" ); if( bGenMenu ) htm << "</noscript>" << crlf; // // Generate the label menu if (bGenMenu) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<a href='javascript:showMenu(\\\""; // any filename would go here htm << "\\\",\\\"a1\\\",\\\"label\\\","; htm.endJSActionsLink(iconSz, bUseIcon); htm << "</script>" << crlf; htm << "<noscript>" << crlf; htmmenu.beginUrlMenu(&fRequest, "menu_label"); } int j = 0; for ( i = 0; i < NLABELSUBOPTS; i++ ) { // // Don't present some options if this // is browse-only or back-in-time mode if( ( fRequest.GetBrowseMode() || fRequest.GetBITBRev().Length() ) && !p4wAllCommands::CanBrowse( labelSubVal[i] ) ) continue; // // Generate the complete location url redirectUrl( labelSubVal[i], locUrl, &fRequest ); if( fRequest.GetCmd() == labelSubVal[i] ) htm.selectOpt( 1, locUrl.Text() ); else htm.selectOpt( 0, locUrl.Text() ); htm.text( labelSubOptsText[i] ); if (labelSubVal[i] == AC_LABELFILESTEXT) { const StrPtr *X = fRequest.GetStateArg("X"); if (!X || !strchr(X->Text(), 'l')) continue; } if (bGenMenu) htmmenu.renderUrlMenuItem( "label", i, labelSubVal[i], locUrl.Text(), labelSubOptsHead[i], strstr(labelSubOptsText[i], "...") ? 1 : 0); switch(labelSubVal[i]) { case AC_LABELS: case AC_CREATELABELTMP: htmmenu.SetSepNeeded(1); htmmenu.RenderMenuItem("label", AC_LABELS, 0, 1 << (NLABELSUBOPTS + j++)); break; } } if (bGenMenu) htmmenu.endUrlMenu(); htm.endSelect(); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "3" ); htm.icon( clearIcon.Text(), "30", "3", "", 1 ); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "40" ); htm.button( "view", "Go" ); htm.endCol(); htm.beginCol(); htm.endForm(); htm.endCol(); } if (bGenMenu) htm << "</noscript>" << crlf; break; case TT_CLIENT: // // List of clients has no subnavigation menu. The // client spec has only a return to clients link if( (ac != AC_CLIENTS && ac != AC_MULTIUSER) || fRequest.GetCmd() == AC_CANCELCMD ) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_CLIENTS, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "View clients"; htm.endNobreak(); htm.endLink(); htm.endCol(); bGenMenu = 0; } else if( ac == AC_CLIENTS ) { Options *opts = fRequest.GetOpts(); if (fRequest.GetScreenChunks() & SCRN_TOOLBAR) { if( !fRequest.GetBrowseMode() && fRequest.GetMultiUser() && strcmp(fRequest.GetClient().Text(), "(not set)")) { if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginCol(); htm.beginForm( actionURL.Text() ); htm.endCol(); if( bGenMenu ) htm << "</noscript>" << crlf; htm.beginCol( NULL, NULL, NULL, NULL, NULL, "1" ); if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginSelect( "viewValue", 1, 0, "go( this )" ); if( bGenMenu ) htm << "</noscript>" << crlf; // // Generate the clients menu if (bGenMenu) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<a href='javascript:showMenu(\\\""; // any filename would go here htm << "\\\",\\\"a1\\\",\\\"clients\\\","; htm.endJSActionsLink(iconSz, bUseIcon); htm << "</script>" << crlf; htm << "<noscript>" << crlf; htmmenu.beginUrlMenu(&fRequest, "menu_clients"); } int j = 0; for ( i = 0; i < NCLIENTSSUBOPTS; i++ ) { // // Generate the complete location url redirectUrl( clientsSubVal[i], locUrl, &fRequest ); if( fRequest.GetCmd() == clientsSubVal[i] ) htm.selectOpt( 1, locUrl.Text() ); else htm.selectOpt( 0, locUrl.Text() ); htm.text( clientsSubOptsText[i] ); if (bGenMenu) htmmenu.renderUrlMenuItem( "clients", i, clientsSubVal[i], locUrl.Text(), clientsSubOptsHead[i], strstr(clientsSubOptsText[i], "...") ? 1 : 0); } if (bGenMenu) htmmenu.endUrlMenu(); htm.endSelect(); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "3" ); htm.icon( clearIcon.Text(), "30", "3", "", 1 ); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "40" ); htm.button( "view", "Go" ); htm.endCol(); htm.beginCol(); htm.endForm(); htm.endCol(); if (bGenMenu) htm << "</noscript>" << crlf; } else if( (*opts)[ 'M' ] ) { urlMaker.ConstructURL( url, baseNonePath.Text(), AC_MULTIUSER, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "Choose client"; htm.endNobreak(); htm.endLink(); htm.endCol(); bGenMenu = 0; } else if( !fRequest.GetBrowseMode() && strcmp(fRequest.GetClient().Text(), "(not set)")) { urlMaker.ConstructURL( url, baseNonePath.Text(), AC_EDITCLIENT, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "Edit current client"; htm.endNobreak(); htm.endLink(); htm.endCol(); bGenMenu = 0; } else bGenMenu = 0; } else bGenMenu = 0; htm.beginCol(); htm.beginUrlMenu(&fRequest, "menu_client"); fRequest << htm; htm.Clear(); renderClientMenuItem(AC_CLIENTVIEW, &fRequest, 1); renderClientMenuItem(AC_EDITCLIENT, &fRequest, 0); // if (!fRequest.GetBrowseMode()) { htm.SetSepNeeded(1); htm.RenderMenuItem("client", AC_CLIENTS, 0, 1 << NCLIENTSUBOPTS); fRequest << htm; htm.Clear(); } renderClientMenuItem(AC_CLIENTSWITCH, &fRequest, 1); htm.endUrlMenu(); htm.endCol(); fRequest << htm; htm.Clear(); } break; case TT_USER: // // List of clients has no subnavigation menu. The // client spec has only a return to clients link if( ac != AC_USERS || fRequest.GetCmd() == AC_CANCELCMD ) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_USERS, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "View users"; htm.endNobreak(); htm.endLink(); htm.endCol(); } else if( ac == AC_USERS && !fRequest.GetBrowseMode() ) { urlMaker.ConstructURL( url, baseNonePath.Text(), AC_EDITUSER, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "Edit current user"; htm.endNobreak(); htm.endLink(); htm.endCol(); } break; case TT_JOB: // // List of jobs has only a link to create a new job. // Job detail has a subnavigation menu. Create job // has only a link to return to jobs. if( ac == AC_CREATEJOB || fRequest.GetCmd() == AC_JOBCMD || fRequest.GetCmd() == AC_DELETEJOB || fRequest.GetCmd() == AC_CANCELCMD ) { StrBufDict jobArgs; jobArgs.SetVar( "mx", "10" ); urlMaker.ConstructURL( url, baseWPath.Text(), AC_JOBS, &jobArgs, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "View jobs"; htm.endNobreak(); htm.endLink(); htm.endCol(); bGenMenu = 0; } else if( ac == AC_JOBS ) { // Generate the new job link unless this is // browse-only or back-in-time browse mode if( !fRequest.GetBrowseMode() && (fRequest.GetBITBRev().Length() == 0) && (fRequest.GetScreenChunks() & SCRN_TOOLBAR)) { urlMaker.ConstructURL( url, baseNonePath.Text(), AC_CREATEJOB, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "Create job"; htm.endNobreak(); htm.endLink(); htm.endCol(); } htm.beginCol(); htm.beginUrlMenu(&fRequest, "menu_job"); fRequest << htm; htm.Clear(); renderJobMenuItem(AC_JOBVIEW, &fRequest, 1); renderJobMenuItem(AC_EDITJOB, &fRequest, 1); renderJobMenuItem(AC_DELETEJOBCONFIRM, &fRequest, 1); if (!fRequest.GetBrowseMode()) { htm.SetSepNeeded(1); htm.RenderMenuItem("job", AC_JOBS, 0, 1 << NJOBSUBOPTS); fRequest << htm; htm.Clear(); } renderJobMenuItem(AC_FIXPENDING, &fRequest, 2); renderJobMenuItem(AC_FIXSUBMITTED, &fRequest, 2); if (!fRequest.GetBrowseMode()) { htm.SetSepNeeded(1); htm.RenderMenuItem("job", AC_JOBS, 0, 1 << (NJOBSUBOPTS+1)); fRequest << htm; htm.Clear(); } renderJobMenuItem(AC_FIXESJOB, &fRequest, 1); renderJobMenuItem(AC_JOBFIELDS, &fRequest, 1); htm.endUrlMenu(); htm.endCol(); fRequest << htm; htm.Clear(); bGenMenu = 0; } else { if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginCol(); htm.beginForm( actionURL.Text() ); htm.endCol(); if( bGenMenu ) htm << "</noscript>" << crlf; htm.beginCol( NULL, NULL, NULL, NULL, NULL, "1" ); if( bGenMenu ) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginSelect( "viewValue", 1, 0, "go( this )" ); if( bGenMenu ) htm << "</noscript>" << crlf; // // Generate the branch menu if (bGenMenu) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<a href='javascript:showMenu(\\\""; // any filename would go here htm << "\\\",\\\"a1\\\",\\\"job\\\","; htm.endJSActionsLink(iconSz, bUseIcon); htm << "</script>" << crlf; htm << "<noscript>" << crlf; htmmenu.beginUrlMenu(&fRequest, "menu_job"); } int j = 0; for (i = 0; i < NJOBSUBOPTS; i++) { // // Don't present some options if this // is browse-only or back-in-time mode if( ( fRequest.GetBrowseMode() || fRequest.GetBITBRev().Length() ) && !p4wAllCommands::CanBrowse( jobSubVal[i] ) ) continue; // // Generate complete location url redirectUrl( jobSubVal[i], locUrl, &fRequest ); if( fRequest.GetCmd() == jobSubVal[i] ) htm.selectOpt( 1, locUrl.Text() ); else htm.selectOpt( 0, locUrl.Text() ); htm.text( jobSubOptsText[i] ); if (bGenMenu) htmmenu.renderUrlMenuItem( "job", i, jobSubVal[i], locUrl.Text(), jobSubOptsHead[i], strstr(jobSubOptsText[i], "...") ? 1 : 0); switch(jobSubVal[i]) { case AC_JOBS: case AC_DELETEJOBCONFIRM: case AC_FIXSUBMITTED: htmmenu.SetSepNeeded(1); htmmenu.RenderMenuItem("job", AC_JOBS, 0, 1 << (NJOBSUBOPTS + j++)); break; } } if (bGenMenu) htmmenu.endUrlMenu(); htm.endSelect(); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "3" ); htm.icon( clearIcon.Text(), "30", "3", "", 1 ); htm.endCol(); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "40" ); htm.button( "view", "Go" ); htm.endCol(); htm.beginCol(); htm.endForm(); htm.endCol(); } if (bGenMenu) htm << "</noscript>" << crlf; break; case TT_SETTINGS: if( fRequest.GetCmd() == AC_CANCELCMD ) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_CONFIGURATION, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "‹--Return to settings"; htm.endNobreak(); htm.endLink(); htm.endCol(); } break; case TT_P4CMD: if( fRequest.GetCmd() == AC_CANCELCMD ) { urlMaker.ConstructURL( url, baseNoPath.Text(), AC_P4CMDPANE, NULL, fRequest.GetUnicode() ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "60" ); htm.beginLink( url.Text(), "nav_link" ); htm.beginNobreak(); htm << "‹--Return to p4 cmd"; htm.endNobreak(); htm.endLink(); htm.endCol(); } break; default: break; } int nbrbtns = 0; if (!(fRequest.GetScreenChunks() & SCRN_TOOLBAR)) { htm.Clear(); goto menuonly; } fRequest << htm; htm.Clear(); // // Generate icons if this is the file tab if( tab == TT_FILE ) doIcons( lac ); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "3" ); htm.icon( clearIcon.Text(), "1", "3", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Generate the Cancel button if( tab == TT_SUBMITTED ) htm.beginCol( ); else htm.beginCol( NULL, "right" ); fRequest << htm; htm.Clear(); doCancelButton(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "4" ); htm.icon( clearIcon.Text(), "1", "4", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Generate the Logout button if (!fRequest.BypassAuth()) { htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); fRequest << htm; htm.Clear(); doLogoutButton(); } // // Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, fRequest.GetBrowseMode() ? "6" : "11" ); if (!fRequest.GetBrowseMode()) htm.icon( clearIcon.Text(), "1", "5", "", 1, "0", "0" ); htm.icon( grayIcon.Text(), "18", "1", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Generate the Recent Activity toggle button int rc; if (rc = p4wAllCommands::ShowRecentActivity( ac )) { if (rc != 2) { if( fRequest.HideRecentChanges() ) urlMaker.ConstructIcon( icon, "/recentactivityIcon", iconSz, iconSz, "Show recent activity bar", 1 ); else urlMaker.ConstructIcon( icon, "/recentactivityOnIcon", iconSz, iconSz, "Hide recent activity bar", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( recentUrl.Text() ); htm << icon; htm.endLink(); htm.endCol(); nbrbtns++; } if (!SEC_DISALLOW_RAW_CMDS || fRequest.isLocalRequest()) { // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Generate the Raw Commands toggle button if( fRequest.HideRawP4Cmds() ) urlMaker.ConstructIcon( icon, "/p4cmdIcon", iconSz, iconSz, "Show P4 command bar", 1 ); else urlMaker.ConstructIcon( icon, "/p4cmdOnIcon", iconSz, iconSz, "Hide P4 command bar", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( rawCmdUrl.Text() ); htm << icon; htm.endLink(); htm.endCol(); nbrbtns++; } // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Generate the GoTo toggle button if( fRequest.HideGoTo() ) urlMaker.ConstructIcon( icon, "/goIcon", iconSz, iconSz, "Show go to bar", 1 ); else urlMaker.ConstructIcon( icon, "/goOnIcon", iconSz, iconSz, "Hide go to bar", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( gotoUrl.Text() ); htm << icon; htm.endLink(); htm.endCol(); nbrbtns++; } // // Separator if (nbrbtns) { htm.beginCol( "middle", "center", NULL, NULL, NULL, "11" ); htm.icon( clearIcon.Text(), "1", "5", "", 1, "0", "0" ); htm.icon( grayIcon.Text(), "18", "1", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); } // // About/Information button htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); urlMaker.ConstructIcon( icon, "/infoIcon", iconSz, iconSz, "Information", 1 ); htm.beginLink( aboutUrl.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Help urlMaker.ConstructIcon( icon, "/helpIcon", iconSz, iconSz, "Help", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "30" ); htm.beginLink( helpUrl.Text(), NULL, "nav_link" ); htm << icon; htm.endLink(); htm.endCol(); if (!(fRequest.GetScreenChunks() & SCRN_TABS) && !(fRequest.GetScreenChunks() & SCRN_HEADER)) { htm.beginCol(0,0,0,0,0,"100%"); htm << " "; htm.endCol(); } if (!X || !strchr(X->Text(), 't')) { // // End this part of the table htm.endTRow(); htm.endTable(); htm.endCol(); } htm.beginCol(0,0,0,0,0,0,0,1); // // RSS link if needed if (fRequest.GetCmd() == AC_SUBMITTEDCHANGELISTS || fRequest.GetCmd() == AC_JOBS) { p4wStrBuf rssURL; if (fRequest.GetCmd() == AC_SUBMITTEDCHANGELISTS) { urlMaker.ConstructURL( rssURL, NULL, AC_RSSCHGS, fRequest.GetDynArgs() ); } else { urlMaker.ConstructURL( rssURL, NULL, AC_RSSJOBS, fRequest.GetDynArgs() ); int i; StrPtr *s; for( i = 0; ( s = (StrPtr *)fRequest.GetDynArg( "jsf", i ) ) != NULL; i++ ) rssURL << "&jsf=" << s; } rssURL << RSSEXT; htm << " "; htm.beginLink( rssURL.Text() ); StrBuf icon; urlMaker.ConstructURL( icon, "/rssIcon", AC_ICON, NULL ); htm.icon( icon.Text(), "25", "47", "RSS 2.0", 1, NULL, NULL, "absmiddle" ); htm.endLink(); } htm.endCol(); if (X && strchr(X->Text(), 't')) { // // End this part of the table htm.endTRow(); htm.endTable(); htm.endCol(); if( fRequest.GetJavascriptMode() == 2 ) // MSIE { htm.beginCol(0,0,"100%",0,0,"100%"); htm.endCol(); } } htm.endTRow(); htm.endTable(); menuonly: htm.SetRequest(&fRequest); if (bGenMenu && !thx) { switch(tab) { case TT_FILE: if (ac == AC_BROWSEFILE) { htm.RenderRevHistMenu(); } else if (fRequest.GetLastReturnType() == AC_PATHBROWSER) { htm.RenderPathMenu(); htm.RenderFileMenu(-1); } case TT_SUBMITTED: case TT_BRANCH: case TT_LABEL: case TT_CLIENT: case TT_JOB: fRequest << htm << htmmenu; htm.Clear(); break; default: break; } } htm.endCol(); htm.endTRow(); htm.comment( "END SUBNAVIGATION" ); fRequest << htm; } void p4wMenuPane::doIcons( AllCommands ac ) { // // Generate the icons for the path or file // browser page p4wURL urlMaker; StrBuf url; p4wHtml htm; StrBuf icon; StrBuf grayIcon; StrBuf clearIcon; StrBuf baseNoPath; StrBuf baseWPath; StrBuf baseDPath; StrBufDict cmdArgs; StrBuf path; int iconSz = 25; const StrPtr *X = fRequest.GetStateArg( "X" ); // undoc eXperimental flags if (X) { if (strchr(X->Text(), '3')) iconSz = 37; else if (strchr(X->Text(), '4')) iconSz = 50; else if (strchr(X->Text(), '6')) iconSz = 75; else if (strchr(X->Text(), '8')) iconSz = 100; } // // Construct some frequently used icons urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); urlMaker.ConstructURL( grayIcon, "/grayPixelIcon", AC_ICON, NULL ); // // Construct bases used to construct the urls. Some links // require the path, and others have the path cleared out. path.Set( fRequest.GetReturnURL( ac ).Text() ); fRequest.UseNewBase( baseWPath, NULL, "path", path.Text() ); if( ac == AC_PATHBROWSER ) baseWPath << "..."; fRequest.UseNewBase( baseNoPath, NULL, "path", "//" ); // // Remove the node/filename (if present) for the View depot // tree command if( ac != AC_PATHBROWSER ) { char *e = urlMaker.GetNodeLocation( path.Text(), fRequest.GetViewMode() != VM_WORKSPACE, ac ); path.Set( path.Text(), e - path.Text() ); } fRequest.UseNewBase( baseDPath, NULL, "path", path.Text() ); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); if( ac == AC_BROWSEFILE ) { // // First icon for file browser mode is view depot tree urlMaker.ConstructURL( url, baseDPath.Text(), AC_PATHBROWSER, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/gotreeIcon", iconSz, iconSz, "Display tree view", 1 ); } else { // // Otherwise, first icon is up one level StrBuf base; StrBuf pathup; pathup.Set( fRequest.GetReturnURL( ac ).Text() ); char *p = pathup.Text() + pathup.Length() - 1; *p = '\0'; if (strcmp(fRequest.GetClientRoot().Text(), pathup.Text())) { p = strrchr(pathup.Text(), '/'); if (!p) p = strrchr(pathup.Text(), '\\'); if (!p) { pathup.Set( fRequest.GetReturnURL( ac ).Text() ); p = pathup.Text() + pathup.Length() - 1; } *++p = '\0'; pathup.SetLength(); } fRequest.UseNewBase( base, NULL, "path", pathup.Text() ); urlMaker.ConstructURL( url, base.Text(), ac, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/gotreeIcon", iconSz, iconSz, "Up one level", 1 ); } htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "7" ); htm.icon( grayIcon.Text(), "18", "1", "", 1, "0", "0" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endCol(); // // Display listview toggle icons const StrPtr *server; int protocol = 0; server = fRequest.GetProtocol( "server2" ); if( server ) protocol = server->Atoi(); if( protocol > 19 ) { fRequest << htm; htm.Clear(); listviewIcons(&fRequest, ac); } // // Generate the icons for the path browser only if this // is not browse-only mode or back-in-time browsing. if( ac == AC_PATHBROWSER && !fRequest.GetBrowseMode() && ( fRequest.GetBITBRev().Length() == 0 ) ) { // // Next icon for path browser mode switches between depot and workspace views if( fRequest.GetViewMode() == VM_WORKSPACE ) { // // In workspace mode: display link to switch to depot // mode StrBuf newBase; fRequest.UseNewBase( newBase, NULL, "md", "c" ); fRequest.UseNewBase( newBase, newBase.Text(), "cd", "//" ); fRequest.UseNewBase( newBase, newBase.Text(), "cdf", NULL ); fRequest.UseNewBase( newBase, newBase.Text(), "wr", NULL ); fRequest.UseNewBase( newBase, newBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( url, newBase.Text(), AC_DEPOTVIEW, NULL, fRequest.GetUnicode() ); } else { urlMaker.ConstructURL( url, NULL, AC_WORKSPACE, NULL, fRequest.GetUnicode() ); } urlMaker.ConstructIcon( icon, fRequest.GetViewMode() == VM_WORKSPACE ? "/workspace_icon_onIcon" : "/workspace_icon_offIcon", iconSz, iconSz, fRequest.GetViewMode() == VM_WORKSPACE ? "Display depot tree" : "Display workspace tree", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "7" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.icon( grayIcon.Text(), "18", "1", "", 1, "0", "0" ); htm.endCol(); // // Sync to head icon urlMaker.ConstructURL( url, baseWPath.Text(), AC_SYNCCMD, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/runsyncIcon", iconSz, iconSz, "Sync to head revisions", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Open for edit urlMaker.ConstructURL( url, baseWPath.Text(), AC_EDITFILE, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/runeditIcon", iconSz, iconSz, "Open for edit in default changelist", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text(), 0, 0, 0, 0, 0, "onClick", "return confirm('WARNING: You are about to open all files in this folder and its subfolders for edit. Do you want to proceed?')" ); htm << icon; htm.endLink(); htm.endCol(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Open for delete urlMaker.ConstructURL( url, baseWPath.Text(), AC_DELETEFILE, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/rundeleteIcon", iconSz, iconSz, "Open for delete in default changelist", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text(), 0, 0, 0, 0, 0, "onClick", "return confirm('WARNING: You are about to open all files in this folder and its subfolders for delete. Do you want to proceed?')" ); htm << icon; htm.endLink(); htm.endCol(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Submit default changelist urlMaker.ConstructURL( url, baseNoPath.Text(), AC_CHANGEPENDINGEDIT, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/runsubmitIcon", iconSz, iconSz, "Submit default changelist", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Revert all unchanged files in this path cmdArgs.SetVar( "fl", "-a" ); urlMaker.ConstructURL( url, baseWPath.Text(), AC_REVERTCMD, &cmdArgs, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/runrevertIcon", iconSz, iconSz, "Revert unchanged files", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); } else if( ac == AC_BROWSEFILE || ac == AC_FILESTATE ) { // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // File browser (filelog) needs a link to toggle between // showing extended filelog or not unless forbidden by // the -sh flag if (!SEC_DISALLOW_REVHIST_INTEG || fRequest.isLocalRequest()) { // // if already showing extended filelog so display // link to turn it off AllCommands cmd = AC_BROWSEFILE; if (fRequest.GetCmd() == AC_CHGLISTANNOTATE) cmd = AC_CHGLISTANNOTATE; else if (fRequest.GetCmd() == AC_CHGLISTFULLANNOTATE) cmd = AC_CHGLISTFULLANNOTATE; const StrPtr *iFlag = fRequest.GetDynArg( "fl" ); if( iFlag && (*iFlag == "-i" || *iFlag == "-h") ) { if( fRequest.GetViewMode() == VM_WORKSPACE ) { StrBuf baseWMPath; fRequest.UseNewBase( baseWMPath, NULL, "path", fRequest.GetPath().Text() ); urlMaker.ConstructURL( url, baseWMPath.Text(), cmd, NULL, fRequest.GetUnicode() ); } else { fRequest.ConstructSafeURL( url, fRequest.GetURL().Text(), cmd, NULL ); } urlMaker.ConstructIcon( icon, "/branchHistOnIcon", iconSz, iconSz, "Hide branching history", 1 ); // // Display link to turn on extended filelog } else { StrBufDict cmdArgs; const StrPtr *M = fRequest.GetStateArg("M"); int bh = (M && strchr(M->Text(), 'h')) ? 1 : 0; cmdArgs.SetVar( "fl", bh ? "-h" : "-i" ); if( fRequest.GetViewMode() == VM_WORKSPACE ) { StrBuf baseWMPath; fRequest.UseNewBase( baseWMPath, NULL, "path", fRequest.GetPath().Text() ); urlMaker.ConstructURL( url, baseWMPath.Text(), cmd, &cmdArgs, fRequest.GetUnicode() ); } else { fRequest.ConstructSafeURL( url, fRequest.GetURL().Text(), cmd, &cmdArgs ); } urlMaker.ConstructIcon( icon, "/branchHistOffIcon", iconSz, iconSz, bh ? "Show content history" : "Show branching history", 1 ); } if ((cmd == AC_CHGLISTANNOTATE) || (cmd == AC_CHGLISTFULLANNOTATE)) { const StrPtr *u = fRequest.GetDynArg("u"); if (u) url << "&u=1"; } htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); } // // Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "7" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.icon( grayIcon.Text(), "18", "1", "", 1, "0", "0" ); htm.endCol(); if( !fRequest.GetBrowseMode() && ( fRequest.GetBITBRev().Length() == 0 ) ) { // // Sync to head icon urlMaker.ConstructURL( url, baseWPath.Text(), AC_SYNCFILE, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/runsyncIcon", iconSz, iconSz, "Sync to head revision", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Open for edit urlMaker.ConstructURL( url, baseWPath.Text(), AC_EDITFILE, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/runeditIcon", iconSz, iconSz, "Open for edit in default changelist", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Open for delete urlMaker.ConstructURL( url, baseWPath.Text(), AC_DELETEFILE, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/rundeleteIcon", iconSz, iconSz, "Open for delete in default changelist", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Diff file urlMaker.ConstructURL( url, baseWPath.Text(), AC_DIFFWVC, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/rundiffIcon", iconSz, iconSz, "Diff synced revision vs. workspace file", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Diff options menu fRequest << htm; htm.Clear(); diffsMenu(&fRequest); // // Launch editor # if defined( OS_MACOSX ) || defined( OS_NT ) if ( !fRequest.isLocalRequest() ) { urlMaker.ConstructURL( url, baseWPath.Text(), AC_EDITTEXTLOCAL, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/launcheditIcon", iconSz, iconSz, "Edit workspace file in browser", 1 ); } else #endif { urlMaker.ConstructURL( url, baseWPath.Text(), AC_LAUNCHEDITOR, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/launcheditIcon", iconSz, iconSz, "Edit workspace file in default editor", 1 ); } htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); } // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // View Depot file urlMaker.ConstructURL( url, baseWPath.Text(), AC_FILETEXTDEPOT, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/showtextIcon", iconSz, iconSz, "View head revision text", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // if( !fRequest.GetBrowseMode() && ( fRequest.GetBITBRev().Length() == 0 ) ) { // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Submit default changelist urlMaker.ConstructURL( url, baseNoPath.Text(), AC_CHANGEPENDINGEDIT, NULL, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/runsubmitIcon", iconSz, iconSz, "Submit default changelist", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); // // Clear Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "2" ); htm.icon( clearIcon.Text(), "1", "2", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); // // Revert if unchanged cmdArgs.SetVar( "fl", "-a" ); urlMaker.ConstructURL( url, baseWPath.Text(), AC_REVERTFILE, &cmdArgs, fRequest.GetUnicode() ); urlMaker.ConstructIcon( icon, "/runrevertIcon", iconSz, iconSz, "Revert if unchanged", 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( url.Text() ); htm << icon; htm.endLink(); htm.endCol(); } } // // Separator htm.beginCol( "middle", "center", NULL, NULL, NULL, "7" ); htm.icon( clearIcon.Text(), "1", "4", "", 1, "0", "0" ); htm.icon( grayIcon.Text(), "18", "1", "", 1, "0", "0" ); htm.endLink(); htm.endCol(); fRequest << htm; } void p4wMenuPane::doCancelButton() { // // Generate a cancel server request button if // appropriate. p4wHtml htm; p4wURL urlMaker; StrBuf clearIcon; urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); // // Exclude this button from pages where it doesn't // make sense (where no server command is generated). // Also, don't // display this button on this button's result page. switch( fRequest.GetCmd() ) { case AC_CANCELCMD: case AC_SUBMITFRM: case AC_FILESMATCHINGFRM: case AC_DELETEJOBCONFIRM: case AC_DELETEBRANCHCONFIRM: case AC_DELETELABELCONFIRM: case AC_REVERTCONFIRM: case AC_HELP: htm.icon( clearIcon.Text(), "25", "25", "", 1 ); htm.endCol(); fRequest << htm; return; default: break; } // // An error page also doesn't need a cancel button if( fView.IsErrorPage() ) { htm.icon( clearIcon.Text(), "25", "25", "", 1 ); htm.endCol(); fRequest << htm; return; } // // Only display this button // if the server supports this functionality. const StrPtr *server = fRequest.GetProtocol( "server2" ); if( !server || server->Atoi() < 16 ) return; p4wHtml suffix; StrBuf path; StrBuf icon; StrBufDict cmdArgs; AllCommands lac = fRequest.GetCmd(); StrBuf lacVal; lacVal << (int)lac; int iconSz = 25; const StrPtr *X = fRequest.GetStateArg( "X" ); // undoc eXperimental flags if (X) { if (strchr(X->Text(), '3')) iconSz = 37; else if (strchr(X->Text(), '4')) iconSz = 50; else if (strchr(X->Text(), '6')) iconSz = 75; else if (strchr(X->Text(), '8')) iconSz = 100; } cmdArgs.SetVar( "lac", lacVal ); suffix.endCol(); fRequest.UseNewBase( path, NULL, "path", "/" ); urlMaker.ConstructIcon( icon, "/cancelIcon", iconSz, iconSz, "Cancel operation", 1 ); OutputHREF( NULL, path.Text(), AC_CANCELCMD, &cmdArgs, icon.Text(), suffix.Text() ); } void p4wMenuPane::doLogoutButton() { // // Generate a Logout server request button if // appropriate. if (fRequest.BypassAuth()) return; p4wHtml htm; p4wURL urlMaker; StrBuf clearIcon; urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); // // Exclude this button from pages where // no server command is generated. switch( fRequest.GetCmd() ) { case AC_CANCELCMD: case AC_SUBMITFRM: case AC_FILESMATCHINGFRM: case AC_DELETEJOBCONFIRM: case AC_DELETEBRANCHCONFIRM: case AC_DELETELABELCONFIRM: case AC_REVERTCONFIRM: case AC_HELP: htm.icon( clearIcon.Text(), "25", "25", "", 1 ); htm.endCol(); fRequest << htm; return; default: break; } // // An error page also can't have a logout button if( fView.IsErrorPage() ) { htm.icon( clearIcon.Text(), "25", "25", "", 1 ); htm.endCol(); fRequest << htm; return; } // // Only display this button // if the server supports this functionality. const StrPtr *server = fRequest.GetProtocol( "server2" ); if( !server || server->Atoi() < 18 ) return; p4wHtml suffix; StrBuf path; StrBuf icon; StrBufDict cmdArgs; AllCommands lac = fRequest.GetCmd(); StrBuf lacVal; lacVal << (int)lac; int iconSz = 25; const StrPtr *X = fRequest.GetStateArg( "X" ); // undoc eXperimental flags if (X) { if (strchr(X->Text(), '3')) iconSz = 37; else if (strchr(X->Text(), '4')) iconSz = 50; else if (strchr(X->Text(), '6')) iconSz = 75; else if (strchr(X->Text(), '8')) iconSz = 100; } cmdArgs.SetVar( "lac", lacVal ); cmdArgs.SetVar( "pw", "1" ); suffix.endCol(); fRequest.UseNewBase( path, NULL, "path", "/" ); urlMaker.ConstructIcon( icon, "/logoutIcon", iconSz, iconSz, "Logout from server", 1 ); OutputHREF( NULL, path.Text(), AC_LOGOUT, &cmdArgs, icon.Text(), suffix.Text() ); } int p4wMenuPane::GetOtherUserSubChgMenuShowVals() { int i; for (i = -1; changeSubVal[++i] != AC_DESCRIBE; ) ; int show = 1 << i; for (i = -1; changeSubVal[++i] != AC_GETJOB; ) ; show += 1 << i; for (i = -1; changeSubVal[++i] != AC_SYNCCHANGE; ) ; show += 1 << i; show += 1 << NCHANGESUBOPTS; return show; } int p4wMenuPane::GetLockedBranchMenuShowVals() { int i; for (i = -1; branchSubVal[++i] != AC_BRANCHVIEW; ) ; int show = 1 << i; for (i = -1; branchSubVal[++i] != AC_INTEGRATEBRANCH; ) ; show += 1 << i; for (i = -1; branchSubVal[++i] != AC_BRANCHDIFF; ) ; show += 1 << i; show += 1 << NBRANCHSUBOPTS; return show; } int p4wMenuPane::GetLockedLabelMenuShowVals() { int i; for (i = -1; labelSubVal[++i] != AC_LABELVIEW; ) ; int show = 1 << i; for (i = -1; labelSubVal[++i] != AC_CREATELABELTMP; ) ; show += 1 << i; for (i = -1; labelSubVal[++i] != AC_LABELFILES; ) ; show += 1 << i; for (i = -1; labelSubVal[++i] != AC_LABELFILESTEXT; ) ; show += 1 << i; show += 1 << NLABELSUBOPTS; return show; } void p4wMenuPane::renderSubChgMenu( p4wRequest *fRequest, const char *user ) { p4wHtml htm( 1 ); htm.SetRequest(fRequest); htm.beginUrlMenu(fRequest, "menu_subchg"); *fRequest << htm; htm.Clear(); p4wMenuPane::renderSubChgMenuItem(AC_SUBMITTEDCHANGELISTS, fRequest); htm.SetSepNeeded(1); htm.RenderMenuItem("subchg", AC_CHANGES, 0, 1 << NCHANGESUBOPTS); *fRequest << htm; htm.Clear(); p4wMenuPane::renderSubChgMenuItem(AC_DESCRIBE, fRequest); if (user && !strcmp(user, fRequest->GetUser().Text())) { const StrPtr *server; int protocol = 0; server = fRequest->GetProtocol( "server2" ); if( server ) protocol = server->Atoi(); if( protocol >= 23 ) // 2007.2 or later? p4wMenuPane::renderSubChgMenuItem(AC_EDITCHANGE, fRequest); } htm.SetSepNeeded(1); htm.RenderMenuItem("subchg", AC_CHANGES, 0, 1 << (NCHANGESUBOPTS+1)); *fRequest << htm; htm.Clear(); p4wMenuPane::renderSubChgMenuItem(AC_GETJOB, fRequest); p4wMenuPane::renderSubChgMenuItem(AC_SYNCCHANGE, fRequest); htm.endUrlMenu(); *fRequest << htm; } void p4wMenuPane::renderSubChgMenuItem( AllCommands ac, p4wRequest *fRequest, int buXc ) { char *p; p4wHtml htm; StrBuf locUrl; int i; for (i = -1; changeSubVal[++i] != ac; ) ; htm.SetRequest(fRequest); htm.SetSepNeeded(0); // // Need to determine if the list of // submitted changelists is from file or // path browser in order to determine correct // ac code to pass. if( ac == AC_SUBMITTEDCHANGELISTS ) { AllCommands rt = fRequest->GetLastReturnType(); if( rt == AC_PATHBROWSER ) ac = AC_SUBMITTEDCHANGELISTS; else ac = AC_SUBMITTEDCHANGELISTSFILE; } redirectUrl( ac, locUrl, fRequest ); if (buXc == 2 && (p = strstr(locUrl.Text(), "&sr="))) { *(p+4) = '\0'; locUrl.SetLength(); } htm.renderUrlMenuItem( "subchg", i, changeSubVal[i], locUrl.Text(), changeSubOptsHead[i], strstr(changeSubOptsText[i], "...") ? 1 : 0, 0, 0, buXc); *fRequest << htm; } void p4wMenuPane::renderBranchMenuItem( AllCommands ac, p4wRequest *fRequest, int buXc ) { char *p; p4wHtml htm; StrBuf locUrl; int i; for (i = -1; branchSubVal[++i] != ac; ) ; htm.SetRequest(fRequest); htm.SetSepNeeded(0); redirectUrl( ac, locUrl, fRequest ); htm.renderUrlMenuItem( "branch", i, branchSubVal[i], locUrl.Text(), branchSubOptsHead[i], strstr(branchSubOptsText[i], "...") ? 1 : 0, 0, 0, buXc); *fRequest << htm; } void p4wMenuPane::renderLabelMenuItem( AllCommands ac, p4wRequest *fRequest, int buXc ) { char *p; p4wHtml htm; StrBuf locUrl; int i; for (i = -1; labelSubVal[++i] != ac; ) ; htm.SetRequest(fRequest); htm.SetSepNeeded(0); redirectUrl( ac, locUrl, fRequest ); htm.renderUrlMenuItem( "label", i, labelSubVal[i], locUrl.Text(), labelSubOptsHead[i], strstr(labelSubOptsText[i], "...") ? 1 : 0, 0, 0, buXc); *fRequest << htm; } void p4wMenuPane::renderClientMenuItem( AllCommands ac, p4wRequest *fRequest, int buXc ) { char *p; p4wHtml htm; StrBuf locUrl; int i; for (i = -1; clientSubVal[++i] != ac; ) ; htm.SetRequest(fRequest); htm.SetSepNeeded(0); redirectUrl( ac, locUrl, fRequest ); htm.renderUrlMenuItem( "client", i, clientSubVal[i], locUrl.Text(), clientSubOptsHead[i], strstr(clientSubOptsText[i], "...") ? 1 : 0, 0, 0, buXc); *fRequest << htm; } void p4wMenuPane::renderJobMenuItem( AllCommands ac, p4wRequest *fRequest, int buXc ) { char *p; p4wHtml htm; StrBuf locUrl; int i; for (i = -1; jobSubVal[++i] != ac; ) ; htm.SetRequest(fRequest); htm.SetSepNeeded(0); redirectUrl( ac, locUrl, fRequest ); if (buXc == 2 && (p = strstr(locUrl.Text(), "&jb="))) { *(p+4) = '\0'; locUrl.SetLength(); } htm.renderUrlMenuItem( "job", i, jobSubVal[i], locUrl.Text(), jobSubOptsHead[i], strstr(jobSubOptsText[i], "...") ? 1 : 0, 0, 0, buXc); *fRequest << htm; } void p4wMenuPane::redirectUrl( AllCommands ac, StrBuf &newUrl, p4wRequest *fRequest ) { // // Generate the location url corresponding to the command StrBufDict args; StrBuf newBase; p4wURL urlMaker; int isAbsolute = 0; const StrPtr *bvp = fRequest->GetDynArg( "bv" ); const StrPtr *srp = fRequest->GetDynArg( "sr" ); newUrl.Clear(); switch( ac ) { case AC_SYNCLABEL: case AC_SYNCCHANGE: // // Sync to label or changelist // requires some url mangling to // use the return url for the path and set the sr // variable to the current GetURL() value. if( !fRequest->GetURL().Length() && srp ) args.SetVar( "sr", srp->Text() ); else args.SetVar( "sr", fRequest->GetURL().Text() ); fRequest->UseNewBase( newBase, NULL, "path", fRequest->GetReturnURL( AC_PATHBROWSER ).Text() ); ++isAbsolute; break; case AC_DESCRIBE: if ( (fRequest->GetCmd() == AC_SYNCCHANGE || fRequest->GetCmd() == AC_SYNCPROCESSOR) && !fRequest->GetURL().Length() && srp ) { fRequest->UseNewBase( newBase, NULL, "path", NULL ); newBase << srp; ++isAbsolute; break; } case AC_FIXESCHANGE: case AC_ADDFIX: case AC_ADDFIXPROCESSOR: if( !fRequest->GetURL().Length() && srp ) newBase.Set( srp->Text() ); else newBase.Set( fRequest->GetURL().Text() ); break; case AC_LABELVIEW: case AC_EDITLABEL: case AC_DELETELABELCONFIRM: case AC_LABELFILES: case AC_LABELFILESTEXT: case AC_REPLACELABEL: case AC_CREATELABELTMP: if( srp ) { fRequest->UseNewBase( newBase, NULL, "path", NULL ); newBase << srp; ++isAbsolute; } else { newBase.Set( fRequest->GetURL() ); } break; case AC_SYNCCHANGERNG: { StrBuf sr; sr << fRequest->GetURL() << ","; sr << fRequest->GetURL(); args.SetVar( "sr", sr.Text() ); fRequest->UseNewBase( newBase, NULL, "path", fRequest->GetReturnURL( AC_PATHBROWSER ).Text() ); ++isAbsolute; } break; case AC_INTEGRATEBRANCH: if( !fRequest->GetURL().Length() && bvp ) args.SetVar( "bv", bvp->Text() ); else args.SetVar( "bv", fRequest->GetURL().Text() ); fRequest->UseNewBase( newBase, NULL, "path", fRequest->GetReturnURL( AC_PATHBROWSER ).Text() ); ++isAbsolute; break; case AC_BRANCHVIEW: case AC_EDITBRANCH: case AC_DELETEBRANCHCONFIRM: case AC_BRANCHDIFF: if( bvp ) { fRequest->UseNewBase( newBase, NULL, "path", NULL ); newBase << bvp; ++isAbsolute; } else { newBase.Set( fRequest->GetURL() ); } break; case AC_CREATEJOB: case AC_CREATEBRANCH: case AC_CREATELABEL: case AC_EDITCLIENT: // // Create Job/Branch urls should not have a path // component that may be mistakenly interpreted as // the job or branch names. fRequest->UseNewBase( newBase, NULL, "path", NULL ); ++isAbsolute; break; case AC_LABELSPATH: // // Use the return url for the base path in // the Labels in Path command. { AllCommands rt = fRequest->GetLastReturnType(); StrBuf p; p.Set( fRequest->GetReturnURL( rt ) ); fRequest->UseNewBase( newBase, NULL, "path", p.Text() ); ++isAbsolute; } break; case AC_PATHBROWSER: fRequest->UseNewBase( newBase, NULL, "cdf", NULL ); fRequest->UseNewBase( newBase, newBase.Text(), "path", fRequest->GetReturnURL( AC_PATHBROWSER ).Text() ); ++isAbsolute; break; case AC_GETJOB: ac = AC_JOBS; if( !fRequest->GetURL().Length() && srp ) args.SetVar( "sr", srp->Text() ); else args.SetVar( "sr", fRequest->GetURL().Text() ); case AC_JOBS: case AC_SUBMITTEDCHANGELISTS: case AC_SUBMITTEDCHANGELISTSFILE: { AllCommands rt = fRequest->GetLastReturnType(); StrBuf p; p.Set( fRequest->GetReturnURL( rt ) ); fRequest->UseNewBase( newBase, NULL, "path", p.Text() ); ++isAbsolute; if( ac == AC_JOBS ) args.SetVar( "mx", "25" ); else args.SetVar( "mx", "50" ); } break; case AC_FIXPENDING: { if( fRequest->GetURL().Length() && strcmp( fRequest->GetURL().Text(), "..." ) ) newBase.Set( fRequest->GetURL().Text() ); args.SetVar( "jb", fRequest->GetURL().Text() ); } break; case AC_FIXSUBMITTED: { AllCommands rt = fRequest->GetLastReturnType(); StrBuf p; p.Set( fRequest->GetReturnURL( rt ) ); fRequest->UseNewBase( newBase, NULL, "path", p.Text() ); ++isAbsolute; args.SetVar( "mx", "50" ); args.SetVar( "jb", fRequest->GetURL().Text() ); } break; case AC_LABELS: case AC_BRANCHES: case AC_CONFIGURATION: case AC_SERVERINFO: case AC_P4CMDPANE: fRequest->UseNewBase( newBase, NULL, "path", "/" ); ++isAbsolute; break; case AC_SYNCCMD: if( !fRequest->GetURL().Length() ) newBase.Set( "..." ); else newBase.Set( fRequest->GetURL().Text() ); break; default: if( fRequest->GetURL().Length() && strcmp( fRequest->GetURL().Text(), "..." ) ) newBase.Set( fRequest->GetURL().Text() ); break; } // // Construct the url. Convert relative url to absolute, // complete with the http port as needed by "location". StrBuf tmpUrl; int unicode; // // XXX MSIE needs the utf-8 characters escaped in // location urls. if( fRequest->GetJavascriptMode() == 2 ) unicode = 0; else unicode = fRequest->GetUnicode(); urlMaker.ConstructLocationURL( tmpUrl, newBase.Text(), ac, &args, unicode ); if( isAbsolute ) { newUrl << "\""; if (fRequest->IsHTTPS()) newUrl << "https://"; else newUrl << "http://"; newUrl << fRequest->GetHTTPPort() << tmpUrl; newUrl << "\""; } else { newUrl << "\""; newUrl << p4wStrBuf().NormalizeBase( fRequest->GetBase(), unicode ); newUrl << tmpUrl; newUrl << "\""; } } void p4wMenuPane::diffsMenu( p4wRequest *fRequest ) { if (fRequest->GetStateArg( "thx" )) // CSS disabled? return; const StrPtr *server; int protocol = 0; server = fRequest->GetProtocol( "server2" ); if( server ) protocol = server->Atoi(); if( protocol < 14 ) return; int iconSz = 25; const StrPtr *X = fRequest->GetStateArg( "X" ); // undoc eXperimental flags if (X) { if (strchr(X->Text(), '3')) iconSz = 37; else if (strchr(X->Text(), '4')) iconSz = 50; else if (strchr(X->Text(), '6')) iconSz = 75; else if (strchr(X->Text(), '8')) iconSz = 100; } AllCommands ac = fRequest->GetCmd(); p4wHtml htm(1); htm.SetRequest(fRequest); p4wURL urlMaker; StrBuf clearIcon; urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); StrBuf diffBase; StrBuf diffsUrl; StrBuf diffsText; const StrPtr *dc = fRequest->GetStateArg( "dc" ); const StrPtr *dl = fRequest->GetStateArg( "dl" ); const StrPtr *dw = fRequest->GetStateArg( "dw" ); StrBuf diff; StrBuf dwNew; char oldType = '\0'; if (dw) { diff << dw; char *p = strpbrk( diff.Text(), "ncsuO" ); if (p) { oldType = *p; strcpy(p, p+1); diff.SetLength(); } dw = &diff; } StrBuf path; path.Set( fRequest->GetReturnURL( ac ).Text() ); StrBufDict args; if (ac == AC_DIFFCVH || ac == AC_DIFF2) { const StrPtr *rev1 = fRequest->GetDynArg( "rev1" ); const StrPtr *rev2 = fRequest->GetDynArg( "rev2" ); args.SetVar( "rev1", rev1 ); args.SetVar( "rev2", rev2 ); } StrBuf icon; StrBuf baseNoPath; fRequest->UseNewBase( baseNoPath, NULL, "path", "//" ); urlMaker.ConstructURL( diffsUrl, baseNoPath.Text(), AC_CONFIGURATION, NULL, fRequest->GetUnicode() ); htm.beginCol(); htm << "<script language=javascript>" << crlf; htm << "document.write(\"<a href='javascript:showMenu(\\\""; // any filename would go here htm << "\\\",\\\"toolbasdiffs\\\",\\\"Diffs\\\","; htm << -1; htm << ",\\\""; // any dyn args would go here htm << "\\\")' id='id_toolbasdiffs'>"; htm << "<img src='/menuarrowtoolbarIcon?ac=20' height='"; htm << iconSz; htm << "' width='"; htm << 15 * iconSz/25; htm << "' border='0' alt='' "; htm << "title='Diff options'>"; htm << "</a>\")" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; htm.beginLink( diffsUrl.Text() ); urlMaker.ConstructIcon( icon, "/menuarrowtoolbarIcon", iconSz, 15 * iconSz/25, "", 1 ); htm << icon; htm.endLink(); htm << crlf << "</noscript>" << crlf; htm << crlf; int divctr = 0; htm.beginDiv("menu_Diffs", "mu", "display:none"); htm.beginTable(0, "10"); // wrap menu in a table so MSIE won't make the menu 100% wide htm.beginTRow(); htm.beginCol(0,0,0,0,0,0,0,1); if (dw) dwNew << dw->Text(); fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Two Pane (Full File) "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, !oldType ? "bulletIcon" : NULL); dwNew.Set("\0"); if (dw) dwNew << dw->Text(); dwNew << "c"; fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Two Pane (Context Diffs) "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, ( oldType == 'c' ) ? "bulletIcon" : NULL); StrBuf contextUrl; contextUrl.Set(diffsUrl); dwNew.Set("\0"); if (dw) dwNew << dw->Text(); dwNew << "O"; fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Diffs Only "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, ( oldType == 'O' ) ? "bulletIcon" : NULL); dwNew.Set("\0"); if (dw) dwNew << dw->Text(); dwNew << "n"; fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" RCS "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, ( oldType == 'n' ) ? "bulletIcon" : NULL); dwNew.Set("\0"); if (dw) dwNew << dw->Text(); dwNew << "u"; fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Unified Format "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, ( oldType == 'u' ) ? "bulletIcon" : NULL); dwNew.Set("\0"); if (dw) dwNew << dw->Text(); dwNew << "s"; fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Summary "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, ( oldType == 's' ) ? "bulletIcon" : NULL); htm.SetSepNeeded(1); htm.RenderMenuItem("Diffs", fRequest->GetCmd(), 0, 1 << divctr++); htm << crlf; if( fRequest->GetJavascriptMode() != 2 || fRequest->GetBrowserVersion() >= 7.0) // MSIE 6 is brain dead - skip slideoff { htm.beginDiv("menuDiffs", "menu"); htm << crlf; diffsText.Set(" Context Lines >>"); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), contextUrl.Text(), diffsText.Text()); htm.beginUList(); htm.beginTable( 0, "30%", "2", 0, "#c0c0c0" ); htm.beginTRow( 0, 0, "#e6e6e6" ); htm.beginCol(); *fRequest << htm; htm.Clear(); int i; int b = 0; for (i = 0; i < 10 || (i == 10 && !b); ) b = diffSubmenu( fRequest, i++, ac, dw, path, args ); htm.endCol(); htm.endTRow(); htm.endTable(); htm << " "; htm.endUList(); htm.endDiv(); htm.SetSepNeeded(1); htm.RenderMenuItem("Diffs", fRequest->GetCmd(), 0, 1 << divctr++); htm << crlf; } fRequest->UseNewBase( diffBase, NULL, "dl", NULL ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Wrap Lines Ignoring Tabs "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, !dl ? "bulletIcon" : NULL); fRequest->UseNewBase( diffBase, NULL, "dl", "m" ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Wrap Lines "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, (dl && !strcmp(dl->Text(), "m")) ? "bulletIcon" : NULL); fRequest->UseNewBase( diffBase, NULL, "dl", "n" ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Do Not Wrap Lines "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, (dl && !strcmp(dl->Text(), "n")) ? "bulletIcon" : NULL); htm.SetSepNeeded(1); htm.RenderMenuItem("Diffs", fRequest->GetCmd(), 0, 1 << divctr++); htm << crlf; dw = fRequest->GetStateArg( "dw" ); // reload the dw and start the whitespace treatment char oldWhsp = '\0'; if (dw) { diff.Set(dw); char *p = strpbrk( diff.Text(), "wbl" ); if (p) { oldWhsp = *p; strcpy(p, p+1); diff.SetLength(); } dw = &diff; } dwNew.Set("\0"); if (dw) dwNew << dw->Text(); fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Show All Diffs "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, !oldWhsp ? "bulletIcon" : NULL); dwNew.Set("\0"); if (dw) dwNew << dw->Text(); dwNew << "b"; fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Ignore Whitespace Changes "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, ( oldWhsp == 'b') ? "bulletIcon" : NULL); dwNew.Set("\0"); if (dw) dwNew << dw->Text(); dwNew << "w"; fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Ignore All Whitespace "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, ( oldWhsp == 'w') ? "bulletIcon" : NULL); if (protocol > 16) { dwNew.Set("\0"); if (dw) dwNew << dw->Text(); dwNew << "l"; fRequest->UseNewBase( diffBase, NULL, "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); diffsText.Set(" Ignore Line Endings "); htm.renderUrlMenuItem("Diffs", divctr++, fRequest->GetCmd(), diffsUrl.Text(), diffsText.Text(), 0, ( oldWhsp == 'l') ? "bulletIcon" : NULL); } htm.endCol(); htm.endTRow(); htm.endTable(); htm.endDiv(); htm.endCol(); *fRequest << htm; } int p4wMenuPane::diffSubmenu( p4wRequest *fRequest, int i, AllCommands ac, const StrPtr *dw, StrBuf & path, StrBufDict & args ) { static int ctxt[11] = { 1, 5, 10, 15, 20, 25, 35, 50, 70, 95, 0 }; p4wHtml htm(1); p4wURL urlMaker; int rc; StrNum iStr; StrBuf diffBase; StrBuf diffsUrl; StrBuf diffsText; const StrPtr *dc = fRequest->GetStateArg( "dc" ); StrBuf dwNew; if (dw) dwNew << dw->Text(); dwNew << "c"; if (i == 10) { if (dc) ctxt[10] = atoi(dc->Text()); else return 0; } iStr.Set(ctxt[i]); fRequest->UseNewBase( diffBase, NULL, "dc", ctxt[i]==15 ? NULL : iStr.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "dw", dwNew.Text() ); fRequest->UseNewBase( diffBase, diffBase.Text(), "path", path.Text() ); urlMaker.ConstructURL( diffsUrl, diffBase.Text(), ac, &args, fRequest->GetUnicode() ); if ((!dc && ctxt[i]==15) || (dc && !strcmp(dc->Text(), iStr.Text()))) { htm << " <li class=\"bullet\">"; rc = 1; } else { htm << " <li>"; rc = 0; } if (i == 10) { diffsText.Set("Other"); } else { diffsText.Set(" "); if (ctxt[i] < 10) diffsText << " "; diffsText << iStr << " "; } htm.beginLink( diffsUrl.Text() ); htm << diffsText; htm.endLink(); htm << "</li>" << crlf; *fRequest << htm; return rc; } void p4wMenuPane::listviewIcons( p4wRequest *fRequest, AllCommands cmd ) { p4wHtml htm(1); p4wURL urlMaker; StrBuf icon; StrBuf clearIcon; StrBuf grayIcon; urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); urlMaker.ConstructURL( grayIcon, "/grayPixelIcon", AC_ICON, NULL ); int iconSz = 25; const StrPtr *X = fRequest->GetStateArg( "X" ); // undoc eXperimental flags if (X) { if (strchr(X->Text(), '3')) iconSz = 37; else if (strchr(X->Text(), '4')) iconSz = 50; else if (strchr(X->Text(), '6')) iconSz = 75; else if (strchr(X->Text(), '8')) iconSz = 100; } StrBuf reqURL; StrBuf thumbnailAC; StrBuf thumbnailBase; StrBuf thumbnailsUrl; StrBuf thumbnailsText; StrBuf thumbnailsTitle; const StrPtr *thz = fRequest->GetStateArg( "thz" ); const StrPtr *thm = fRequest->GetStateArg( "thm" ); const StrPtr *thb = fRequest->GetStateArg( "thb" ); const StrPtr *thx = fRequest->GetStateArg( "thx" ); const StrPtr *thw = fRequest->GetStateArg( "thw" ); const StrPtr *thv = fRequest->GetStateArg( "thv" ); reqURL << fRequest->GetURL(); if (!strcmp(reqURL.Text(), "...")) reqURL.Set(""); char buf[16]; sprintf(buf, "?ac=%d", cmd); thumbnailAC << buf; fRequest->UseNewBase( thumbnailBase, NULL, "rt", NULL ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", NULL ); thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); thumbnailsTitle.Set("Display "); if (cmd == AC_BROWSEFILE ) thumbnailsTitle << "revision history"; else { thumbnailsTitle << (fRequest->GetViewMode() == VM_WORKSPACE ? "workspace tree" : "depot tree"); thumbnailsTitle << " list"; } urlMaker.ConstructIcon( icon, fRequest->HideThumbnails() && fRequest->HideDetails() ? "/list_icon_onIcon" : "/list_icon_offIcon", iconSz, iconSz, thumbnailsTitle.Text(), 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( thumbnailsUrl.Text() ); htm << icon; htm.endLink(); htm.endCol(); thumbnailsUrl.Clear(); fRequest->UseNewBase( thumbnailBase, NULL, "rt", "s" ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", "d" ); thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); thumbnailsTitle.Set("Display "); if (cmd == AC_BROWSEFILE ) thumbnailsTitle << "revision history"; else { thumbnailsTitle << (fRequest->GetViewMode() == VM_WORKSPACE ? "workspace tree" : "depot tree"); thumbnailsTitle << " details"; } urlMaker.ConstructIcon( icon, !fRequest->HideDetails() ? "/details_icon_onIcon" : "/details_icon_offIcon", iconSz, iconSz, thumbnailsTitle.Text(), 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( thumbnailsUrl.Text() ); htm << icon; htm.endLink(); htm.endCol(); thumbnailsUrl.Clear(); fRequest->UseNewBase( thumbnailBase, NULL, "rt", "s" ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", NULL ); thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); thumbnailsTitle.Set("Display "); if (cmd == AC_BROWSEFILE ) thumbnailsTitle << "revision history"; else thumbnailsTitle << (fRequest->GetViewMode() == VM_WORKSPACE ? "workspace tree" : "depot tree"); thumbnailsTitle << " thumbnails"; urlMaker.ConstructIcon( icon, !fRequest->HideThumbnails() ? "/thumbnails_icon_onIcon" : "/thumbnails_icon_offIcon", iconSz, iconSz, thumbnailsTitle.Text(), 1 ); htm.beginCol( NULL, NULL, NULL, NULL, NULL, "25" ); htm.beginLink( thumbnailsUrl.Text() ); htm << icon; htm.endLink(); htm.endCol(); if (!fRequest->GetStateArg( "thx" )) // CSS enabled? { StrBuf configureURL; htm.beginCol( NULL, NULL, NULL, NULL, NULL, "13" ); StrBuf baseNoPath; fRequest->UseNewBase( baseNoPath, NULL, "path", "//" ); urlMaker.ConstructURL( thumbnailsUrl, baseNoPath.Text(), AC_CONFIGURATION, NULL, fRequest->GetUnicode() ); urlMaker.ConstructIcon( icon, "/menuarrowtoolbarIcon", 25, 15, "", 1 ); configureURL << thumbnailsUrl; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<a href='javascript:showMenu(\\\""; // any filename would go here htm << "\\\",\\\"toolbarthumbs\\\",\\\"Thumbs\\\","; htm << -1; htm << ",\\\""; // any dyn args would go here htm << "\\\")' id='id_toolbarthumbs'>"; htm << "<img src='/menuarrowtoolbarIcon?ac=20' height='"; htm << iconSz; htm << "' width='"; htm << 15 * iconSz/25; htm << "' border='0' alt='' "; htm << "title='Thumbnail options'>"; htm << "</a>\")" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; htm.beginLink( thumbnailsUrl.Text() ); htm << icon; htm.endLink(); htm << crlf << "</noscript>" << crlf; htm << crlf; int divctr = 0; htm.SetRequest(fRequest); htm.beginDiv("menu_Thumbs", "mu", "display:none"); htm.beginTable(0, "10"); // wrap menu in a table so MSIE won't make the menu 100% wide htm.beginTRow(); htm.beginCol(0,0,0,0,0,0,0,1); fRequest->UseNewBase( thumbnailBase, NULL, "thz", NULL ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", NULL ); if( fRequest->HideThumbnails() ) fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "rt", "s" ); thumbnailsText.Set(" Large 160x160"); thumbnailsUrl.Clear(); thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); htm.renderUrlMenuItem("Thumbs", divctr++, fRequest->GetCmd(), thumbnailsUrl.Text(), thumbnailsText.Text(), 0, !thz ? "bulletIcon" : NULL); fRequest->UseNewBase( thumbnailBase, NULL, "thz", "m" ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", NULL ); if( fRequest->HideThumbnails() ) fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "rt", "s" ); thumbnailsText.Set(" Medium 120x120"); thumbnailsUrl.Clear(); thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); htm.renderUrlMenuItem("Thumbs", divctr++, fRequest->GetCmd(), thumbnailsUrl.Text(), thumbnailsText.Text(), 0, ( thz && *thz == "m" ) ? "bulletIcon" : NULL); fRequest->UseNewBase( thumbnailBase, NULL, "thz", "s" ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", NULL ); if( fRequest->HideThumbnails() ) fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "rt", "s" ); thumbnailsText.Set(" Small 80x80"); thumbnailsUrl.Clear(); thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); htm.renderUrlMenuItem("Thumbs", divctr++, fRequest->GetCmd(), thumbnailsUrl.Text(), thumbnailsText.Text(), 0, ( thz && *thz == "s" ) ? "bulletIcon" : NULL); htm.SetSepNeeded(1); htm.RenderMenuItem("Thumbs", fRequest->GetCmd(), 0, 1 << divctr++); htm << crlf; if( fRequest->GetJavascriptMode() != 2 || fRequest->GetBrowserVersion() >= 7.0) // MSIE 6 is brain dead - skip slideoff { htm.beginDiv("menuThumbs", "menu"); htm << crlf; thumbnailsUrl.Set(configureURL); thumbnailsText.Clear(); if (thw) thumbnailsText << " Columns (Minimum No.) >></a>"; else thumbnailsText << " Columns >></a>"; htm.renderUrlMenuItem("Thumbs", divctr++, fRequest->GetCmd(), thumbnailsUrl.Text(), thumbnailsText.Text()); htm.beginUList(); htm.beginTable( 0, "30%", "2", 0, "#c0c0c0" ); htm.beginTRow( 0, 0, "#e6e6e6" ); htm.beginCol(); *fRequest << htm; htm.Clear(); int i; for (i = 0; i < 10; ) thumbnailSubmenu( fRequest, ++i, thumbnailAC, reqURL ); htm.endCol(); htm.endTRow(); htm.endTable(); htm << " "; htm.endUList(); htm.endDiv(); } fRequest->UseNewBase( thumbnailBase, NULL, "thw", thw ? NULL : "y" ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", NULL ); if( fRequest->HideThumbnails() ) fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "rt", "s" ); thumbnailsText.Set(" Autowrap Thumbnails "); thumbnailsUrl.Clear(); thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); htm.renderUrlMenuItem("Thumbs", divctr++, fRequest->GetCmd(), thumbnailsUrl.Text(), thumbnailsText.Text(), 0, thw ? "checkmarkIcon" : NULL); htm.SetSepNeeded(1); htm.RenderMenuItem("Thumbs", fRequest->GetCmd(), 0, 1 << divctr++); htm << crlf; fRequest->UseNewBase( thumbnailBase, NULL, "thm", thm ? NULL : "y" ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", NULL ); if( fRequest->HideThumbnails() ) fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "rt", "s" ); thumbnailsText.Set(" Magnify Small Images "); thumbnailsUrl.Clear(); thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); htm.renderUrlMenuItem("Thumbs", divctr++, fRequest->GetCmd(), thumbnailsUrl.Text(), thumbnailsText.Text(), 0, thm ? "checkmarkIcon" : NULL); fRequest->UseNewBase( thumbnailBase, NULL, "thb", thb ? NULL : "y" ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", NULL ); if( fRequest->HideThumbnails() ) fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "rt", "s" ); thumbnailsText.Set(" Show Borders"); thumbnailsUrl.Clear(); thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); htm.renderUrlMenuItem("Thumbs", divctr++, fRequest->GetCmd(), thumbnailsUrl.Text(), thumbnailsText.Text(), 0, thb ? "checkmarkIcon" : NULL); htm.endCol(); htm.endTRow(); htm.endTable(); htm.endDiv(); htm.endCol(); } *fRequest << htm; } void p4wMenuPane::thumbnailSubmenu( p4wRequest *fRequest, int i, StrBuf & thumbnailAC, StrBuf & reqURL ) { p4wHtml htm(1); p4wURL urlMaker; StrNum iStr; StrBuf thumbnailBase; StrBuf thumbnailsUrl; StrBuf thumbnailsText; const StrPtr *thc = fRequest->GetStateArg( "thc" ); iStr.Set(i); fRequest->UseNewBase( thumbnailBase, NULL, "thc", i==4 ? NULL : iStr.Text() ); fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "thv", NULL ); if( fRequest->HideThumbnails() ) fRequest->UseNewBase( thumbnailBase, thumbnailBase.Text(), "rt", "s" ); if ((!thc && i==4) || (thc && !strcmp(thc->Text(), iStr.Text()))) htm << " <li class=\"bullet\">"; else htm << " <li>"; thumbnailsText.Set(" "); if (i < 10) thumbnailsText << " "; thumbnailsText << iStr << " "; thumbnailsUrl << thumbnailBase << reqURL << thumbnailAC; thumbnailsUrl.Set( p4wStrBuf().EscapeURL( thumbnailsUrl, fRequest->GetUnicode() ) ); htm.beginLink( thumbnailsUrl.Text() ); htm << thumbnailsText; htm.endLink(); htm << "</li>" << crlf; *fRequest << htm; } void p4wMenuPane::OutputIcon( p4wRequest *fRequest, const char *iconName, int height, int width ) { // // Output the named icon using specified characteristics StrBuf icon; p4wURL urlMaker; urlMaker.ConstructIcon( icon, iconName, height, width, "", 0 ); *fRequest << icon; }
# | 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/p4wMenuPane.cpp | |||||
#1 | 8914 | Matt Attaway | Initial add of the P4Web source code |