--- loncom/interface/loncommon.pm	2004/11/23 07:29:24	1.234
+++ loncom/interface/loncommon.pm	2005/01/25 00:27:59	1.247
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.234 2004/11/23 07:29:24 raeburn Exp $
+# $Id: loncommon.pm,v 1.247 2005/01/25 00:27:59 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -691,20 +691,30 @@ sub help_open_menu {
     $template .= <<"ENDTEMPLATE";
  <script type="text/javascript">
 //<!-- BEGIN LON-CAPA Internal
-function helpMenu(caller) {
-    if (caller == 'open') {
-        newWindow =  window.open("","helpmenu","HEIGHT=$height,WIDTH=$width,resize=yes,scrollbars=yes" )
-        caller = newWindow.document
-    } else {
-        caller = this.document
-    }
-    caller.write("<html><head><title>LON-CAPA Help Menu</title><meta http-equiv='pragma' content='no-cache'></head>")
-    caller.write("<frameset rows='105,*' border='0'><frame name='bannerframe'  src='$banner_link'><frame name='bodyframe' src='$details_link'></frameset>")
-    caller.write("</html>")
-    caller.close()
-    if (caller == newWindow.document) {
-        caller.focus()
+function helpMenu(target) {
+    var caller = this;
+    if (target == 'open') {
+        var newWindow = null;
+        try {
+            newWindow =  window.open("","helpmenu","HEIGHT=$height,WIDTH=$width,resizable=yes,scrollbars=yes" )
+        }
+        catch(error) {
+            writeHelp(caller);
+            return;
+        }
+        if (newWindow) {
+            caller = newWindow;
+        }
     }
+    writeHelp(caller);
+    return;
+}
+function writeHelp(caller) {
+    caller.document.write("<html><head><title>LON-CAPA Help Menu</title><meta http-equiv='pragma' content='no-cache'></head>")
+    caller.document.write("<frameset rows='105,*' border='0'><frame name='bannerframe'  src='$banner_link'><frame name='bodyframe' src='$details_link'></frameset>")
+    caller.document.write("</html>")
+    caller.document.close()
+    caller.focus()
 }
 // END LON-CAPA Internal -->
  </script>
@@ -884,6 +894,7 @@ sub define_excel_formats {
     $format->{'h1'}   = $workbook->add_format(bold=>1, size=>18);
     $format->{'h2'}   = $workbook->add_format(bold=>1, size=>16);
     $format->{'h3'}   = $workbook->add_format(bold=>1, size=>14);
+    $format->{'i'}    = $workbook->add_format(italic=>1);
     $format->{'date'} = $workbook->add_format(num_format=>
                                             'mm/dd/yyyy hh:mm:ss');
     return $format;
@@ -1230,9 +1241,11 @@ Outputs:
 ###############################################################
 ###############################################################
 sub decode_user_agent {
+    my ($r)=@_;
     my @browsertype=split(/\&/,$Apache::lonnet::perlvar{"lonBrowsDet"});
     my %mathcap=split(/\&/,$$Apache::lonnet::perlvar{"lonMathML"});
     my $httpbrowser=$ENV{"HTTP_USER_AGENT"};
+    if (!$httpbrowser && $r) { $httpbrowser=$r->header_in('User-Agent'); }
     my $clientbrowser='unknown';
     my $clientversion='0';
     my $clientmathml='';
@@ -2285,7 +2298,7 @@ sub get_student_view {
   if (defined($moreenv)) {
       %form=(%form,%{$moreenv});
   }
-  if ($target eq 'tex') {$form{'grade_target'} = 'tex';}
+  if (defined($target)) { $form{'grade_target'} = $target; }
   $feedurl=&Apache::lonnet::clutter($feedurl);
   my $userview=&Apache::lonnet::ssi_body($feedurl,%form);
   $userview=~s/\<body[^\>]*\>//gi;
@@ -2325,7 +2338,7 @@ sub get_student_answers {
 
 =item * &submlink()
 
-Inputs: $text $uname $udom $symb
+Inputs: $text $uname $udom $symb $target
 
 Returns: A link to grades.pm such as to see the SUBM view of a student
 
@@ -2333,15 +2346,64 @@ Returns: A link to grades.pm such as to
 
 ###############################################
 sub submlink {
-    my ($text,$uname,$udom,$symb)=@_;
+    my ($text,$uname,$udom,$symb,$target)=@_;
+    if (!($uname && $udom)) {
+	(my $cursymb, my $courseid,$udom,$uname)=
+	    &Apache::lonxml::whichuser($symb);
+	if (!$symb) { $symb=$cursymb; }
+    }
+    if (!$symb) { $symb=&symbread(); }
+    $symb=&Apache::lonnet::escape($symb);
+    if ($target) { $target="target=\"$target\""; }
+    return '<a href="/adm/grades?&command=submission&'.
+	'symb='.$symb.'&student='.$uname.
+	'&userdom='.$udom.'" '.$target.'>'.$text.'</a>';
+}
+##############################################
+
+=pod
+
+=item * &pgrdlink()
+
+Inputs: $text $uname $udom $symb $target
+
+Returns: A link to grades.pm such as to see the PGRD view of a student
+
+=cut
+
+###############################################
+sub pgrdlink {
+    my $link=&submlink(@_);
+    $link=~s/(&command=submission)/$1&showgrading=yes/;
+    return $link;
+}
+##############################################
+
+=pod
+
+=item * &pprmlink()
+
+Inputs: $text $uname $udom $symb $target
+
+Returns: A link to parmset.pm such as to see the PPRM view of a
+student andn resource
+
+=cut
+
+###############################################
+sub pprmlink {
+    my ($text,$uname,$udom,$symb,$target)=@_;
     if (!($uname && $udom)) {
 	(my $cursymb, my $courseid,$udom,$uname)=
 	    &Apache::lonxml::whichuser($symb);
 	if (!$symb) { $symb=$cursymb; }
     }
     if (!$symb) { $symb=&symbread(); }
-    return '<a href="/adm/grades?symb='.$symb.'&student='.$uname.
-	'&userdom='.$udom.'&command=submission">'.$text.'</a>';
+    $symb=&Apache::lonnet::escape($symb);
+    if ($target) { $target="target=\"$target\""; }
+    return '<a href="/adm/parmset?&command=set&'.
+	'symb='.$symb.'&uname='.$uname.
+	'&udom='.$udom.'" '.$target.'>'.$text.'</a>';
 }
 ##############################################
 
@@ -2599,26 +2661,45 @@ ENDROLE
 		$font.'"><b>'.$title.'</b></font>';
         if ($customtitle) {
             $titleinfo = $customtitle;
-        } 
+        }
+
 	if ($ENV{'request.state'} eq 'construct') {
 	    my ($uname,$thisdisfn)=
 		($ENV{'request.filename'} =~ m|^/home/([^/]+)/public_html/(.*)|);
 	    my $formaction='/priv/'.$uname.'/'.$thisdisfn;
 	    $formaction=~s/\/+/\//g;
-	    $titleinfo = '<form name="dirs" method="post" action="'.$formaction
-		.'" target="_top">'
-		.&Apache::lonhtmlcommon::crumbs($uname.'/'.$thisdisfn,'_top','/priv','',-1,1)."<br />"
-		.&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()')
-		.'</form>'
-		.&Apache::lonmenu::constspaceform();
-
-	    &Apache::lonhtmlcommon::store_recent('construct',$formaction,$formaction);
-	    if ($thisdisfn!~m|/$|) {  $forcereg=1; }
-	}
+            unless ($customtitle) {  #this is for resources; directories have customtitle, and crumbs and select recent are created in lonpubdir.pm  
+                my $parentpath = '';
+                my $lastitem = '';
+                if ($thisdisfn =~ m-(.+/)([^/]*)$-) {
+                    $parentpath = $1;
+                    $lastitem = $2;
+                } else {
+                    $lastitem = $thisdisfn;
+                }
+	        $titleinfo = &Apache::loncommon::help_open_menu('','','','',3,'Authoring').
+                      '<font face="Arial, Helvetica, sans-serif"><b>Construction Space</b>:</font>&nbsp;'. 
+                      '<form name="dirs" method="post" action="'.$formaction
+		    .'" target="_top"><tt><b>'
+		    .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv','','+1',1)."<font size=\"+1\">$lastitem</font></b></tt><br />"
+		    .&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()')
+		    .'</form>'
+		    .&Apache::lonmenu::constspaceform();
 
-        return $bodytag.&Apache::lonmenu::menubuttons($forcereg,'web',
-                                                      $forcereg).
-      '<table bgcolor="'.$pgbg.'" width="100%" border="0" cellspacing="3" cellpadding="3"><tr><td rowspan="3" bgcolor="'.$tabbg.'">'.$titleinfo.'</td>'.$roleinfo.'</tr></table>';
+            }
+	    $forcereg=1;
+        }
+        my $titletable = '<table bgcolor="'.$pgbg.'" width="100%" border="0" '.
+                         'cellspacing="3" cellpadding="3">'.
+                         '<tr><td rowspan="3" bgcolor="'.$tabbg.'">'.
+                         $titleinfo.'</td>'.$roleinfo.'</tr></table>';
+        if ($ENV{'request.state'} eq 'construct') {
+            $bodytag .= &Apache::lonmenu::menubuttons($forcereg,'web',$forcereg,$titletable);
+	} else {
+            $bodytag .= &Apache::lonmenu::menubuttons($forcereg,'web',$forcereg).
+                        $titletable;
+        }
+        return $bodytag;
     }
 
 #
@@ -2628,6 +2709,17 @@ ENDROLE
     if ($customtitle) {
         $titleinfo = $customtitle;
     }
+    #
+    # Extra info if you are the DC
+    my $dc_info = '';
+    if ($ENV{'user.adv'} && exists($ENV{'user.role.dc./'.
+                        $ENV{'course.'.$ENV{'request.course.id'}.
+                                 '.domain'}.'/'})) {
+        my $cid = $ENV{'request.course.id'};
+        $dc_info.= $cid.' '.$ENV{'course.'.$cid.'.internal.coursecode'};
+        $dc_info = '('.$dc_info.')';
+    }
+    #
     return(<<ENDBODY);
 $bodytag
 <table width="100%" cellspacing="0" border="0" cellpadding="0">
@@ -2637,7 +2729,7 @@ $upperleft</td>
 </tr>
 <tr>
 <td rowspan="3" bgcolor="$tabbg">
-$titleinfo
+$titleinfo $dc_info
 <td bgcolor="$tabbg" align="right">
 <font size="2" face="Arial, Helvetica, sans-serif">
     $ENV{'environment.firstname'}
@@ -2704,52 +2796,37 @@ Returns number of sections.
 ###############################################
 sub get_sections {
     my ($cdom,$cnum,$sectioncount,$possible_roles) = @_;
+    if (!($cdom && $cnum)) { return 0; }
     my $cid = $cdom.'_'.$cnum;
     my $numsections = 0;
-    if ($cdom && $cnum) {
-        if (!defined($possible_roles) || (grep/^st$/,@$possible_roles)) {
-            my ($classlist) = &Apache::loncoursedata::get_classlist($cid,$cdom,$cnum);
-            my $sec_index = &Apache::loncoursedata::CL_SECTION();
-            my $status_index = &Apache::loncoursedata::CL_STATUS();
-            while (my ($student,$data) = each %$classlist) {
-                my ($section,$status) = ($data->[$sec_index],
-                                         $data->[$status_index]);
-                unless ($section eq '' || $section =~ /^\s*$/) {
-                    if (!defined($$sectioncount{$section})) {
-                        $$sectioncount{$section} = 1;
-                        $numsections ++;
-                    } else {
-                        $$sectioncount{$section} ++;
-                    }
-                }
-            }
-        }
-        my %courseroles = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);
-        foreach my $user (sort keys %courseroles) {
-            if ($user =~ /^(\w{2})/) {
-                my $role = $1;
-                if (!defined($possible_roles) || (grep/^$role$/,@$possible_roles)) {
-                    if ($role eq 'cr') {
-                        if ($user =~ m-^$role/[^/]*/[^/]*/[^/]*:[^:]*:[^:]*:(\w+)-) {
-                            if (!defined($$sectioncount{$1})) {
-                                $$sectioncount{$1} = 1;
-                                $numsections ++;
-                            } else {
-                                $$sectioncount{$1} ++;
-                            }
-                        }
-                    }
-                    if ($user =~ /^$role:[^:]*:[^:]*:(\w+)/) {
-                        if (!defined($$sectioncount{$1})) {
-                            $$sectioncount{$1} = 1;
-                            $numsections ++;
-                        } else {
-                            $$sectioncount{$1} ++;
-                        }
-                    }
-                }
-            }
-        }
+
+    if (!defined($possible_roles) || (grep/^st$/,@$possible_roles)) {
+	my ($classlist) = &Apache::loncoursedata::get_classlist($cid,$cdom,$cnum);
+	my $sec_index = &Apache::loncoursedata::CL_SECTION();
+	my $status_index = &Apache::loncoursedata::CL_STATUS();
+	while (my ($student,$data) = each %$classlist) {
+	    my ($section,$status) = ($data->[$sec_index],
+				     $data->[$status_index]);
+	    unless ($section eq '-1' || $section =~ /^\s*$/) {
+		if (!defined($$sectioncount{$section})) { $numsections++; }
+		$$sectioncount{$section}++;
+	    }
+	}
+    }
+    my %courseroles = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);
+    foreach my $user (sort(keys(%courseroles))) {
+	if ($user !~ /^(\w{2})/) { next; }
+	my ($role) = ($user =~ /^(\w{2})/);
+	if ($possible_roles && !(grep(/^$role$/,@$possible_roles))) { next; }
+	my $section;
+	if ($role eq 'cr' &&
+	    $user =~ m-^$role/[^/]*/[^/]*/[^/]*:[^:]*:[^:]*:(\w+)-) {
+	    $section=$1;
+	}
+	if ($user =~ /^$role:[^:]*:[^:]*:(\w+)/) { $section=$1; }
+	if (!defined($section) || $section eq '-1') { next; }
+	if (!defined($$sectioncount{$section})) { $numsections++; } 
+	$$sectioncount{$section}++;
     }
     return $numsections;
 }
@@ -3361,6 +3438,9 @@ they are plotted.  If undefined, default
 =item @Values: An array of array references.  Each array reference holds data
 to be plotted in a stacked bar chart.
 
+=item If the final element of @Values is a hash reference the key/value
+pairs will be added to the graph definition.
+
 =back
 
 Returns:
@@ -3872,7 +3952,7 @@ sub escape_double {
 #   Escapes the last element of a full URL.
 sub escape_url {
     my ($url)   = @_;
-    my @urlslices = split(/\//, $url);
+    my @urlslices = split(/\//, $url,-1);
     my $lastitem = &Apache::lonnet::escape(pop(@urlslices));
     return join('/',@urlslices).'/'.$lastitem;
 }