--- loncom/interface/statistics/lonstathelpers.pm	2011/03/25 01:34:53	1.66
+++ loncom/interface/statistics/lonstathelpers.pm	2020/10/24 19:37:20	1.76.2.5
@@ -1,6 +1,6 @@
 # The LearningOnline Network with CAPA
 #
-# $Id: lonstathelpers.pm,v 1.66 2011/03/25 01:34:53 www Exp $
+# $Id: lonstathelpers.pm,v 1.76.2.5 2020/10/24 19:37:20 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -85,15 +85,15 @@ sub render_resource {
     ##
     ## Render the problem
     my ($base) = ($resource->src =~ m|^(.*/)[^/]*$|);
-    $base="http://".$ENV{'SERVER_NAME'}.$base;
+    $base=&Apache::lonnet::absolute_url().$base;
     my ($src,$symb)=($resource->link,&escape($resource->shown_symb));
     my $rendered_problem = &Apache::lonnet::ssi_body($src.'?symb='.$symb);
     $rendered_problem =~ s/<\s*form\s*/<nop /g;
     $rendered_problem =~ s|(<\s*/form\s*>)|<\/nop>|g;
-    return '<table bgcolor="ffffff"><tr><td>'.
-        '<base href="'.$base.'" />'.
-        $rendered_problem.
-        '</td></tr></table>';
+    return '<div class="LC_Box">'.
+        '<h4 class="LC_hcell">'.&mt('Problem').'</h4>'.
+        '<base href="'.$base.'" />'.$rendered_problem.
+        '</div>';
 }
 
 ####################################################
