// // Copyright 2000 Perforce Software. All rights reserved. // // This file is part of Perforce - the FAST SCM System. // // p4wBranchesPane: // Displays output of the branches command #include <p4wp4.h> #include "p4wStrBuf.h" #include "p4wHtml.h" #include "p4wPane.h" #include "p4wBranchesPane.h" #include "p4wMenuPane.h" p4wBranchesPane::p4wBranchesPane( p4wView & ParentView, p4wRequest & Request ) : p4wPane(ParentView, Request), fRowCtr(0), fBranchCtr(0), fBfl('\0') { } p4wBranchesPane::~p4wBranchesPane() { } // ------------------------------------- // Render functions. // void p4wBranchesPane::Begin() { // // Begin the pane. p4wHtml htm; p4wURL urlMaker; StrBuf clearIcon; StrBuf grayIcon; // // Construct whitespace spacer & line underneathe title urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); urlMaker.ConstructURL( grayIcon, "/grayPixelIcon", AC_ICON, NULL ); htm.comment( "BEGIN BRANCHES PANE" ); if (fRequest.GetScreenChunks() & SCRN_TITLE) { // Output the title htm.beginTRow(); htm.beginCol(); htm.beginSpan( "title" ); htm << "Branches:"; htm.endSpan(); htm.endCol(); htm.endTRow(); // // Generate line underneath the title htm.beginTRow(); htm.beginCol( "top" ); htm.icon( grayIcon.Text(), "1", "100%", "", 1, "0", "0" ); htm.endCol(); htm.endTRow(); } fRequest << htm; htm.Clear(); // // Generate the branches filter form if (fRequest.GetScreenChunks() & SCRN_FILTER) doForm(); // // Start the table 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(); htm.beginTable( "0", "100%", "0", "0", "#FFFFFF" ); // // Generate table headings. Generate spacers between columns // just in case the Description field is so large that it // crowds the other fields. htm.beginTRow( NULL, NULL, "#EEEEEE" ); htm.beginColHead(); htm.icon( clearIcon.Text(), "18", "5", "", 1 ); htm.endColHead(); htm.beginColHead( NULL, "left" ); htm << "Branch"; htm.endColHead(); htm.beginColHead( NULL, NULL, NULL, NULL, "#EEEEEE" ); htm << "<script language=javascript>" << crlf; htm << "document.write(\"<img src='/clearpixelIcon?ac=20' height='0' width='2' border='0' alt='' title=''>\")" << crlf; htm << "</script>" << crlf; htm << "<noscript>" << crlf; htm.icon( clearIcon.Text(), "0", "12", "", 1 ); htm << "</noscript>" << crlf; htm.endColHead(); htm.beginColHead( NULL, "left" ); htm << "Owner"; htm.endColHead(); htm.beginColHead( NULL, NULL, NULL, NULL, "#EEEEEE" ); htm.icon( clearIcon.Text(), "0", "12", "", 1 ); htm.endColHead(); htm.beginColHead( NULL, "left" ); htm << "Options"; htm.endColHead(); htm.beginColHead( NULL, NULL, NULL, NULL, "#EEEEEE" ); htm.icon( clearIcon.Text(), "0", "12", "", 1 ); htm.endColHead(); htm.beginColHead( NULL, "left" ); htm << "Updated"; htm.endColHead(); htm.beginColHead( NULL, NULL, NULL, NULL, "#EEEEEE" ); htm.icon( clearIcon.Text(), "0", "12", "", 1 ); htm.endColHead(); htm.beginColHead( NULL, "left" ); htm << "Accessed"; htm.endColHead(); htm.beginColHead( NULL, NULL, NULL, NULL, "#EEEEEE" ); htm.icon( clearIcon.Text(), "0", "12", "", 1 ); htm.endColHead(); htm.beginColHead( NULL, "left" ); htm << "Description"; htm.endColHead(); htm.endTRow(); htm.beginTRow(); htm.beginCol( "top", NULL, "12", NULL, NULL, NULL, "5" ); htm.icon( grayIcon.Text(), "1", "100%", "", 1, "0", "0" ); htm.endCol(); htm.endTRow(); fRequest << htm; const StrPtr *bfl = fRequest.GetDynArg( "bfl" ); if (bfl) fBfl = *(bfl->Text()); const StrPtr *bnm = fRequest.GetDynArg( "bnm" ); if (bnm) fBnm << bnm->Text(); const StrPtr *bow = fRequest.GetDynArg( "bow" ); if (bow) fBow << bow->Text(); const StrPtr *bdu = fRequest.GetDynArg( "bdu" ); if (bdu) fBdu << bdu->Text(); const StrPtr *bda = fRequest.GetDynArg( "bda" ); if (bda) fBda << bda->Text(); } void p4wBranchesPane::Render( StrDict * varList ) { // // Build the list entry which contains urls for branch & user const char *branch = varList->GetVar( "branch" )->Text(); const char *user = varList->GetVar( "Owner" )->Text(); if (fBfl & 0x01) { if (!user || strcmp(user, fRequest.GetUser().Text())) return; } if (fBnm.Length()) { if (!branch || !strstr(branch, fBnm.Text())) return; } if (fBow.Length()) { if (!user || strcmp(user, fBow.Text())) return; } if (fBdu.Length()) { char *p; StrBuf date; date << p4wStrBuf().Expand(StrRef("%Update@*Y/*m/*d%"), *varList, Unicode() ); switch(*(p = fBdu.Text())) { case '_': if (strncmp(date.Text(), p+1, strlen(p+1)) != 0) return; break; case '-': if (fBdu.Length() == 11 ) { if (strcmp(date.Text(), p+1) >= 0) { return; } } else if (strcmp(date.Text(), p+1) > 0) { return; } break; default: if (fBdu.Length() == 10 ) { if (strcmp(date.Text(), p) < 0) { return; } } else if (strncmp(date.Text(), p, strlen(p)) < 0) { return; } break; } } if (fBda.Length()) { char *p; StrBuf date; date << p4wStrBuf().Expand(StrRef("%Access@*Y/*m/*d%"), *varList, Unicode() ); switch(*(p = fBda.Text())) { case '_': if (strncmp(date.Text(), p+1, strlen(p+1)) != 0) return; break; case '-': if (fBda.Length() == 11 ) { if (strcmp(date.Text(), p+1) >= 0) { return; } } else if (strcmp(date.Text(), p+1) > 0) { return; } break; default: if (fBda.Length() == 10 ) { if (strcmp(date.Text(), p) < 0) { return; } } else if (strncmp(date.Text(), p, strlen(p)) < 0) { return; } break; } } // // If page content limit in bytes has been exceeded, don't // generate this entry if( PageLimitExceeded() ) return; StrBuf branchURL; StrBuf userURL; StrBuf newBase; p4wHtml htm(1); p4wURL urlMaker; StrBuf clearIcon; // // Construct the vertical spacing icon urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); // // Build the branch URL fRequest.UseNewBase( newBase, NULL, "path", NULL ); newBase << branch; urlMaker.ConstructURL( branchURL, newBase.Text(), AC_BRANCHVIEW, NULL, fRequest.GetUnicode() ); // // Build the user URL fRequest.UseNewBase( newBase, NULL, "path", NULL ); newBase << user; urlMaker.ConstructURL( userURL, newBase.Text(), AC_USERVIEW, NULL, fRequest.GetUnicode() ); // // Save off the Options StrBuf options; options << p4wStrBuf().Expand(StrRef("%Options% "), *varList, Unicode() ).Text(); // // Begin the row for this branch htm.beginTRow( "top", 0, 0, (fRowCtr & 0x01) ? "list_row alt_row" : "list_row" ); htm.beginCol(); htm.endCol(); // // Link to branch view htm.beginCol(0,0,0,0,0,0,0,1); htm.beginLink( branchURL.Text() ); htm.text( p4wStrBuf().EscapeHTML( StrRef(branch), Unicode()).Text() ); htm.endLink(); htm << crlf; htm << "<script language=javascript>" << crlf; htm << "document.write(\"<span class='muaro'><a href='javascript:showMenu(\\\""; htm << p4wStrBuf().EscapeHTML( StrRef(branch), Unicode() ).Text(); htm << "\\\",\\\"m"; htm << fBranchCtr; htm << "\\\",\\\"branch\\\","; if (strcmp(user, fRequest.GetUser().Text()) && !strstr(options.Text(), "unlocked")) // other user & locked? htm << p4wMenuPane::GetLockedBranchMenuShowVals(); else htm << -1; htm << ",\\\"\\\")' id='id_m"; htm << fBranchCtr++; htm << "' title ='Menu'>"; htm << " "; htm << "</a></span>"; htm << "\")" << crlf; htm << "</script>" << crlf; htm.endCol(); htm.beginCol(); htm.endCol(); // // Owner htm.beginCol(); htm.beginLink( userURL.Text() ); htm.text( p4wStrBuf().EscapeHTML( StrRef(user), Unicode()).Text() ); htm.endLink(); htm.endCol(); htm.beginCol(); htm.endCol(); // // Options. Don't use nobr because it will cause this field // to spill into next field if using Netscape 4.x with a long // description field. htm.beginCol(); htm.text( options.Text() ); htm.endCol(); htm.beginCol(); htm.endCol(); // // Update date htm.beginCol(); htm.beginNobreak(); htm.text( p4wStrBuf().Expand(StrRef("%Update@*Y/*m/*d% "), *varList, Unicode() ).Text() ); htm.endNobreak(); htm.endCol(); htm.beginCol(); htm.endCol(); // Access Date htm.beginCol(); StrPtr *access = varList->GetVar("Access"); if (access && *(access->Text()) != '0') { htm.text( p4wStrBuf().Expand(StrRef("%Access@*Y/*m/*d% "), *varList, Unicode() ).Text() ); } htm.endCol(); htm.beginCol(); htm.endCol(); // // Description htm.beginCol(); htm.text( p4wStrBuf().Expand(StrRef("%Description% "), *varList, Unicode() ).Text() ); 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 p4wBranchesPane::End() { // // End the "Branches" list. p4wHtml htm; if( !fBranchCtr ) { p4wURL urlMaker; StrBuf clearIcon; urlMaker.ConstructURL( clearIcon, "/clearpixelIcon", AC_ICON, NULL ); htm.beginTRow(); htm.beginCol(); htm.endCol(); htm.beginCol( NULL, NULL, "4" ); htm.text( "No branches found." ); htm.endCol(); htm.endTRow(); htm.beginTRow(); htm.beginCol(); htm.icon( clearIcon.Text(), "5", "0", "", 1 ); htm.endCol(); htm.endTRow(); } // // End the pane. htm.endTable(); htm.endCol(); htm.endTRow(); htm.endTable(); htm.endCol(); htm.endTRow(); htm.comment( "END BRANCHES PANE" ); fRequest << htm; } void p4wBranchesPane::doForm() { // // Generate the branches filter form p4wHtml htm; p4wURL urlMaker; StrBuf actionURL; StrBuf path; StrBuf clearIcon; char *p; const StrPtr *bfl = fRequest.GetDynArg( "bfl", HE_Page ); const StrPtr *bnm = fRequest.GetDynArg( "bnm", HE_Page ); const StrPtr *bow = fRequest.GetDynArg( "bow", HE_Page ); const StrPtr *bdu = fRequest.GetDynArg( "bdu", HE_Page ); const StrPtr *bda = fRequest.GetDynArg( "bda", HE_Page ); // // 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(); fRequest.ConstructSafeURL( actionURL, path.Text(), AC_BRANCHESPROCESSOR, NULL ); htm.beginTRow(); htm.beginCol(); fRequest << htm; htm.Clear(); StrBuf filtermsg; doFilterMessage(&filtermsg); fRequest.doShowHideBlock(SH_BRANCHES, "branch filter", "Branch Filter", filtermsg.Text()); htm.endCol(); htm.endTRow(); // // 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"); // // Start the tables with the form 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" ); // // Top row of filter htm.beginTRow(); htm.beginCol(0,0,0,"100%"); htm.icon( clearIcon.Text(), "1", "14", "", 1 ); htm.endCol(); htm.beginCol(0,0,0,0,0,0,0,1); htm.label("Branch name contains:", "bnm"); htm.endCol(); htm.beginCol(); htm.textField("bnm", bnm && bnm->Length() ? bnm->Text() : 0, 0, "bnm"); htm.endCol(); htm.beginCol(); htm.icon( clearIcon.Text(), "1", "50", "", 1 ); htm.endCol(); htm.beginCol(); htm.text("Updated:"); htm.endCol(); htm.beginCol(0,0,0,0,0,0,0,1); htm.radio("Updated", "on", bdu && *(bdu->Text()) == '_', 0, "uon"); htm.label("on ", "uon"); htm.radio("Updated", "before", bdu && *(bdu->Text()) == '-', 0, "ub4"); htm.label("before ", "ub4"); htm.radio("Updated", "after", !bdu || (*(bdu->Text()) != '_' && *(bdu->Text()) != '-'), 0, "uaf"); htm.label("after ", "uaf"); htm.endCol(); htm.beginCol(); if (bdu && bdu->Length()) { p = bdu->Text(); if (*p == '-' || *p == '_') p++; } else p = NULL; htm.textField("bdu", p ? p : 0, 0, "bdu", 0, "formFieldClear(this, 'yyyy/mm/dd')", "formFieldRestore(this, 'yyyy/mm/dd')"); if (!p) { htm << "<script language=\"JavaScript\" type=\"text/javascript\">" << crlf; htm << "d = document.getElementById('bdu');;" << crlf; htm << "if (d) { d.value = 'yyyy/mm/dd'; d.style.color = '#A0A0A0'; }" << crlf; htm << "</script>" << crlf; } htm.endCol(); htm.beginCol(0,0,0,0,0,"100%"); htm.endCol(); htm.endTRow(); // // 2nd row of filter htm.beginTRow(); htm.beginCol(0,0,0,0,0,0,0,1); htm.label("Owner:", "bow"); htm.endCol(); htm.beginCol(); if (bfl && (bfl->Atoi() & 1)) htm.textField("bow", p4wStrBuf().EscapeHTML( fRequest.GetUser(), Unicode()).Text(), 0, "bow"); else htm.textField("bow", bow && bow->Length() ? bow->Text() : 0, 0, "bow"); htm.endCol(); htm.beginCol(); htm.endCol(); htm.beginCol(); htm.text("Accessed:"); htm.endCol(); htm.beginCol(0,0,0,0,0,0,0,1); htm.radio("Accessed", "on", bda && *(bda->Text()) == '_', 0, "aon"); htm.label("on ", "aon"); htm.radio("Accessed", "before", bda && *(bda->Text()) == '-', 0, "ab4"); htm.label("before ", "ab4"); htm.radio("Accessed", "after", !bda || (*(bda->Text()) != '_' && *(bda->Text()) != '-'), 0, "aft"); htm.label("after ", "aft"); htm.endCol(); htm.beginCol(); if (bda && bda->Length()) { p = bda->Text(); if (*p == '-' || *p == '_') p++; } else p = NULL; htm.textField("bda", p ? p : 0, 0, "bda", 0, "formFieldClear(this, 'yyyy/mm/dd')", "formFieldRestore(this, 'yyyy/mm/dd')"); if (!p) { htm << "<script language=\"JavaScript\" type=\"text/javascript\">" << crlf; htm << "d = document.getElementById('bda');" << crlf; htm << "if (d) { d.value = 'yyyy/mm/dd'; d.style.color = '#A0A0A0'; }" << crlf; htm << "</script>" << crlf; } htm.endCol(); htm.endTRow(); // // Filter button htm.beginTRow(); htm.beginCol(); htm.icon( clearIcon.Text(), "5", "1", "", 1 ); htm.endCol(); htm.endTRow(); htm.beginTRow(); htm.beginCol(0,0,"100%",0,0,0,0,1); htm.button( "Show", "Filter" ); // // Clear button htm.button( "Clear", "Reset Defaults" ); htm.endCol(); htm.endTRow(); htm.endTable(); StrBuf grayIcon; urlMaker.ConstructURL( grayIcon, "/grayPixelIcon", AC_ICON, NULL ); htm.icon( clearIcon.Text(), "10", "100%", "", 1, "0", "0" ); htm.icon( grayIcon.Text(), "1", "100%", "", 1, "0", "0" ); htm.endCol(); htm.endTRow(); htm.endCol(); htm.endTRow(); htm.endTable(); htm << "<script language=javascript>" << crlf; htm << "document.write(\"</div>\")" << crlf; htm << "</script>" << crlf; fRequest << htm; } void p4wBranchesPane::doFilterMessage(StrBuf *msg) { const StrPtr *bfl = fRequest.GetDynArg( "bfl", HE_Page ); const StrPtr *bnm = fRequest.GetDynArg( "bnm", HE_Page ); const StrPtr *bow = fRequest.GetDynArg( "bow", HE_Page ); const StrPtr *bdu = fRequest.GetDynArg( "bdu", HE_Page ); const StrPtr *bda = fRequest.GetDynArg( "bda", HE_Page ); if (bnm) *msg << "(Name contains: "" << bnm->Text() << """; char *p = NULL; if (bfl && (bfl->Atoi() & 1)) p = p4wStrBuf().EscapeHTML( fRequest.GetUser(), Unicode() ).Text(); else if (bow) p = bow->Text(); if (p) { if (*(msg->Text())) *msg << "; Owner: "; else *msg << "(Owner: "; *msg << """ << p<< """; } if (bdu) { if (*(msg->Text())) *msg << "; Updated "; else *msg << "(Updated "; switch(*(bdu->Text())) { case '-': if (bdu->Length() < 11) *msg << "on or"; *msg << " before"; p = bdu->Text()+1; break; case '_': if (bdu->Length() < 11) *msg << "in"; else *msg << "on"; p = bdu->Text()+1; break; default: if (bdu->Length() < 10) *msg << "in or"; *msg << " after"; p = bdu->Text(); break; } *msg << ": " << p; } if (bda) { if (*(msg->Text())) *msg << "; Accessed "; else *msg << "(Accessed "; switch(*(bda->Text())) { case '-': if (bda->Length() < 11) *msg << "on or"; *msg << " before"; p = bda->Text()+1; break; case '_': if (bda->Length() < 11) *msg << "in"; else *msg << "on"; p = bda->Text()+1; break; default: if (bda->Length() < 10) *msg << "in or"; *msg << " after"; p = bda->Text(); break; } *msg << ": " << p; } if (*(msg->Text())) *msg << ")"; }
# | 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/p4wBranchesPane.cpp | |||||
#1 | 8914 | Matt Attaway | Initial add of the P4Web source code |