--- loncom/interface/lonhelper.pm	2004/08/03 18:41:20	1.84
+++ loncom/interface/lonhelper.pm	2005/01/10 12:15:23	1.92
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # .helper XML handler to implement the LON-CAPA helper
 #
-# $Id: lonhelper.pm,v 1.84 2004/08/03 18:41:20 albertel Exp $
+# $Id: lonhelper.pm,v 1.92 2005/01/10 12:15:23 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1174,6 +1174,13 @@ sub end_choice {
     return '';
 }
 
+{
+    # used to generate unique id attributes for <input> tags. 
+    # internal use only.
+    my $id = 0;
+    sub new_id { return $id++; }
+}
+
 sub render {
     my $self = shift;
     my $var = $self->{'variable'};
@@ -1256,14 +1263,16 @@ BUTTONS
     my $type = "radio";
     if ($self->{'multichoice'}) { $type = 'checkbox'; }
     foreach my $choice (@{$self->{CHOICES}}) {
+        my $id = &new_id();
         $result .= "<tr>\n<td width='20'>&nbsp;</td>\n";
         $result .= "<td valign='top'><input type='$type' name='$var.forminput'"
             . "' value='" . 
-            HTML::Entities::encode($choice->[1],'<>&"') 
+            HTML::Entities::encode($choice->[1],"<>&\"'") 
             . "'";
         if ($checkedChoices{$choice->[1]}) {
             $result .= " checked ";
         }
+        $result .= qq{id="$id"};
         my $choiceLabel = $choice->[0];
         if ($choice->[4]) {  # if we need to evaluate this choice
             $choiceLabel = "sub { my $helper = shift; my $state = shift;" .
@@ -1271,7 +1280,8 @@ BUTTONS
             $choiceLabel = eval($choiceLabel);
             $choiceLabel = &$choiceLabel($helper, $self);
         }
-        $result .= "/></td><td> " . &mtn($choiceLabel) . "</td></tr>\n";
+        $result .= "/></td><td> ".qq{<label for="$id">}.
+            &mtn($choiceLabel). "</label></td></tr>\n";
     }
     $result .= "</table>\n\n\n";
     $result .= $buttons;
@@ -1414,7 +1424,7 @@ sub render {
     $result .= "<select name='${var}.forminput'>\n";
     foreach my $choice (@{$self->{CHOICES}}) {
         $result .= "<option value='" . 
-            HTML::Entities::encode($choice->[1],'<>&"') 
+            HTML::Entities::encode($choice->[1],"<>&\"'") 
             . "'";
         if ($checkedChoices{$choice->[1]}) {
             $result .= " selected";
@@ -1750,7 +1760,7 @@ BEGIN {
     &Apache::lonhelper::register('Apache::lonhelper::resource',
                               ('resource', 'filterfunc', 
                                'choicefunc', 'valuefunc',
-                               'mapurl'));
+                               'mapurl','option'));
 }
 
 sub new {
@@ -1855,6 +1865,42 @@ sub start_mapurl {
 
 sub end_mapurl { return ''; }
 
+
+sub start_option {
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+    if (!defined($paramHash->{OPTION_TEXTS})) {
+	$paramHash->{OPTION_TEXTS} = [ ];
+	$paramHash->{OPTION_VARS}  = [ ];
+
+    }
+    # OPTION_TEXTS is a list of the text attribute
+    #               values used to create column headings.
+    # OPTION_VARS is a list of the variable names, used to create the checkbox
+    #             inputs.
+    #  We're ok with empty elements. as place holders
+    # Although the 'variable' element should really exist.
+    #
+
+    my $option_texts  = $paramHash->{OPTION_TEXTS};
+    my $option_vars   = $paramHash->{OPTION_VARS};
+    push(@$option_texts,  $token->[2]{'text'});
+    push(@$option_vars,   $token->[2]{'variable'});
+
+    #  Need to create and declare the option variables as well to make them
+    # persistent.
+    #
+    my $varname = $token->[2]{'variable'};
+    $helper->declareVar($varname);
+
+
+    return '';
+}
+
+sub end_option {
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+    return '';
+}
+
 # A note, in case I don't get to this before I leave.
 # If someone complains about the "Back" button returning them
 # to the previous folder state, instead of returning them to
@@ -1906,10 +1952,13 @@ BUTTONS
 
     $result .= $buttons;
 
-    my $filterFunc = $self->{FILTER_FUNC};
-    my $choiceFunc = $self->{CHOICE_FUNC};
-    my $valueFunc = $self->{VALUE_FUNC};
-    my $multichoice = $self->{'multichoice'};
+    my $filterFunc     = $self->{FILTER_FUNC};
+    my $choiceFunc     = $self->{CHOICE_FUNC};
+    my $valueFunc      = $self->{VALUE_FUNC};
+    my $multichoice   = $self->{'multichoice'};
+    my $option_vars    = $self->{OPTION_VARS};
+    my $option_texts   = $self->{OPTION_TEXTS};
+    my $headings_done  = 0;
 
     # Evaluate the map url as needed
     my $mapUrl;
@@ -1927,15 +1976,40 @@ BUTTONS
     my $checked = 0;
     my $renderColFunc = sub {
         my ($resource, $part, $params) = @_;
+	my $result = "";
+
+	if(!$headings_done) {
+	    if ($option_texts) {
+		foreach my $text (@$option_texts) {
+		    $result .= "<th>$text</th>";
+		}
+	    }
+	    $result .= "<th>Select</th>";
+	    $result .= "</tr><tr>"; # Close off the extra row and start a new one.
+	    $headings_done = 1;
+	}
 
         my $inputType;
         if ($multichoice) { $inputType = 'checkbox'; }
         else {$inputType = 'radio'; }
 
         if (!&$choiceFunc($resource)) {
-            return '<td>&nbsp;</td>';
+	    $result .= '<td>&nbsp;</td>';
+            return $result;
         } else {
-            my $col = "<td><input type='$inputType' name='${var}.forminput' ";
+	    my $col = "";
+	    my $resource_name =   
+                   HTML::Entities::encode(&$valueFunc($resource),"<>&\"'");
+	    if($option_vars) {
+		foreach my $option_var (@$option_vars) {
+		    $col .= 
+                        "<td align='center'><input type='checkbox' name ='$option_var".
+			".forminput' value='".
+			$resource_name . "' /> </td>";
+		}
+	    }
+
+            $col .= "<td align='center'><input type='$inputType' name='${var}.forminput' ";
             if (!$checked && !$multichoice) {
                 $col .= "checked ";
                 $checked = 1;
@@ -1944,10 +2018,8 @@ BUTTONS
 		$col .= "checked ";
 		$checked = 1;
 	    }
-            $col .= "value='" . 
-                HTML::Entities::encode(&$valueFunc($resource),'<>&"') 
-                . "' /></td>";
-            return $col;
+            $col .= "value='" . $resource_name  . "' /></td>";
+            return $result.$col;
         }
     };
 
@@ -2122,13 +2194,25 @@ SCRIPT
  
         $buttons = <<BUTTONS;
 <br />
-<input type="button" onclick="checkactive()" value="$lt{'ocs'}" />
-<input type="button" onclick="uncheckexpired()" value="$lt{'ues'}" /><br />
-<input type="button" onclick="checkall(true, '$var')" value="$lt{'sas'}" />
-<input type="button" onclick="checkall(false, '$var')" value="$lt{'uas'}" /><br />
-<input type="button" onclick="checksec(true)" value="$lt{'sfsg'}">
-<input type="text" size="5" name="chksec">&nbsp;
-<input type="button" onclick="checksec(false)" value="$lt{'ufsg'}">
+<table>
+  <tr>
+  
+    <td><input type="button" onclick="checkactive()" value="$lt{'ocs'}" /></td>
+    <td><input type="button" onclick="uncheckexpired()" value="$lt{'ues'}" /><br /></td>
+  </tr>
+  <tr>
+     <td><input type="button" onclick="checkall(true, '$var')" value="$lt{'sas'}" /></td>
+     <td> <input type="button" onclick="checkall(false, '$var')" value="$lt{'uas'}" /><br /></td>
+  </tr>
+  <tr>
+      <td><input type="button" onclick="checksec(true)" value="$lt{'sfsg'}"></td>
+      <td><input type="text" size="5" name="chksec">&nbsp;</td>
+  </tr>
+  <tr>
+      <td><input type="button" onclick="checksec(false)" value="$lt{'ufsg'}"></td>
+      <td></td>
+  </tr>
+</table>
 <br />
 BUTTONS
     }
@@ -2207,7 +2291,10 @@ BUTTONS
             $checked = 1;
         }
         $result .=
-            " value='" . HTML::Entities::encode($choice->[0] . ':' . $choice->[2] . ':' . $choice->[1] . ':' . $choice->[3],'<>&"')
+            " value='" . HTML::Entities::encode($choice->[0] . ':' 
+						.$choice->[2] . ':' 
+						.$choice->[1] . ':' 
+						.$choice->[3], "<>&\"'")
             . "' /></td><td>"
             . HTML::Entities::encode($choice->[1],'<>&"')
             . "</td><td align='center'>" 
@@ -2375,6 +2462,13 @@ sub start_filefilter {
 
 sub end_filefilter { return ''; }
 
+{ 
+    # used to generate unique id attributes for <input> tags. 
+    # internal use only.
+    my $id=0;
+    sub new_id { return $id++;}
+}
+
 sub render {
     my $self = shift;
     my $result = '';
@@ -2461,7 +2555,7 @@ BUTTONS
     }
 
     # Sort the fileList into order
-    @fileList = sort @fileList;
+    @fileList = sort {lc($a) cmp lc($b)} @fileList;
 
     $result .= $buttons;
 
@@ -2513,14 +2607,16 @@ BUTTONS
             if ($status eq 'Published' && $helper->{VARS}->{'construction'}) {
                 $onclick = 'onclick="a=1" ';
             }
+            my $id = &new_id();
             $result .= '<tr><td align="right"' . " bgcolor='$color'>" .
                 "<input $onclick type='$type' name='" . $var
-            . ".forminput' value='" . HTML::Entities::encode($fileName,'<>&"').
+            . ".forminput' ".qq{id="$id"}." value='" . HTML::Entities::encode($fileName,"<>&\"'").
                 "'";
             if (!$self->{'multichoice'} && $choices == 0) {
                 $result .= ' checked';
             }
-            $result .= "/></td><td bgcolor='$color'>" . $file . "</td>" .
+            $result .= "/></td><td bgcolor='$color'>".
+                qq{<label for="$id">}. $file . "</label></td>" .
                 "<td bgcolor='$color'>$title</td>" .
                 "<td bgcolor='$color'>$status</td>" . "</tr>\n";
             $choices++;
@@ -2548,10 +2644,14 @@ sub fileState {
     my $constructionSpaceDir = shift;
     my $file = shift;
     
+    my ($uname,$udom)=($ENV{'user.name'},$ENV{'user.domain'});
+    if ($ENV{'request.role'}=~/^ca\./) {
+	(undef,$udom,$uname)=split(/\//,$ENV{'request.role'});
+    }
     my $docroot = $Apache::lonnet::perlvar{'lonDocRoot'};
     my $subdirpart = $constructionSpaceDir;
-    $subdirpart =~ s/^\/home\/$ENV{'user.name'}\/public_html//;
-    my $resdir = $docroot . '/res/' . $ENV{'user.domain'} . '/' . $ENV{'user.name'} .
+    $subdirpart =~ s/^\/home\/$uname\/public_html//;
+    my $resdir = $docroot . '/res/' . $udom . '/' . $uname .
         $subdirpart;
 
     my @constructionSpaceFileStat = stat($constructionSpaceDir . '/' . $file);
@@ -3124,7 +3224,6 @@ sub render {
         my $res = $navmap->getByMapPc($vars->{RESOURCE_ID});
         my $title = $res->compTitle();
         $symb = $res->symb();
-        $navmap->untieHashes();
         $resourceString .= '<li>'.&mt('for the map named [_1]',"<b>$title</b>").'</li>';
         $level = 8;
         $affectedResourceId = $vars->{RESOURCE_ID};
@@ -3134,7 +3233,6 @@ sub render {
         my $res = $navmap->getById($vars->{RESOURCE_ID});
         $symb = $res->symb();
         my $title = $res->compTitle();
-        $navmap->untieHashes();
         $resourceString .= '<li>'.&mt('for the resource named [_1]',"<b>$title</b>").'</li>';
         $level = 7;
         $affectedResourceId = $vars->{RESOURCE_ID};
@@ -3194,7 +3292,7 @@ sub render {
         $result .= '<li>'.&mt('for section [_1]',"<b>$section</b>").'</li>';
         $level -= 3;
         $result .= "<input type='hidden' name='csec' value='" .
-            HTML::Entities::encode($section,'<>&"') . "' />\n";
+            HTML::Entities::encode($section,"'<>&\"") . "' />\n";
     } else {
         # FIXME: This is probably wasteful! Store the name!
         my $classlist = Apache::loncoursedata::get_classlist();
@@ -3206,9 +3304,9 @@ sub render {
         $level -= 6;
         my ($uname, $udom) = split /:/, $vars->{USER_NAME};
         $result .= "<input type='hidden' name='uname' value='".
-            HTML::Entities::encode($uname,'<>&"') . "' />\n";
+            HTML::Entities::encode($uname,"'<>&\"") . "' />\n";
         $result .= "<input type='hidden' name='udom' value='".
-            HTML::Entities::encode($udom,'<>&"') . "' />\n";
+            HTML::Entities::encode($udom,"'<>&\"") . "' />\n";
     }
 
     # Print value