@@ -135,15 +135,18 @@ Skips 'survey' problems.
 ####################################################
 ####################################################
 sub problem_selector {
-    my ($AcceptedResponseTypes,$sequence_addendum,$symbmode,$all,$prefix,$smallbox,$onclick) = @_;
+    my ($AcceptedResponseTypes,$sequence_addendum,$symbmode,$all,$prefix,
+        $byres,$include_tools,$smallbox,$onclick) = @_;
 # all: also make sequences selectable
 # prefix: prefix for all form names
+# byres: radiobutton shown per resource
+# include_tools: external tools included 
 # smallbox: use smaller box
 # onclick: javascript to execute when clicked
     my $Str;
     my $jsadd='';
     if ($onclick) {
-        $jsadd="onClick='$onclick'";
+        $jsadd="onclick='$onclick'";
     }
     $Str =  &Apache::loncommon::start_scrollbox(($smallbox?'420px':'620px'),
                                                 ($smallbox?'400px':'600px'),
@@ -156,6 +159,36 @@ sub problem_selector {
     foreach my $seq (@sequences) {
         my $seq_str = '';
         foreach my $res (&get_resources($navmap,$seq)) {
+            if ($res->src() eq '/res/lib/templates/simpleproblem.problem') {
+                next if (grep(/^placeholder$/,@{$res->parts}));
+            }
+            my $title = $res->compTitle;
+            if (! defined($title) || $title eq '') {
+                ($title) = ($res->src =~ m:/([^/]*)$:);
+            }
+            my $totalresps = 0;
+            if ($byres) {
+                foreach my $part (@{$res->parts}) {
+                    $totalresps += scalar($res->responseIds($part));
+                }
+                my $value = &HTML::Entities::encode($res->symb(),'<>&"');
+                my $checked;
+                if ($env{'form.problemchoice'} eq $res->symb()) {
+                    $checked = ' checked="checked"';
+                }
+                my $rowspan;
+                if ($totalresps > 1) {
+                    $rowspan = ' rowspan="'.$totalresps.'"';
+                }
+                $seq_str .= &Apache::loncommon::start_data_table_row().
+                            '<td'.$rowspan.' style="vertical-align:top">'.
+                            '<label><input type="radio" name="symb" value="'.$value.'"'.$checked.' />'.
+                            $title.'</label>';
+                my $link = $res->link.'?symb='.&escape($res->shown_symb);
+                $seq_str .= ('&nbsp;'x2).
+                            '<a target="preview" href="'.$link.'">'.&mt('view').'</a></td>';
+            }
+            my %partsseen;
             foreach my $part (@{$res->parts}) {
                 my @response_ids   = $res->responseIds($part);
                 my @response_types = $res->responseType($part);
@@ -163,54 +196,96 @@ sub problem_selector {
                     my $respid = $response_ids[$i];
                     my $resptype = $response_types[$i];
                     if ($resptype =~ m/$AcceptedResponseTypes/) {
-                        my $value = &make_target_id({symb=>$res->symb,
-                                                     part=>$part,
-                                                     respid=>$respid,
-                                                     resptype=>$resptype});
-                        my $checked = '';
-                        if ($env{'form.problemchoice'} eq $value) {
-                            $checked = ' checked="checked"';
-                        }
-                        my $title = $res->compTitle;
-                        if (! defined($title) || $title eq '') {
-                            ($title) = ($res->src =~ m:/([^/]*)$:);
-                        }
-                        $seq_str .=  &Apache::loncommon::start_data_table_row().
-                            ($symbmode?
-                             '<td><input type="radio" id="'.$prefix.$rb_count.'" name="'.$prefix.'symb" value="'.&HTML::Entities::encode($res->symb,'<>&"').'" '.$checked.' '.
-                             $jsadd.
-                             ' /></td>'
-                            :qq{<td><input type="radio" id="$rb_count" name="problemchoice" value="$value"$checked /></td>}).
-                            '<td><label for="'.$prefix.$rb_count.'">'.$resptype.'</label></td>'.
-                            '<td><label for="'.$prefix.$rb_count.'">'.$title.'</label>';
-                        if (scalar(@response_ids) > 1) {
-                            $seq_str .= &mt('response').' '.$respid;
+                        if ($byres) {
+                            if (exists($partsseen{$part})) {
+                                $seq_str .= &Apache::loncommon::continue_data_table_row();
+                            } else {
+                                my $parttitle = $part;
+                                if ($part eq '0') {
+                                    $parttitle = '';
+                                }
+                                if ($parttitle ne '') {
+                                    $parttitle = ('&nbsp;'x2).&mt('part').':&nbsp;'.$parttitle;
+                                }
+                                if (keys(%partsseen)) {
+                                    $seq_str .= &Apache::loncommon::continue_data_table_row();
+                                }
+                                unless ($partsseen{$part}) {
+                                    my $resprowspan;
+                                    if (scalar(@response_ids) > 1) {
+                                        $resprowspan = ' rowspan="'.scalar(@response_ids).'"';
+                                    }
+                                    $seq_str .= '<td'.$resprowspan.' style="vertical-align:top">'.
+                                                $parttitle.'</td>';
+                                    $partsseen{$part} = scalar(@response_ids);
+                                }
+                            }
+                            $seq_str .= '<td>'.$resptype;
+                            if (scalar(@response_ids) > 1) {
+                                $seq_str .= '&nbsp;'.&mt('id').':&nbsp;'.$respid;
+                            }
+                            $seq_str .= '</td>'. &Apache::loncommon::end_data_table_row()."\n";
+                        } else {
+                            my $value = &make_target_id({symb=>$res->symb,
+                                                         part=>$part,
+                                                         respid=>$respid,
+                                                         resptype=>$resptype});
+                            my $checked = '';
+                            if ($env{'form.problemchoice'} eq $value) {
+                                $checked = ' checked="checked"';
+                            }
+                            $seq_str .= &Apache::loncommon::start_data_table_row().
+                                ($symbmode?
+                                 '<td><input type="radio" id="'.$prefix.$rb_count.'" name="'.$prefix.'symb" value="'.&HTML::Entities::encode($res->symb,'<>&"').'" '.$checked.' '.
+                                 $jsadd.
+                                 ' /></td>'
+                                 :qq{<td><input type="radio" id="$rb_count" name="problemchoice" value="$value"$checked /></td>}).
+                                '<td><label for="'.$prefix.$rb_count.'">'.$resptype.'</label></td>'.
+                                '<td><label for="'.$prefix.$rb_count.'">'.$title.'</label>';
+                            if (scalar(@response_ids) > 1) {
+                                $seq_str .= &mt('response').' '.$respid;
+                            }
+                            my $link = $res->link.'?symb='.&escape($res->shown_symb);
+                            $seq_str .= ('&nbsp;'x2).
+                                        '<a target="preview" href="'.$link.'">'.&mt('view').'</a>';
+                            $seq_str .= "</td>". &Apache::loncommon::end_data_table_row()."\n";
                         }
-                        my $link = $res->link.'?symb='.&escape($res->shown_symb);
-                        $seq_str .= ('&nbsp;'x2).
-                            '<a target="preview" href="'.$link.'">'.&mt('view').'</a>';
-                        $seq_str .= "</td>". &Apache::loncommon::end_data_table_row()."\n";
                         $rb_count++;
                     }
                 }
             }
         }
         if ($seq_str ne '') {
-            $Str .= &Apache::loncommon::start_data_table_header_row().
-                '<th colspan="3">'.
-                ($all?'<input type="radio" id="'.$prefix.'s'.$rb_count.'" name="'.$prefix.'symb" value="'.&HTML::Entities::encode($seq->symb,'<>&').'" '.$jsadd.' />':'').
-                $seq->compTitle.'</th>'.
-                &Apache::loncommon::end_data_table_header_row()."\n".$seq_str;
-            if (defined($sequence_addendum)) {
+            if ($byres) {
+                $Str .= &Apache::loncommon::start_data_table_header_row().
+                        '<th colspan="3">'.$seq->compTitle.'</th>'.
+                        &Apache::loncommon::end_data_table_header_row().
+                        $seq_str;
+            } else {
                 $Str .= &Apache::loncommon::start_data_table_header_row().
-                    ('<td>&nbsp;</td>'x2).
-                    '<td align="right">'.$sequence_addendum.'</td>'.
-                    &Apache::loncommon::end_data_table_header_row()."\n";
+                    '<th colspan="3">'.
+                    ($all?'<input type="radio" id="'.$prefix.'s'.$rb_count.'" name="'.$prefix.'symb" value="'.&HTML::Entities::encode($seq->symb,'<>&').'" '.$jsadd.' />':'').
+                    $seq->compTitle.'</th>'.
+                    &Apache::loncommon::end_data_table_header_row()."\n".$seq_str;
+                if (defined($sequence_addendum)) {
+                    $Str .= &Apache::loncommon::start_data_table_header_row().
+                        ('<td>&nbsp;</td>'x2).
+                        '<td align="right">'.$sequence_addendum.'</td>'.
+                        &Apache::loncommon::end_data_table_header_row()."\n";
+                }
             }
         }
-
     }
     $Str .= &Apache::loncommon::end_data_table().&Apache::loncommon::end_scrollbox()."\n";
+    if (!$rb_count) {
+        if ($byres) {
+            $Str = '<p class="LC_info">'.&mt('No gradable problems found').'</p>';
+        } elsif ($AcceptedResponseTypes eq '.') {
+            $Str = '<p class="LC_info">'.&mt('No problems found').'</p>';
+        } else {
+            $Str = '<p class="LC_info">'.&mt('No analyzable problems found').'</p>';
+        }
+    }
     return $Str;
 }
 
@@ -286,7 +361,8 @@ END
 END
     if (ref($anoncounter) eq 'HASH') {
         if (keys(%{$anoncounter}) > 0) {
-            my $anonwarning = &mt('Your selection includes both problems with and without anonymous submissions.').'\n'.&mt('You must select either only anonymous or only named problems.').'\n\n'.&mt('If a selection contains both anonymous and named parts, [_1]use the Anoymous/Named buttons to ensure selections will be either all anonymous [_1]or all named.','\n');
+            my $anonwarning = &mt('Your selection includes both problems with and without anonymous submissions.')."\n".&mt('You must select either only anonymous or only named problems.')."\n\n".&mt('If a selection contains both anonymous and named parts,[_1]use the Anonymous/Named buttons to ensure selections will be either all anonymous[_1]or all named.',"\n");
+            &js_escape(\$anonwarning);
             $checkanonjs = <<"END";
 
 <script type="text/javascript" language="JavaScript">
@@ -716,10 +792,7 @@ sub GetStudentAnswers {
     # Read in the cache (if it exists) before we start timing things.
     &Apache::lonstathelpers::ensure_proper_cache($resource->{'symb'});
     # Open progress window
-    my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin
-        ($r,'Student Answer Compilation Status',
-         'Student Answer Compilation Progress', scalar(@$Students),
-         $status_type,undef,$formname,$inputname);
+    my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,scalar(@$Students));
     $r->rflush();
     foreach my $student (@$Students) {
         last if ($c->aborted());
@@ -1004,7 +1077,7 @@ prior to every analysis lookup.
 sub ensure_proper_cache {
     my ($symb) = @_;
     my $cid = $env{'request.course.id'};
-    my $new_filename =  '/home/httpd/perl/tmp/'.
+    my $new_filename = LONCAPA::tempdir() .
         'problemanalysis_'.$cid.'_analysis_cache.db';
     if (! defined($cache_filename) ||
         $cache_filename ne $new_filename ||
@@ -1388,9 +1461,9 @@ sub limit_by_time_form {
     $Str .= '<fieldset>';
     my $timecheckbox = '<input type="checkbox" name="limit_by_time" ';
     if (&limit_by_time()) {
-        $timecheckbox .= ' checked ';
+        $timecheckbox .= 'checked="checked" ';
     } 
-    $timecheckbox .= 'OnChange="javascript:toggle_limitby_activity(this.checked);" ';
+    $timecheckbox .= 'onchange="javascript:toggle_limitby_activity(this.checked);" ';
     $timecheckbox .= ' />';
     $Str .= '<legend><label>'.&mt('[_1] Limit by time',$timecheckbox).'</label></legend>';
     $Str .= &mt('Start Time: [_1]',$startdateform).'<br />';
@@ -1492,10 +1565,7 @@ sub gather_full_student_data {
     my @Students = @Apache::lonstatistics::Students;
     #
     # Open the progress window
-    my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin
-        ($r,&mt('Student Data Compilation Status'),
-         &mt('Student Data Compilation Progress'), scalar(@Students),
-         $status_type,undef,$formname,$inputname);
+    my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,scalar(@Students));
     #
     while (my $student = shift @Students) {
         return if ($c->aborted());