// // Copyright 2001 Perforce Software. All rights reserved. // // This file is part of Perforce - the FAST SCM System. // // p4wJobsPane: // List of jobs with a form to change filter and/or // max number of jobs to display #include <p4wp4.h> #include "p4wStrBuf.h" #include "p4wHtml.h" #include "p4wPane.h" #include "p4wJobsPane.h" p4wJobsPane::p4wJobsPane( p4wView & ParentView, p4wRequest & Request ) : p4wPane( ParentView, Request ), fSeenBegin(0), fGotSpec(0), fSeenData(0), fRowCtr(0), fJobCtr(0) { } p4wJobsPane::~p4wJobsPane() { } void p4wJobsPane::Begin() { // // Generate the title p4wHtml htm(1); p4wURL urlMaker; StrBuf grayIcon; StrBuf clearIcon; // // Used to generate a line underneath the title, and // some vertical whitespace urlMaker.ConstructURL( grayIcon, "/grayPixelIcon", AC_ICON, NULL ); urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); htm.comment( "BEGIN JOBS PANE" ); if (fRequest.GetScreenChunks() & SCRN_TITLE) { // Output the title const StrPtr *pcl = fRequest.GetDynArg( "pcl" ); const StrPtr *sr = fRequest.GetDynArg( "sr" ); htm.beginTRow(); htm.beginCol(); htm.beginTable( "0", "100%", "0", "0" ); htm.beginTRow(); htm.beginCol(0,0,0,0,0,0,0,1); htm.beginSpan( "title" ); if (pcl && pcl->Length()) { if (*pcl == "new") htm << "Select Job to Add to Default Changelist"; else { htm << "Select Job to Add to Changelist "; htm << pcl->Text(); } } else if (sr && sr->Length()) { htm << "Select Job to Add to Changelist "; htm << sr->Text(); } else { htm << "Jobs:"; } htm.endSpan(); htm.endCol(); htm.endTRow(); htm.endTable(); htm.endCol(); htm.endTRow(); // // Generate line underneath the title htm.beginTRow(); htm.beginCol( "top" ); htm.icon( clearIcon.Text(), "2", "1", "", 1 ); htm.linebreak(); htm.icon( grayIcon.Text(), "1", "100%", "", 1, "0", "0" ); htm.endCol(); htm.endTRow(); } fRequest << htm; } void p4wJobsPane::ConstructLocationURL( p4wStrBuf *jobURL ) { p4wURL urlMaker; StrBufDict args; const char *path = NULL; const StrPtr *mx = fRequest.GetDynArg( "mx" ); if( mx && mx->Length() ) args.SetVar( "mx", mx ); const StrPtr *pcl = fRequest.GetDynArg( "pcl" ); if ( pcl && pcl->Length() ) args.SetVar( "pcl", pcl ); const StrPtr *sr = fRequest.GetDynArg( "sr" ); if ( sr && sr->Length() ) args.SetVar( "sr", sr ); const StrPtr *ft = fRequest.GetDynArg( "ft" ); if( ft && ft->Length() ) args.SetVar( "ft", ft ); const StrPtr *jasc = fRequest.GetDynArg( "jasc" ); if( jasc && *jasc == "lo" ) args.SetVar( "jasc", "1" ); const StrPtr *jfp = fRequest.GetDynArg( "jfp" ); if( jfp ) args.SetVar( "jfp", "1" ); const StrPtr *jin = fRequest.GetDynArg( "jin" ); if( jin ) args.SetVar( "jin", "1" ); int i; StrPtr *s; for( i = 0; ( s = (StrPtr *)fRequest.GetDynArg( "jsf", i ) ) != NULL; i++ ) args.SetVar( "jsf", i, *s ); if( fRequest.GetURL().Length() ) path = fRequest.GetURL().Text(); urlMaker.ConstructLocationURL( *jobURL, path, AC_RSSJOBS, &args, fRequest.GetUnicode() ); *jobURL << RSSEXT; } void p4wJobsPane::Render( StrDict * varList ) { // // The first row of data contains the spec definition // with the field names. fSeenData = 1; SpecElem *se; StrPtr *specString = varList->GetVar( StrRef("specdef") ); if( specString != NULL ) { Error e; fJobSpec.Decode( specString, &e ); ++fGotSpec; } // // Decide if we can output this job. If the page is // too big or the spec definition is missing we have // to bail out. if( PageLimitExceeded() || !fGotSpec ) return; // // Generate the form, start the table and output the // field names if we haven't already. We can't do this // earlier because the field names come with the data. p4wHtml htm; p4wURL urlMaker; StrBuf clearIcon; StrBuf grayIcon; int nCols; // // Used to generate some vertical whitespace and the // line under the table headings urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); urlMaker.ConstructURL( grayIcon, "/grayPixelIcon", AC_ICON, NULL ); if( !fSeenBegin) { // // Generate the Job filter box ++fSeenBegin; doSubmitButton(); // // Start the table of jobs nCols = fJobSpec.Count() * 2 + 1; StrBuf cspan; cspan << nCols; htm.beginTRow(); htm.beginCol(); htm.icon( clearIcon.Text(), "6", "1", "", 1 ); htm.endCol(); htm.endTRow(); htm.beginTRow(); htm.beginCol(); htm.beginTable( "0", "100%", "0", "1", "#7F7F7F" ); htm.beginTRow( NULL, NULL, "#FFFFFF" ); htm.beginCol(); // build JS column chooser menu StrBuf extra; // if no cols gicen, this holds default cols SpecElem *se; int code; int i; htm.beginUrlMenu(&fRequest, "menu_jobcols"); if (!fRequest.GetDynArg( "jsf", 0 )) // no cols given already? { // then add in default cols for( i = 0; i < fJobSpec.Count(); i++ ) { se = fJobSpec.Get( i ); code = se->code; if (code > 105) continue; extra << "&jsf=" << se->tag.Text(); } } for( i = 0; i < fJobSpec.Count(); i++ ) { se = fJobSpec.Get( i ); code = se->code; int bHidden; StrBuf url; url << "?ac=" << AC_SHOWHIDEJOBCOLS; if (bHidden = isHiddenField( se->tag.Text(), code )) url << "&show="; else url << "&hide="; url << se->tag.Text() << extra; StrBuf label; label << " " << se->tag.Text(); htm.renderUrlMenuItem( "jobcols", i, AC_SHOWHIDEJOBCOLS, url.Text(), label.Text(), 0, bHidden ? NULL : "checkmarkIcon", 0, 0); } htm.endUrlMenu(); // build jobs table htm.beginTable( "0", "100%", "0", "0", "#FFFFFF" ); htm.beginTRow( NULL, NULL, "#EEEEEE" ); const StrPtr *thx = fRequest.GetStateArg( "thx" ); const StrPtr *X = fRequest.GetStateArg("X"); if ((!X || !strchr(X->Text(), 'j')) && !thx && (fRequest.GetScreenChunks() & SCRN_FILTER)) { StrBuf showhideIcon; urlMaker.ConstructURL( showhideIcon, "/showhideIcon", AC_ICON, NULL ); StrBuf shURL; urlMaker.ConstructURL( shURL, fRequest.GetBase().Text(), AC_SHOWHIDEJOBCOLS, NULL, fRequest.GetUnicode() ); htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<th style='border-right: 1px solid #7F7F7F; width: 17px;'>"; htm << "<a href='javascript:showMenu(\\\""; // any filename would go here htm << "\\\",\\\"jcols\\\",\\\"jobcols\\\","; htm << -1; htm << ",\\\"\\\")' id='id_jcols' title ='Visible fields'>"; htm << "<img src='showhideIcon?ac=20' height='17' width='17' border='0' alt='' align=absmiddle title=''>"; htm << "</a>\")" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.beginColHead(); htm.icon( clearIcon.Text(), "17", "13", "", 1 ); if ((!X || !strchr(X->Text(), 'j')) && !thx) htm << "</noscript>" << crlf; htm.endColHead(); int colCtr = 1; // // Generate table headings, skip hidden fields for( i = 0; i < fJobSpec.Count(); i++ ) { se = fJobSpec.Get( i ); if( isHiddenField( fJobSpec.Get( i )->tag.Text(), se->code ) ) continue; htm.beginColHead( NULL, "left" ); if (!i && (!X || !strchr(X->Text(), 'j')) && !thx) { htm << "<script language=javascript>" << crlf; htm << "document.write(\" \")"; htm << "</script>"; } htm.text( fJobSpec.Get( i )->tag.Text() ); htm.endColHead(); htm.beginColHead( NULL, NULL, NULL, NULL, "#EEEEEE" ); htm.icon( clearIcon.Text(), "0", "12", "", 1 ); htm.endColHead(); colCtr += 2; } htm.endTRow(); fColCtrStr << colCtr; htm.beginTRow(); htm.beginCol( "top", NULL, cspan.Text(), NULL, NULL, NULL, "5" ); htm.icon( grayIcon.Text(), "1", "100%", "", 1, "0", "0" ); htm.endCol(); htm.endTRow(); } // // Generate the job table entry StrBuf jobURL; StrBuf newBase; fRequest.UseNewBase( newBase, NULL, "path", NULL ); htm.beginTRow( "top", 0, 0, (fRowCtr & 0x01) ? "list_row alt_row" : "list_row" ); htm.beginCol(); htm.endCol(); const StrPtr *pcl = fRequest.GetDynArg( "pcl" ); const StrPtr *sr = fRequest.GetDynArg( "sr" ); for( int j = 0; j < fJobSpec.Count(); j++ ) { // // Skip hidden fields se = fJobSpec.Get( j ); if( isHiddenField( se->tag.Text(), se->code ) ) continue; StrPtr *value = varList->GetVar( se->tag ); htm.beginCol(0,0,0,0,0,0,0, se->code == 101 ? 1 : 0); if( !value ) { htm.icon( clearIcon.Text(), "0", "50", "", 1 ); htm.endCol(); htm.beginCol(); htm.icon( clearIcon.Text(), "0", "12", "", 1 ); htm.endCol(); continue; } const char *field = value->Text(); if( se->code == 101 ) { // // Job number is a link to the // job view page. // // If job name is enclosed in quotes strip them out StrBuf jobName; int len = strlen( field ); if( *field == '"' && ( *( field + len - 1 ) == '"' ) ) jobName.Set( field + 1, len - 2 ); else jobName.Set( field ); if (pcl && pcl->Length()) { StrBufDict cmdArgs; if (*pcl != "new") cmdArgs.SetVar( "arg", pcl ); cmdArgs.SetVar( "jb", jobName ); urlMaker.ConstructURL( jobURL, newBase.Text(), AC_CHANGEPENDINGEDIT, &cmdArgs, fRequest.GetUnicode() ); } else if (sr && sr->Length()) { StrBufDict cmdArgs; newBase << sr; cmdArgs.SetVar( "jb", jobName ); urlMaker.ConstructURL( jobURL, newBase.Text(), AC_ADDFIX, &cmdArgs, fRequest.GetUnicode() ); } else { newBase << jobName; urlMaker.ConstructURL( jobURL, newBase.Text(), AC_JOBVIEW, NULL, fRequest.GetUnicode() ); } htm.beginLink( jobURL.Text() ); htm.text( p4wStrBuf().EscapeHTML( StrRef( field ), Unicode() ).Text() ); htm.endLink(); if (!pcl && !sr) { htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<span class='muaro'><a href='javascript:showMenu(\\\""; htm << p4wStrBuf().EscapeHTML( StrRef( field ), Unicode() ).Text(); htm << "\\\",\\\"m"; htm << fJobCtr; htm << "\\\",\\\"job\\\","; htm << -1; htm << ",\\\"\\\")' id='id_m"; htm << fJobCtr++; htm << "' title ='Menu'>"; htm << " "; htm << "</a></span>"; htm << "\")" << crlf; htm << "</script>" << crlf; } } else if( se->IsDate() ) { // // Truncate the min:sec from any date // fields if found const char *end = strchr( field, ' ' ); if( !end ) end = strchr( field, '\0' ); StrRef Date( field, end - field ); htm << Date; } else if( se->IsText() ) { // // Truncate text fields to a fixed length int mLen = 50; StrBuf tField; if( value->Length() > mLen ) { char *s = value->Text(); // // Make sure we break on a legal character // if this is a unicode installation if( GlobalCharSet::Get() != 0 ) { char *p = s + value->Length(); int i = 0; CharStep *ss = CharStep::Create( s, GlobalCharSet::Get() ); while( ( ss->Next() < p ) && ( ++i < mLen ) ); mLen = ss->Ptr() - s; delete ss; } tField.Set( s, mLen ); tField << "..."; } else { tField.Set( field ); } htm << p4wStrBuf().EscapeHTML( tField, Unicode() ); } else { htm << field; } htm.endCol(); htm.beginCol(); htm.icon( clearIcon.Text(), "0", "12", "", 1 ); htm.endCol(); } htm.endTRow(); // // Vertical space between rows htm.beginTRow( 0, 0, 0, (fRowCtr++ & 0x01) ? "alt_row b" : "b" ); htm.beginCol( 0, 0, "100%" ); htm.icon( clearIcon.Text(), "3", "1", "", 1 ); htm.endCol(); htm.endTRow(); fRequest << htm; } void p4wJobsPane::End() { // // End the tables and provide // a note to bookmark with an url to the bookmark // help, and end the pane. StrBuf helpURL; StrBuf newBase; p4wURL urlMaker; p4wHtml htm; StrBuf clearIcon; // // Used to generate some vertical whitespace urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); if( !fSeenData && !fRequest.fHadPasswordError ) { doSubmitButton(); htm.beginTRow(); htm.beginCol(); htm.text( "No jobs found." ); htm.endCol(); htm.endTRow(); fRequest << htm; htm.Clear(); } if( fSeenBegin ) { htm.endTable(); htm.endCol(); htm.endTRow(); htm.endTable(); htm.endCol(); htm.endTRow(); fRequest << htm; htm.Clear(); } // // Generate a reminder to use a bookmark to save // this form with a link to bookmark help. If no jobs // were found, instead generate a hint to use the back // button to change visible fields. fRequest.UseNewBase( newBase, NULL, "path", "/tips" ); urlMaker.ConstructURL( helpURL, newBase.Text(), AC_HELP, NULL, fRequest.GetUnicode() ); helpURL << "#bookmarks"; htm.beginTRow(); htm.beginCol(); htm.icon( clearIcon.Text(), "10", "0", "", 1 ); htm.endCol(); htm.endTRow(); if (fRequest.GetScreenChunks() & SCRN_FILTER) { if( fSeenBegin ) { htm.beginTRow(); htm.beginCol( NULL, NULL, "3" ); htm.text( "Save these preferences with a " ); htm.beginLink( helpURL.Text() ); htm << "bookmark."; htm.endLink(); htm.endCol(); htm.endTRow(); } else if ( !fRequest.fHadPasswordError ) { htm.beginTRow(); htm.beginCol( NULL, NULL, "3" ); htm.text( "Please re-try your request." ); htm.endCol(); htm.endTRow(); } } // // End the pane. htm.endForm(); htm.comment( "END JOBS PANE" ); fRequest << htm; } void p4wJobsPane::doSubmitButton() { if (!(fRequest.GetScreenChunks() & SCRN_FILTER)) return; // // Generate form to give user options to choose the max number of // jobs, jobs filter, view in ascending order (default is reverse), // jobs fixed in path, and jobs including integrations. const StrPtr *mx = fRequest.GetDynArg( "mx", HE_Page ); const StrPtr *ft = fRequest.GetDynArg( "ft", HE_Page ); const StrPtr *jasc = fRequest.GetDynArg( "jasc", HE_Page ); const StrPtr *jfp = fRequest.GetDynArg( "jfp", HE_Page ); const StrPtr *jin = fRequest.GetDynArg( "jin", HE_Page ); const StrPtr *pcl = fRequest.GetDynArg( "pcl", HE_Page ); const StrPtr *sr = fRequest.GetDynArg( "sr", HE_Page ); p4wHtml htm; p4wURL urlMaker; StrBuf actionURL; StrBuf path; StrBuf clearIcon; // // Used to generate some whitespace urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); // // Some browsers will truncate the path from the BASE // if the path does not end in a forward slash. So if // we're in workspace mode, use the full path as a precaution. if( fRequest.GetViewMode() == VM_WORKSPACE ) fRequest.UseNewBase( path, NULL, "path", fRequest.GetPath().Text() ); else path << fRequest.GetURL(); StrBufDict args; if (pcl && pcl->Length()) args.SetVar( "pcl", pcl ); else if (sr && sr->Length()) args.SetVar( "sr", sr ); fRequest.ConstructSafeURL( actionURL, path.Text(), AC_JOBSPROCESSOR, &args ); htm.beginTRow(); htm.beginCol(); htm.beginTable(0, 0, "0", "0"); htm.beginTRow(); fRequest << htm; htm.Clear(); StrBuf filtermsg; doFilterMessage(&filtermsg); fRequest.doShowHideBlock(SH_JOBS, "jobs filter", "Jobs Filter", filtermsg.Text()); htm.endCol(); htm.endTRow(); // // Generate the job filter // // Start a DIV for showing/hiding the filter htm.beginTRow(); htm.beginCol(); htm << "<script language=javascript>" << crlf; htm << "document.write(\"<div id='showhideBlock'>\")" << crlf; htm << "</script>" << crlf; htm.beginTable(0, "100%", "0", "0"); htm.beginTRow(); htm.beginCol(); if( fRequest.GetJavascriptMode() != 2) htm.icon( clearIcon.Text(), "5", "1", "", 1 ); htm.beginForm( actionURL.Text() ); htm.beginTable( "0", "100%", "2", "0", "#FFFFFF" ); htm.beginTRow(); htm.beginCol(0,0,0,"100%"); htm.icon( clearIcon.Text(), "1", "14", "", 1 ); htm.endCol(); htm.beginCol( "top" ); htm.label( "Jobview:", "Filter" ); htm.endCol(); htm.beginCol( "top" ); if( ft ) htm.textField( "Filter", ft->Text(), 75, "Filter" ); else htm.textField( "Filter", NULL, 75, "Filter" ); htm.endCol(); htm.beginCol(); htm.icon( clearIcon.Text(), "1", "10", "", 1 ); htm.endCol(); htm.beginCol( NULL, NULL, "100%", 0, 0, "100%" ); htm.beginSelect( "Asc" ); htm.selectOpt( jasc ? 0 : 1, "hi" ); htm.text( "Show highest" ); htm.selectOpt( jasc ? 1 : 0, "lo" ); htm.text( "Show lowest" ); htm.endSelect(); if( mx ) htm.textField( "Max", mx->Text(), 3, "Max" ); else htm.textField( "Max", NULL, 3, "Max" ); htm.label( " jobs", "Max" ); htm.endCol(); htm.endTRow(); htm.beginTRow(); htm.beginCol(); htm.icon( clearIcon.Text(), "1", "3", "", 1 ); htm.endCol(); htm.endTRow(); htm.beginTRow(); htm.beginCol("top", 0, "2", 0,0,0,0, 1); if( jfp ) htm.checkbox( "Fp", "checked", 1 ); else htm.checkbox( "Fp", "checked" ); htm.label( "Include only jobs with fixes in current path", "Fp" ); // Show include integrated fixes checkbox unless -sh was given if (!SEC_DISALLOW_REVHIST_INTEG || fRequest.isLocalRequest()) { htm << " "; htm.checkbox( "Integ", "checked", jin ? 1 : 0, "if (this.checked) document.getElementById('Fp').checked = true" ); htm.label( "Also include integrated fixes", "Integ" ); } fRequest << htm; htm.Clear(); if( fSeenBegin ) { doShowChoices(); } else { htm.beginCol(0,0,0,"2"); const StrPtr *p; for( int i = 0; ( p = fRequest.GetDynArg( "jsf", i ) ) != NULL; i++ ) { htm.hiddenField( "Jsf", p->Text() ); } htm.endCol(); } htm.endTRow(); htm.beginTRow(); htm.beginCol( "bottom", 0, "2" ); htm.beginLink( NULL, "jobsOptions" ); htm.button( "Show", "Filter" ); htm.endLink(); htm.beginLink( NULL, "jobsOptions" ); htm.button( "Clear", "Reset Defaults" ); htm.endLink(); htm.endCol(); htm.endTRow(); htm.beginTRow(); htm.beginCol(); htm.icon( clearIcon.Text(), "5", "1", "", 1 ); htm.endCol(); htm.endTRow(); htm.endTable(); StrBuf grayIcon; urlMaker.ConstructURL( grayIcon, "/grayPixelIcon", AC_ICON, NULL ); htm.icon( grayIcon.Text(), "1", "100%", "", 1, "0", "0" ); htm.endCol(); htm.endTRow(); htm.endTable(); htm << "<script language=javascript>" << crlf; htm << "document.write(\"</div>\")" << crlf; htm << "</script>" << crlf; fRequest << htm; } void p4wJobsPane::doShowChoices() { // Alan finds this method really useful and would not like to see it changed // to the new show/hide popup dialog. So keep this around as a "X" option. const StrPtr *thx = fRequest.GetStateArg( "thx" ); const StrPtr *X = fRequest.GetStateArg("X"); int hideshowmenu = (!X || !strchr(X->Text(), 'j') && !thx) ? 1 : 0; // 1 -> use menu, 0 -> use select // // Allow user to select fields to show SpecElem *se; int code; p4wHtml htm; p4wURL urlMaker; StrBuf clearIcon; urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); htm.beginCol( 0,0,0,"2" ); htm.endCol(); htm.beginCol( "top",0,0,"2",0,0,0,1 ); if (hideshowmenu) { htm << "<script language=javascript>" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; } htm.text( "Visible fields:" ); if (hideshowmenu) htm << "</noscript>" << crlf; htm.endCol(); htm.beginCol( "top",0,0,"2",0,0,0,1 ); if (hideshowmenu) { StrBuf extra; // if no cols gicen, this holds default cols if ( !fRequest.GetDynArg( "jsf", 0 ) ) { for( int i = 0; i < fJobSpec.Count(); i++ ) { se = fJobSpec.Get( i ); code = se->code; if (code <= 105) extra << "&jsf=" << se->tag.Text(); } } htm << "<script language=javascript>" << crlf; htm << "document.write(\"<div id='hidesh' style='display:none'>\")"; htm << "</script>" << crlf; } htm.beginSelect( "Jsf", 3, 1 ); for( int i = 0; i < fJobSpec.Count(); i++ ) { se = fJobSpec.Get( i ); code = se->code; if( !isHiddenField( se->tag.Text(), code ) ) htm.selectOpt( 1 ); else htm.selectOpt(); htm.text( se->tag.Text() ); } htm.endSelect(); if (hideshowmenu) { htm << "<script language=javascript>" << crlf; htm << "document.write(\"</div>\")"; htm << "</script>" << crlf; } htm.endCol(); htm.beginCol( 0,0,0,0,0, "100%" ); htm.endCol(); fRequest << htm; } void p4wJobsPane::doFilterMessage(StrBuf *msg) { const StrPtr *ft = fRequest.GetDynArg( "ft" ); const StrPtr *jfp = fRequest.GetDynArg( "jfp" ); const StrPtr *jin = fRequest.GetDynArg( "jin" ); const StrPtr *jasc = fRequest.GetDynArg( "jasc" ); const StrPtr *mx = fRequest.GetDynArg( "mx" ); if (ft) *msg << "(Jobview: "" << p4wStrBuf().EscapeHTML( *ft, Unicode() ).Text() << """; if (jfp || jin) { if (*(msg->Text())) *msg << "; "; else *msg << "("; *msg << "Limit to current path"; } if (jin) { *msg << " and include integrations"; } if (jasc) { if (*(msg->Text())) *msg << "; "; else *msg << "("; *msg << "Show lowest "; if (mx) *msg << p4wStrBuf().EscapeHTML( *mx, Unicode() ).Text() << " jobs"; } else if (mx) { const StrPtr *X = fRequest.GetStateArg( "X" ); // undoc eXperimental flags int bQ = (X && strchr(X->Text(), 'm')) ? 1 : 0; if (!bQ) { if (*(msg->Text())) *msg << "; "; else *msg << "("; *msg << "Show highest " << p4wStrBuf().EscapeHTML( *mx, Unicode() ).Text() << " jobs"; } } if (*(msg->Text())) *msg << ")"; } int p4wJobsPane::isHiddenField( const char *field, int code ) { // // Return true if the field should be hidden. int hf = 1; const StrPtr *p; int i; // // Check dynamic argument (job show field) to see if // this field was selected to be shown. for( i = 0; ( p = fRequest.GetDynArg( "jsf", i ) ) != NULL; i++ ) { if( *p == field ) { --hf; break; } } // // If there are no dynamic jsf variables, only the first // 5 job fields are shown by default. if( hf && !i ) hf = code > 105; return hf; }
# | 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/p4wJobsPane.cpp | |||||
#1 | 8914 | Matt Attaway | Initial add of the P4Web source code |