" . start_table("class=\"PageTitleTable\"") ;
my $prHeaderTable = 1 ; # Always print it (disable logic to determine if header should be printed
# if($title ne "") {
$headerTable .= table_row({-class => "PageTitle",
-text => "$title"},
{-class => "PageTitleLogout",
-text => $logout}) ;
$prHeaderTable++ ;
# }
$headerTable .= end_table() . "
" ;
if(defined $buttons) {
$headerTable .= $buttons ;
$prHeaderTable++ ;
} ;
if($prHeaderTable) { $ret .= $headerTable ; } ;
$pageStartPrinted = 1 ;
return $ret . "\n" ;
} ;
###################################################################
### end_page
###
=head2 end_page
C<&P4CGI::end_page()>
End a page. Print HTML trailer.
Example:
print P4CGI::end_page() ;
=cut ;
sub end_page()
{
$DEFAULT_SPAN_CLASS = "" ;
my $depot = spanClass(DEPOT_NAME(CURR_DEPOT_NO())) ;
my $lastch = spanClass(CURRENT_CHANGE_LEVEL()) ;
my $server_port = spanClass(USER_P4PORT()) ;
my ($server_year, $server_No, $server_qual) = SERVER_VERSION() ;
unless(defined $server_year and $server_year > 0) {
$server_port= "" ;
($server_year, $server_No, $server_qual) = ("-","-","") ;
} ;
my $server_version = spanClass("$server_year.$server_No$server_qual") ;
$DEFAULT_SPAN_CLASS = "" ;
my $version = &P4CGI::VERSION() ;
my $changelevel = &P4CGI::CHANGELEVEL() ;
my $p4dbver = "$version/$changelevel" ;
my @p4adm = map { my ($em,@nm) = split(/\s+/,$_) ; "",
(start_table(" class=\"ServerInfo\""),
table_row(
{-type=>"th",
-text=>spanClass("P4DB ver:")},
$p4dbver,
{-type=>"th",
-text=>spanClass("Depot:")},
$depot,
{-type=>"th",
-text=>spanClass("Changes:")},
$lastch,
{-type=>"th",
-text=>spanClass("Port:")},
$server_port,
{-type=>"th",
-text=>spanClass("Server version:")},
$server_version),
table_row(
{-type=>"th",
-text=>$showuser ? spanClass("Current user:") : "" },
undef,
undef,
undef,
undef,
$showuser ? "$P4_USER
Ticket expires $P4_TICKET_EXPIRES" : "" ,
{-type=>"th",
-text=>spanClass("Administrator$adminPluralS:")},
undef,
undef,
join("
",@p4adm)),
end_table(),
"
",
"C<)>
Report an error. This routine will emit HTML code for an error message, print the error log and exit.
This rouine is intended to report internal errors in the code (much like assert(3) in c).
=over 4
=item message
Message that will be displayed to user
=back
Example:
unless(defined $must_be_defined) {
&P4CGI::bail("was not defined") ;
} ;
=cut ;
my $bailed ;
sub bail(@) {
unless(defined $bailed) {
$bailed = 1 ;
my $message = shift ;
my $text = shift ;
unless(defined $pageStartPrinted) {
print
"",
$CGI->header(),
$CGI->start_html(-title => "Error in script",
-bgcolor => "white",
-style => { -src=>$STYLE_SHEET }) ;
$pageStartPrinted = 1 ;
} ;
$message = &htmlEncode($message) ;
print
"
" ,
"An error has occurred
Sorry!" ,
"
Message:
$message
" ;
if(defined $text) {
$text = &htmlEncode($text) ;
print "$text
\n" ;
} ;
print
"Parameters to script:
",
$CGI->Dump() ;
print "
\n",prerrlog(), end_page() ;
die($message) ;
}
} ;
###################################################################
### signalError
###
=head2 signalError
C<&P4CGI::signalError(>BC<)>
Report an operator error in a reasonable fashion.
SignalError can be called before or after start_page() but if it is called
before start_page() a "default" page header will appear. It is recommended
to call signalError() after start_page() to make it more obvious to the
operator what the problem was.
=over 4
=item message
Message that will be displayed to user
=back
Example:
unless(defined $must_be_defined) {
&P4CGI::signalError("was not defined") ;
} ;
=cut ;
sub signalError {
my $message = shift ;
my $text = shift ;
unless(defined $pageStartPrinted) {
print "",start_page("Error","") ;
$pageStartPrinted = 1 ;
} ;
$message = &htmlEncode($message) ;
print
"$message
" ;
if(defined $text) {
$text = &htmlEncode($text) ;
print "
$text
\n" ;
} ;
print "", end_page() ;
exit 0 ;
} ;
###################################################################
### help_link
###
sub help_link($ ) {
my $helpURL="$HELPFILE_PATH/B_Help.html#" . shift ; ;
return ahref(-url=>$helpURL,
"?") ;
}
###################################################################
### start_table
###
=head2 start_table
C<&P4CGI::start_table(>BC<)>
Start a table with optional table attributes
=over 4
=item table_attribute_text
This text will be inserted as attributes to table tag
=back
Example:
print P4CGI::start_table("align=center border") ;
=cut ;
sub start_table
{
my $attribs = shift ;
my $ret = "\n";
}
###################################################################
### end_table
###
=head2 end_table
C<&P4CGI::end_table()>
Return end of table string. (trivial function included mostly for symmetry)
=cut ;
sub end_table()
{
return "
\n" ;
}
###################################################################
### table_row
###
=head2 table_row
C<&P4CGI::table_row(>BC<,>BC<)>
Insert a row in table.
=over 4
=item options
A list of key/value pairs (a hash will do just fine) containing options for
the row.
The key must start with a "-".
Most key/value pairs are treated as attributes to the -tag.
The following keys are recognized as special:
=over 4
=item C<-type>
Type of cells. Default is -type.
=item C<->I
I will be assumed to be a row option and will be inserted in the TR-tag.
The value for the option is the key value, unless value is empty or undefined, in which
case the option anykey is assumed to have no value.
=back
=item listOfValues
Row data. Remaining values are assumed to be data for each cell.
The data is typically the text in the cell but can also be:
=over 4
=item undef
An undefined value indicates that the next cell spans more than one column.
=item Reference to a hash
The hash contains two keys: "-text" for cell text and "-type" for cell type.
All other key/value pairs are treated as attributes to the or | tag.
=back
=back
Example:
print P4CGI::start_table("align=center") ;
### print header row
print P4CGI::table_row(-type => "th",
-valign => "top",
-align => "left",
"Heading 1","Heading 2",undef,"Heading 3") ;
### print data
my %h = (-text => "text in hash",
-bgcolor => "blue") ;
print P4CGI::table_row(-valign => "top",
-bgcolor => "white",
"Cell 1",
{-text => "Cell 2",
-bgcolor => "red"},
\%h,
"Cell 3-2") ;
print P4CGI::end_table() ;
=cut ;
sub table_row
{
confess ("P4CGI::table_row() Parameters required!") if @_ == 0 ;
my @ret ;
my $n = 0 ;
my $ec = 0 ;
my $option = shift ;
my %options ;
while(defined $option and ($option =~ s/^-//)) {
confess ("P4CGI::table_row() Option value required!") if @_ == 0 ;
$options{lc($option)} = shift ;
$option = shift ;
}
unshift @_,$option ;
my $type = "td" ;
$type = $options{"type"} if defined $options{"type"} ;
delete $options{"type"} ;
push @ret," | \n" ;
my $colspan = 0 ;
my $cell ;
foreach $cell (@_) {
$colspan++ ;
if(defined $cell) {
my $COLSPAN="colspan=\"$colspan\"" ;
$colspan=0 ;
if(ref $cell) {
my $reftyp = ref $cell ;
"HASH" eq $reftyp and do { my $txt = $$cell{"-text"} ;
confess "P4CGI::table_row() Missing text argument"
unless defined $txt ;
delete $$cell{"-text"} ;
my $tp = $type ;
$tp = $$cell{"-type"} if defined
$$cell{"-type"} ;
delete $$cell{"-type"} ;
push @ret,"<$tp $COLSPAN" ;
my $attr ;
foreach $attr (keys %$cell) {
($a = $attr) =~ s/^-// ;
push @ret," $a=\"$$cell{$attr}\"" ;
}
push @ret,">$txt$tp>\n" ;
next ; } ;
confess "Illegal cell data type \"$reftyp\"" ;
}
else {
push @ret,"<$type $COLSPAN>$cell$type>\n" ;
}
}
}
push @ret," \n" ;
return join("",@ret) ;
}
###################################################################
### table_header
###
=head2 table_header
C<&P4CGI::table_header(>BC<)>
Create a table header row with a a description and an optional hint for each column.
=over 4
=item list of label/hint
A list of column labels optionally followed by a '/' and a hint.
=back
Example:
print P4CGI::start_table("align=center") ;
### print header row
print P4CGI::table_header("File/click for story","Revision/click to view") ;
### print data
my %h = (-text => "text in hash",
-bgcolor => "blue") ;
print P4CGI::table_row(-valign => "top",
-bgcolor => "white",
"Cell 1",
{-text => "Cell 2",
-bgcolor => "red"},
\%h,
"Cell 3-2") ;
print P4CGI::end_table() ;
=cut ;
sub table_header
{
my @cols ;
my @tmp = @_ ;
my $tmp ;
my $n ;
while(@tmp > 0) {
$tmp = shift @tmp ;
if(defined $tmp) {
my $label = $tmp ;
push @cols,{ -text => $label,
-class => "ListHeader" } ;
}
else {
push @cols,$tmp ;
}
}
return table_row(-class => "ListHeader", @cols) ;
} ;
################################################################
### Make a framed table with a title
###
sub start_framedTable($;$ )
{
my $title = shift ;
my $class ;
$class = shift or do { $class="Frame" ; } ;
my $res = "" ;
$res .= "$title\n" if $title ne "" ;
return $res . "\n" ;
}
sub end_framedTable()
{
return " | \n" ;
}
sub framedTable($$ )
{
my $title = shift ;
my $contents = shift ;
return join("\n",(&start_framedTable($title),
$contents,
&end_framedTable())) ;
}
###################################################################
### Make a list
###
=head2 ul_list
C<&P4CGI::ul_list(>BC<)>
Return a bulleted list.
=over 4
=item I
Lits of data to print as bulleted list
=back
Example:
print P4CGI::ul_list("This","is","a","bulleted","list") ;
=cut ;
sub ul_list(@ )
{
my @ret ;
if($_[0] eq "-title") {
shift ;
push @ret, shift ;
}
push @ret,"\n" ;
my $a ;
foreach $a (@_) {
push @ret,"- $a\n" ;
}
push @ret,"
\n" ;
return join("",@ret) ;
}
###################################################################
### Make a dl list
###
=head2 dl_list
C<&P4CGI::dl_list(>BC<)>
Returns a definition list.
=over 4
=item list_of_pairs
List of data pairs to print as a definition list.
A hash will do just fine, only you have no control over the order in the list.
=back
Example:
print P4CGI::dl_list("This","Description of this",
"That","Description of that") ;
=cut ;
sub dl_list
{
my @ret ;
if($_[0] eq "-title") {
shift ;
push @ret,shift ;
}
if($_[0] eq "-compact") {
push @ret,"\n" ;
shift ;
}
else {
push @ret,"\n" ;
}
while(@_ > 1) {
push @ret,"- ",shift ,"
- ",shift ,"\n" ;
}
push @ret,"
\n" ;
return join("",@ret) ;
}
###################################################################
### Create a href tag
###
=head2 ahref
C<&P4CGI::ahref(>BC<,>BC<,>BC<)>
Returns a ... tag pair.
=over 4
=item I
Optional list of option-value pairs. Valid options are:
=over 4
=item C<-url>
Url for link. Default is current.
=item C<-anchor>
Anchor in url. Default is none.
=back
Any non-valid option marks the end of the options
=item I
Optional list of parameters for link.
=item I
The last parameter is used as text for link.
If the next to the last parameter has the format: C<"HELP=Help text"> the
help text is displayed as a tooltip.
=back
Example:
print &P4CGI::ahref("Back to myself") ; # link to this. No parameters.
print &P4CGI::ahref("-url","www.perforce.com",
"To perforce") ; # link to perforce
print &P4CGI::ahref("-anchor","THERE",
"Go there") ; # link to anchor THERE
print &P4CGI::ahref("-url","changeList.cgi",
"FSPC=//.../doc/...",
"HELP=Click here", # a tooltop help text
"Changes for all documentation") ; # url with parameter
=cut ;
sub ahref
{
my $args=@_ ;
my @tmp = @_ ;
my $url = $ENV{SCRIPT_NAME} ;
my $anchor = "" ;
my $params = "" ;
while($tmp[0] =~ /^-/) {
$tmp[0] =~ /^-url$/i and do {
shift @tmp ;
$url = shift(@tmp) ;
next ;
} ;
$tmp[0] =~ /^-anchor$/i and do {
shift @tmp ;
$anchor = "#" . shift @tmp ;
next ;
} ;
$tmp[0] =~ /^-(.*)/ and do {
my $p = $1 ;
shift @tmp ;
my $v = shift @tmp ;
$params .= " $p=$v" ;
next ;
} ;
last ;
}
my $pars = "" ;
$pars = "?DP=$P4_PORT_NO" if ($P4_PORT_NO and !($url =~ /\WDP=/) and !($url =~ /^mailto/)) ;
my $tooltips="" ;
while(@tmp > 1) {
if($tmp[0] =~ /HELP=(.*)/) {
$tooltips=" title=\"$1\"" ;
shift @tmp ;
next ;
}
if(length($pars) > 0) {
$pars .= ";" ;
}
else {
$pars = "?" ;
} ;
$pars .= urlEncode(shift @tmp) ;
} ;
my $txt = shift @tmp ;
$pars =~ s/ /\+/g ;
return "$txt" ;
}
###################################################################
### ButtonCell
### Create a button link in a table cell
###
sub buttonCell($$@)
{
return "" . &buttonLink(@_) . " | \n" ;
}
###################################################################
### ButtonLink
### Create a button link
###
sub buttonLink($$@)
{
my $url = shift ;
my $help = shift ;
my @text = @_ ;
my $params="" ;
$params = "?DP=$P4_PORT_NO" if ($P4_PORT_NO and !($url =~ /\WDP=/) and !($url =~ /^mailto/)) ;
while(@text > 1) {
if($params) {
$params .= ";" ;
}
else {
$params = "?" ;
}
$params .= shift @text ;
}
my $txt = $text[0] ;
$txt =~ s/ / /g ;
return "$txt\n" ;
}
###################################################################
### buttonVMenuTable
### Create a vertical menu of "buttons".
###
sub buttonVMenuTable(@)
{
my $r = "\n" ;
}
###################################################################
### buttonHMenuTable
### Create a horizontal menu of "buttons".
###
sub buttonHMenuTable(@)
{
return
"\n" ;
}
###################################################################
### spanClass
### Create a element with a class
###
sub spanClass($;$)
{
my $text = shift ;
$text = "" unless defined $text ;
my $class ;
$class = shift or do { $class = $DEFAULT_SPAN_CLASS ; } ;
if($class eq "") {
return "$text" ;
}
return "$text" ;
}
###################################################################
### splitLine
### Use -tags to split lines longer than maxlen characters (and do not include html-tags in count).
###
sub splitLine($$)
{
my $line = shift ;
my $maxlen = shift ;
my @line = split(/(<[^>]+>)/,$line) ;
$line = "" ;
while(@line > 0) {
my $l = shift @line ;
my $txt ="" ;
while(length($l) > $maxlen and
$l =~ s/(.{1,$maxlen}\S)\s(.*)/$2/) {
$txt .= $1 ;
$txt .= "\n" if length($l) ;
}
$txt .= $l ;
$txt =~ s/ / /g ;
$line .= $txt ;
$line .= shift @line if @line > 0 ;
}
return $line ;
}
###################################################################
### formatDescription
### Format a description text and insert it into a cell
###
sub formatDescription($;\@)
{
my $desc = shift ;
my @tmp ;
my $refref ;
$refref = shift or $refref = \@tmp ;
$desc = &htmlEncode($desc) ;
$desc = &P4CGI::magic($desc,$refref) ;
my @desc = map { my $d = splitLine($_,85) ;
$d ;
} split("\n",$desc) ;
my $r = join("\n",@desc) ;
$r =~ s/\n/ \n/g ;
return $r ;
}
###################################################################
### Login form
### Called when a user must log in
###
sub login_form() {
print start_page("Login page") ;
if(NO_OF_DEPOTS() > 1) {
print
$CGI->start_form(-method=>"POST",
-action=>$CGI->self_url()),
start_framedTable("Select depot"),
start_table() ;
my $d ;
my %alts ;
my @depotnames ;
for($d = 0 ; $d < NO_OF_DEPOTS() ; $d++) {
my $n = DEPOT_NAME($d) ;
$alts{$d} = $n ;
push @depotnames, $d ;
}
my $cell = $CGI->popup_menu(-name=>"DP",
"values"=>\@depotnames,
-title=>"Select p4 server",
-default=>CURR_DEPOT_NO(),
-labels=>\%alts) ;
print
table_row({-class=>"Prompt",
-text=>"Select p4 server"},
{-align=>"left",
-text=>$cell}),
table_row("",
$CGI->submit(-value=>'Change server',
-name=>'1')),
end_table(),
end_framedTable(),
$CGI->end_form(),
" ";
}
print
$CGI->start_form(-method=>"POST",
-action=>$CGI->self_url()),"\n",
start_framedTable("Log in"),"\n",
start_table() ;
## Print input field for user name.
my $defaultuser;
$defaultuser = $P4_USER if $P4_USER ;
if($SELECT_USER_FROM_LIST) {
my %p4users = p4users() ;
my %user2username ;
map {
$user2username{$_} = "$_ (".${$p4users{$_}}{"FullName"}.")" ;
} keys %p4users ;
my @usersInOrder = sort {uc($a) cmp uc($b)} keys %p4users ;
print
table_row({-class=>"Prompt",
-text=>"P4 user"},
{-align=>"left",
-text=>$CGI->popup_menu(-name=>"LOGIN_USER",
-values=>\@usersInOrder,
-labels=>\%user2username,
-default=>$defaultuser)}) ;
}
else {
print
table_row({-class=>"Prompt",
-text=>"P4 user"},
{-align=>"left",
-text=>$CGI->textfield(-name=>"LOGIN_USER",
-size=>20,
-maxlength=>80,
-default=>$defaultuser)}) ;
} ;
$CGI->delete("LOGIN_PASSWD") ;
print
table_row({-class=>"Prompt",
-text=>"Password"},
{-align=>"left",
-text=>$CGI->password_field(-name=>"LOGIN_PASSWD",
-size=>20,
-default=>"",
-maxlength=>80)}),
table_row("",
{-align=>"left",
-text=>$CGI->submit(-name=>"Login",
-value=>"Login")}),
end_table(),
end_framedTable(),
"\n" ;
$CGI->delete("LOGIN_USER","Login") ;
my @pars=$CGI->param() ;
foreach (@pars) {
print $CGI->hidden($_,$CGI->param($_)) , "\n" ;
}
print $CGI->end_form() ;
print
"The user name and password used for P4DB is same as your p4 user name and password. " ;
$P4_USER= undef ;
print end_page() ;
exit 0 ;
}
sub BEGIN ()
{
init() ;
} ;
1;
|