--- loncom/homework/imageresponse.pm 2005/06/22 12:03:23 1.72 +++ loncom/homework/imageresponse.pm 2008/12/21 05:22:01 1.94.2.1 @@ -1,8 +1,8 @@ - +# # The LearningOnline Network with CAPA # image click response style # -# $Id: imageresponse.pm,v 1.72 2005/06/22 12:03:23 albertel Exp $ +# $Id: imageresponse.pm,v 1.94.2.1 2008/12/21 05:22:01 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -37,6 +37,9 @@ use Apache::londefdef(); use Apache::Constants qw(:common :http); use Apache::lonlocal; use Apache::lonnet; +use lib '/home/httpd/lib/perl/'; +use LONCAPA; + BEGIN { &Apache::lonxml::register('Apache::imageresponse',('imageresponse')); @@ -56,19 +59,54 @@ sub start_imageresponse { $result=&Apache::response::meta_package_write('imageresponse'); } elsif ($target eq 'analyze') { my $part_id="$Apache::inputtags::part.$id"; + $Apache::lonhomework::analyze{"$part_id.type"} = 'imageresponse'; push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id); + push (@{ $Apache::lonhomework::analyze{"$part_id.bubble_lines"} }, + 1); + } elsif ( $target eq 'edit' ) { + $result .= &Apache::edit::tag_start($target,$token). + &Apache::edit::text_arg('Max Number Of Shown Foils:', + 'max',$token,'4'). + &Apache::edit::end_row(). + &Apache::edit::start_spanning_row(); + } elsif ( $target eq 'modified' ) { + my $constructtag= + &Apache::edit::get_new_args($token,$parstack,$safeeval,'max'); + if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); } } return $result; } sub end_imageresponse { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; - &Apache::response::end_response; - pop @Apache::lonxml::namespace; + + my $part_id = $Apache::inputtags::part; + my $response_id = $Apache::inputtags::response[-1]; + + pop(@Apache::lonxml::namespace); &Apache::lonxml::deregister('Apache::imageresponse',('foilgroup','foil','text','image','rectangle','conceptgroup')); + my $result; - if ($target eq 'edit') { $result=&Apache::edit::end_table(); } + if ($target eq 'edit') { + $result=&Apache::edit::end_table(); + } elsif ($target eq 'tex' + && $Apache::lonhomework::type eq 'exam') { + $result=&Apache::inputtags::exam_score_line($target); + } + undef(%Apache::response::foilnames); + + if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' || + $target eq 'tex' || $target eq 'analyze') { + &Apache::lonxml::increment_counter(&Apache::response::repetition(), + "$part_id.$response_id"); + if ($target eq 'analyze') { + &Apache::lonhomework::set_bubble_lines(); + } + + } + &Apache::response::end_response(); + return $result; } @@ -86,42 +124,54 @@ sub getfoilcounts { my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,'-2'); # +1 since instructors will count from 1 my $count = $#{ $Apache::response::foilgroup{'names'} }+1; - #if (&Apache::response::showallfoils()) { $max=$count; } + if (&Apache::response::showallfoils()) { $max=$count; } return ($count,$max); } sub whichfoils { my ($max)=@_; - if (!defined(@{ $Apache::response::foilgroup{'names'} })) { return; } + return if (!defined(@{ $Apache::response::foilgroup{'names'} })); my @names = @{ $Apache::response::foilgroup{'names'} }; - my @whichopt =(); + my @whichopt; while ((($#whichopt+1) < $max) && ($#names > -1)) { &Apache::lonxml::debug("Have $#whichopt max is $max"); my $aopt; -# if (&Apache::response::showallfoils()) { -# $aopt=0; -# } else { + if (&Apache::response::showallfoils()) { + $aopt=0; + } else { $aopt=int(&Math::Random::random_uniform() * ($#names+1)); -# } + } &Apache::lonxml::debug("From $#names elms, picking $aopt"); $aopt=splice(@names,$aopt,1); &Apache::lonxml::debug("Picked $aopt"); - push (@whichopt,$aopt); + push(@whichopt,$aopt); } return @whichopt; } sub prep_image { my ($image,$mode,$name)=@_; - my $part=$Apache::inputtags::part; - my $respid=$Apache::inputtags::response['-1']; + + my ($x,$y)= &get_submission($name); + &Apache::lonxml::debug("for $name drawing click at $x and $y"); + &draw_image($mode,$image,$x,$y,$Apache::response::foilgroup{"$name.area"}); +} + +sub draw_image { + my ($mode,$image,$x,$y,$areas) = @_; + my $id=&Apache::loncommon::get_cgi_id(); + my (%x,$i); - $x{"cgi.$id.BGIMG"}=&Apache::lonnet::escape($image); - my ($x,$y)=split(/:/,$Apache::lonhomework::history{"resource.$part.$respid.submission"}); + $x{"cgi.$id.BGIMG"}=&escape($image); + #draws 2 xs on the image at the clicked location #one in white and then one in red on top of the one in white - if (defined($x) && $x=~/\S/ && defined($y) && $y =~/\S/ && !&Apache::response::show_answer()) { + + if (defined($x) && $x =~/\S/ + && defined($y) && $y =~/\S/ + && ($mode eq 'submission' || !&Apache::response::show_answer()) + && $mode ne 'answeronly') { my $length = 6; my $width = 1; my $extrawidth = 2; @@ -147,11 +197,10 @@ sub prep_image { $x{"cgi.$id.OBJ$i"}=join(':',(($xmin),($ymax),($xmax),($ymin), "FF0000",($width))); } - if ($mode eq 'answer') { + if ($mode eq 'answer' || $mode eq 'answeronly') { my $width = 1; my $extrawidth = 2; - my @areas = @{ $Apache::response::foilgroup{"$name.area"} }; - foreach my $area (@areas) { + foreach my $area (@{ $areas }) { if ($area=~/^rectangle:/) { $x{"cgi.$id.OBJTYPE"}.='RECTANGLE:'; $i=$x{"cgi.$id.OBJCOUNT"}++; @@ -174,24 +223,26 @@ sub prep_image { } } } - &Apache::lonnet::appenv(%x); + &Apache::lonnet::appenv(\%x); return $id; } sub displayfoils { my ($target,@whichopt) = @_; my $result =''; - my $name; my $temp=1; - foreach $name (@whichopt) { + my @images; + foreach my $name (@whichopt) { $result.=$Apache::response::foilgroup{"$name.text"}; &Apache::lonxml::debug("Text is $result"); if ($target eq 'tex') {$result.="\\vskip 0 mm \n";} else {$result.="
\n";} my $image=$Apache::response::foilgroup{"$name.image"}; &Apache::lonxml::debug("image is $image"); - if ( $target eq 'web' && $image !~ /^http:/ ) { + if ( ($target eq 'web' || $target eq 'answer') + && $image !~ /^https?\:/ ) { $image=&clean_up_image($image); - } + } + push(@images,$image); &Apache::lonxml::debug("image is $image"); if ( &Apache::response::show_answer() ) { if ($target eq 'tex') { @@ -204,15 +255,64 @@ sub displayfoils { if ($target eq 'tex') { $result.=$Apache::response::foilgroup{"$name.image"}."\\vskip 0 mm \n"; } else { - my $id=$Apache::inputtags::response['-1']; - my $token=&prep_image($image); - my $temp=1; - $result.="
\n"; + my $respid=$Apache::inputtags::response['-1']; + my $token=&prep_image($image,'submission',$name); + my $input_id = "HWVAL_$respid:$temp"; + my $id = $env{'form.request.prefix'}.$input_id; + $result.=''. + '
'. + ''. + ''; } } $temp++; } + if ($target eq 'web') { + &Apache::response::setup_prior_tries_hash(\&format_prior_response, + [\@images,\@whichopt]); + } + return $result; +} + +sub format_prior_response { + my ($mode,$answer,$other_data) = @_; + + my $result; + + # make a copy of the data in the refs + my @images = @{ $other_data->[0] }; + my @foils = @{ $other_data->[1] }; + foreach my $name (@foils) { + my $image = pop(@images); + my ($x,$y) = &get_submission($name,$answer); + my $token = &draw_image('submission',$image,$x,$y); + $result .= + '
'; + } + return $result; +} + +sub display_answers { + my ($target,$whichopt)=@_; + + my $result=&Apache::response::answer_header('imageresponse'); + foreach my $name (@$whichopt) { + my $image=$Apache::response::foilgroup{"$name.image"}; + &Apache::lonxml::debug("image is $image"); + if ( ($target eq 'web' || $target eq 'answer') + && $image !~ /^https?\:/ ) { + $image = &clean_up_image($image); + } + my $token=&prep_image($image,'answeronly',$name); + + $result.=&Apache::response::answer_part('imageresponse',"
\n"); + } + $result.=&Apache::response::answer_footer('imageresponse'); return $result; } @@ -220,7 +320,7 @@ sub clean_up_image { my ($image)=@_; if ($image =~ /\s*$max) { $count=$max } &Apache::lonxml::debug("Count is $count from $max"); + @whichopt = &whichfoils($max); + if ($target eq 'web' || $target eq 'tex') { $result=&displayfoils($target,@whichopt); + $Apache::lonxml::post_evaluate=0; } elsif ($target eq 'grade') { if ( defined $env{'form.submitted'}) { &gradefoils(@whichopt); } } elsif ( $target eq 'analyze') { &Apache::response::analyze_store_foilgroup(\@whichopt, ['text','image','area']); + } elsif ($target eq 'answer' + && $env{'form.answer_output_mode'} ne 'tex') { + $result=&display_answers($target,\@whichopt); } + } elsif ($target eq 'edit') { $result=&Apache::edit::end_table(); } @@ -345,18 +491,19 @@ sub start_foil { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' || - $target eq 'analyze') { + $target eq 'analyze' || $target eq 'answer') { my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval); if ($name eq "") { - &Apache::lonxml::warning("Foils without names exist. This can cause problems to malfunction."); + &Apache::lonxml::warning(&mt('Foils without names exist. This can cause problems to malfunction.')); $name=$Apache::lonxml::curdepth; } if (defined($Apache::response::foilnames{$name})) { - &Apache::lonxml::error(&mt("Foil name [_1] appears more than once. Foil names need to be unique.",$name)); + &Apache::lonxml::error(&mt("Foil name [_1] appears more than once. Foil names need to be unique." + ,''.$name.'')); } $Apache::response::foilnames{$name}++; if ( $Apache::imageresponse::conceptgroup - #&& !&Apache::response::showallfoils() + && !&Apache::response::showallfoils() ) { push(@{ $Apache::response::conceptgroup{'names'} }, $name); } else { @@ -388,10 +535,11 @@ sub end_foil { sub start_text { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; - if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') { + if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze' + || $target eq 'answer') { &Apache::lonxml::startredirection; } elsif ($target eq 'edit') { - my $descr=&Apache::lonxml::get_all_text('/text',$parser); + my $descr=&Apache::lonxml::get_all_text('/text',$parser,$style); $result=&Apache::edit::tag_start($target,$token,'Task Description'). &Apache::edit::editfield($token->[1],$descr,'Text',60,2). &Apache::edit::end_row(); @@ -404,10 +552,11 @@ sub start_text { sub end_text { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; - if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') { + if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze' + || $target eq 'answer') { my $name = $Apache::imageresponse::curname; if ( $Apache::imageresponse::conceptgroup - #&& !&Apache::response::showallfoils() + && !&Apache::response::showallfoils() ) { $Apache::response::conceptgroup{"$name.text"} = &Apache::lonxml::endredirection; } else { @@ -422,16 +571,18 @@ sub end_text { sub start_image { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; - if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') { + my $only = join(',',&Apache::loncommon::filecategorytypes('Pictures')); + if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze' + || $target eq 'answer') { &Apache::lonxml::startredirection; } elsif ($target eq 'edit') { - my $bgimg=&Apache::lonxml::get_all_text('/image',$parser); + my $bgimg=&Apache::lonxml::get_all_text('/image',$parser,$style); $Apache::edit::bgimgsrc=$bgimg; $Apache::edit::bgimgsrcdepth=$Apache::lonxml::curdepth; $result=&Apache::edit::tag_start($target,$token,'Clickable Image'). &Apache::edit::editline($token->[1],$bgimg,'Image Source File',40); - $result.=&Apache::edit::browse(undef,'textnode').' '; + $result.=&Apache::edit::browse(undef,'textnode',undef,$only).' '; $result.=&Apache::edit::search(undef,'textnode'). &Apache::edit::end_row(); } elsif ($target eq "modified") { @@ -444,11 +595,11 @@ sub end_image { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; my $name = $Apache::imageresponse::curname; - if ($target eq 'web') { + if ($target eq 'web' || $target eq 'answer') { my $image = &Apache::lonxml::endredirection(); &Apache::lonxml::debug("original image is $image"); if ( $Apache::imageresponse::conceptgroup - #&& !&Apache::response::showallfoils() + && !&Apache::response::showallfoils() ) { $Apache::response::conceptgroup{"$name.image"} = $image; } else { @@ -457,7 +608,7 @@ sub end_image { } elsif ($target eq 'analyze') { my $image = &Apache::lonxml::endredirection(); if ( $Apache::imageresponse::conceptgroup - #&& !&Apache::response::showallfoils() + && !&Apache::response::showallfoils() ) { $Apache::response::conceptgroup{"$name.image"} = $image; } else { @@ -499,10 +650,10 @@ sub start_rectangle { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' || - $target eq 'analyze') { + $target eq 'analyze' || $target eq 'answer') { &Apache::lonxml::startredirection; } elsif ($target eq 'edit') { - my $coords=&Apache::lonxml::get_all_text('/rectangle',$parser); + my $coords=&Apache::lonxml::get_all_text('/rectangle',$parser,$style); $result=&Apache::edit::tag_start($target,$token,'Rectangle'). &Apache::edit::editline($token->[1],$coords,'Coordinate Pairs',40). &Apache::edit::entercoord(undef,'textnode',undef,undef,'box'). @@ -531,13 +682,13 @@ sub end_rectangle { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' || - $target eq 'analyze') { + $target eq 'analyze' || $target eq 'answer') { my $name = $Apache::imageresponse::curname; my $area = &Apache::lonxml::endredirection; $area=~s/\s//g; &Apache::lonxml::debug("out is $area for $name"); if ( $Apache::imageresponse::conceptgroup - #&& !&Apache::response::showallfoils() + && !&Apache::response::showallfoils() ) { push @{ $Apache::response::conceptgroup{"$name.area"} },"rectangle:$area"; } else { @@ -553,10 +704,10 @@ sub start_polygon { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' || - $target eq 'analyze') { + $target eq 'analyze' || $target eq 'answer') { &Apache::lonxml::startredirection; } elsif ($target eq 'edit') { - my $coords=&Apache::lonxml::get_all_text('/polygon',$parser); + my $coords=&Apache::lonxml::get_all_text('/polygon',$parser,$style); $result=&Apache::edit::tag_start($target,$token,'Polygon'). &Apache::edit::editline($token->[1],$coords,'Coordinate list',40). &Apache::edit::entercoord(undef,'textnode',undef,undef,'polygon'). @@ -612,13 +763,13 @@ sub end_polygon { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; if ($target eq 'web' || $target eq 'grade' || $target eq 'tex' || - $target eq 'analyze') { + $target eq 'analyze' || $target eq 'answer') { my $name = $Apache::imageresponse::curname; my $area = &Apache::lonxml::endredirection; $area=~s/\s*//g; &Apache::lonxml::debug("out is $area for $name"); if ( $Apache::imageresponse::conceptgroup - #&& !&Apache::response::showallfoils() + && !&Apache::response::showallfoils() ) { push @{ $Apache::response::conceptgroup{"$name.area"} },"polygon:$area"; } else { 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.