--- loncom/homework/edit.pm 2002/03/22 14:45:11 1.31 +++ loncom/homework/edit.pm 2003/09/08 21:10:53 1.61 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # edit mode helpers # -# $Id: edit.pm,v 1.31 2002/03/22 14:45:11 matthew Exp $ +# $Id: edit.pm,v 1.61 2003/09/08 21:10:53 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -31,16 +31,22 @@ package Apache::edit; use strict; -use Apache::lonnet; +use Apache::lonnet(); +use HTML::Entities(); # Global Vars # default list of colors to use in editing @Apache::edit::colorlist=('#ffffff','#ff0000','#00ff00','#0000ff','#0ff000','#000ff0','#f0000f'); # depth of nesting of edit $Apache::edit::colordepth=0; +@Apache::edit::inserttag=(); +# image-type responses: active background image and curdepth at definition +$Apache::edit::bgimgsrc=''; +$Apache::edit::bgimgsrccurdepth=''; sub initialize_edit { $Apache::edit::colordepth=0; + @Apache::edit::inserttag=(); } sub tag_start { @@ -57,10 +63,17 @@ sub tag_start { &deletelist($target,$token) ." ". - &insertlist($target,$token).&end_row().&start_spanning_row(); + &insertlist($target,$token); #". # &movebuttons($target,$token). # "\n"; + my @help;# = Apache::lonxml::helpinfo($token); + if ($help[0]) { + $result .= '' . + Apache::loncommon::help_open_topic(@help) . + ''; + } else { $result .= " "; } + $result .= &end_row().&start_spanning_row(); } return $result; } @@ -69,13 +82,7 @@ sub tag_end { my ($target,$token,$description) = @_; my $result=''; if ($target eq 'edit') { - my $tag=$token->[1]; - if (!defined($description)) { - $result.="</$tag> "; - } else { - if ($description ne '') { $result.="$description "; } - } - $result.="".&end_table()."\n"; + $result.="".&end_table()."\n"; } return $result; } @@ -95,18 +102,32 @@ sub start_table { $color = $Apache::edit::colorlist[$Apache::edit::colordepth]; } $Apache::edit::colordepth++; - my $result=""; + push(@Apache::edit::inserttag,$token->[1]); + my $result='
'; + $result.='
'; return $result; } sub end_table { $Apache::edit::colordepth--; - my $result="
"; + my $result=''; + $result.="
"; + + my ($tagname,$closingtag); + if (defined($Apache::edit::inserttag[-2])) { + $tagname=$Apache::edit::inserttag[-2]; + } else {$tagname='problem';} + if (defined($Apache::edit::inserttag[-1])) { + $closingtag=$Apache::edit::inserttag[-1]; + } + $result.=&innerinsertlist('edit',$tagname,$closingtag). + "
"; + pop(@Apache::edit::inserttag); return $result; } -sub start_spanning_row { return '';} -sub start_row { return ''; } +sub start_spanning_row { return '';} +sub start_row { return ''; } sub end_row { return ''; } sub movebuttons { @@ -142,7 +163,7 @@ sub handle_delete { } if (!$result) { my $endtag='/'.$token->[1]; - my $bodytext=&Apache::lonxml::get_all_text($endtag,$$parser[$#$parser]); + my $bodytext=&Apache::lonxml::get_all_text($endtag,$parser); $$parser['-1']->get_token(); &Apache::lonxml::debug("Deleting :$bodytext: for $token->[1]"); &Apache::lonxml::end_tag($tagstack,$parstack,$token); @@ -151,22 +172,25 @@ sub handle_delete { } sub get_insert_list { - my ($token) = @_; + my ($tagname) = @_; my $result=''; my @tagnums= (); #&Apache::lonxml::debug("keys ".join("\n",sort(keys(%Apache::lonxml::insertlist)))); - if ($Apache::lonxml::insertlist{"$token->[1].which"}) { - push (@tagnums, @{ $Apache::lonxml::insertlist{"$token->[1].which"} }); + if ($Apache::lonxml::insertlist{"$tagname.which"}) { + push (@tagnums, @{ $Apache::lonxml::insertlist{"$tagname.which"} }); } foreach my $namespace (@Apache::lonxml::namespace) { - if ($Apache::lonxml::insertlist{"$namespace".'::'."$token->[1].which"}) { - push (@tagnums, @{ $Apache::lonxml::insertlist{"$namespace".'::'."$token->[1].which"} }); + if ($Apache::lonxml::insertlist{"$namespace".'::'."$tagname.which"}) { + push (@tagnums, @{ $Apache::lonxml::insertlist{"$namespace".'::'."$tagname.which"} }); } } if (@tagnums) { + my %options; foreach my $tagnum (@tagnums) { - $result.='\n"; + my $descrip=$Apache::lonxml::insertlist{"$tagnum.description"}; + $options{$descrip} ="\n"; } + foreach my $option (sort(keys(%options))) { $result.=$options{$option}; } if ($result) { $result=''.$result; } } return $result; @@ -174,12 +198,21 @@ sub get_insert_list { sub insertlist { my ($target,$token) = @_; + return &innerinsertlist($target,$token->[1]); +} + +sub innerinsertlist { + my ($target,$tagname,$closingtag) = @_; my $result; + my $after=''; + if ($closingtag) { + $after='_after_'.$closingtag; + } if ($target eq 'edit') { - my $optionlist= &get_insert_list($token); + my $optionlist= &get_insert_list($tagname); if ($optionlist) { $result = "Insert: - $optionlist " } else { @@ -213,6 +246,32 @@ sub handle_insert { return $result; } +sub handle_insertafter { + my $tagname=shift; + if ($ENV{"form.insert_after_$tagname\_$Apache::lonxml::curdepth"} eq '') + { return ''; } + my $result; + my $tagnum =$ENV{"form.insert_after_$tagname\_$Apache::lonxml::curdepth"}; + my $func=$Apache::lonxml::insertlist{"$tagnum.function"}; + if ($func eq 'default') { + my $newtag=$Apache::lonxml::insertlist{"$tagnum.tag"}; + my $namespace; + if ($newtag =~ /::/) { ($namespace,$newtag) = split(/::/,$newtag); } + $result.="\n<$newtag>\n"; + } else { + if (defined(&$func)) { + { + no strict 'refs'; + $result.=&$func(); + } + } else { + my $newtag=$Apache::lonxml::insertlist{"$tagnum.tag"}; + &Apache::lonxml::error("Unable to insert (after) tag $newtag, $func was not defined. ($tagname $tagnum)"); + } + } + return $result; +} + sub insert_responseparam { return ' '; @@ -245,6 +304,23 @@ sub insert_stringresponse { '; } +sub insert_essayresponse { + return ' + + +'; +} + +sub insert_imageresponse { + return ' + + + + + +'; +} + sub insert_optionresponse { return ' @@ -265,6 +341,28 @@ sub insert_radiobuttonresponse { '; } +sub insert_rankresponse { + return ' + + + + + +'; +} + +sub insert_matchresponse { + return ' + + + + + + + +'; +} + sub insert_displayduedate { return ''; } sub insert_displaytitle { return ''; } sub insert_hintpart { @@ -281,6 +379,30 @@ sub insert_numericalhint { '; } +sub insert_stringhint { + return ' + +'; +} + +sub insert_formulahint { + return ' + +'; +} + +sub insert_radiobuttonhint { + return ' + +'; +} + +sub insert_optionhint { + return ' + +'; +} + sub insert_startouttext { return "\n"; } @@ -293,16 +415,19 @@ sub textarea_sizes { my ($data)=@_; my $count=0; my $maxlength=-1; - foreach (split ("\n", $$data)) { $count++; - if (length($_) > $maxlength) { $maxlength = length($_); } - } + foreach (split ("\n", $$data)) { + $count+=int(length($_)/79); + $count++; + if (length($_) > $maxlength) { $maxlength = length($_); } + } my $rows = $count; my $cols = $maxlength; return ($rows,$cols); } -sub textfield { +sub editline { my ($tag,$data,$description,$size)=@_; + $data=&HTML::Entities::encode($data); if ($description) { $description="
".$description."
"; } my $result = <<"END"; $description @@ -320,7 +445,9 @@ sub editfield { if ($cols < $minwidth ) { $cols = $minwidth; } if ($rows < $minheight) { $rows = $minheight; } if ($description) { $description="
".$description."
"; } - return "$description\n   \n"; + return $description."\n".'   '."\n"; } sub modifiedfield { @@ -338,16 +465,21 @@ sub modifiedfield { # Returns a 1 if the token has been modified and you should rebuild the tag # side-effects, will modify the $token if new values are found sub get_new_args { - my ($token,$parstack,$safeeval,@args)=@_; - my $rebuild=0; - foreach my $arg (@args) { + my ($token,$parstack,$safeeval,@args)=@_; + my $rebuild=0; + foreach my $arg (@args) { #just want the string that it was set to my $value=$token->[2]->{$arg}; - my $newvalue=$ENV{"form.$Apache::lonxml::curdepth.$arg"}; + my $element=&html_element_name($arg); + my $newvalue=$ENV{"form.$element"}; &Apache::lonxml::debug(" for:$arg: cur is :$value: new is :$newvalue:"); - if ($value ne $newvalue) { - $token->[2]->{$arg}=$newvalue; - $rebuild=1; + if (defined($newvalue) && $value ne $newvalue) { + if (ref($newvalue) eq 'ARRAY') { + $token->[2]->{$arg}=join(',',@$newvalue); + } else { + $token->[2]->{$arg}=$newvalue; + } + $rebuild=1; } } return $rebuild; @@ -376,67 +508,211 @@ sub rebuild_tag { return $result; } +sub html_element_name { + my ($name) = @_; + return $name.'_'.$Apache::lonxml::curdepth; +} + +sub hidden_arg { + my ($name,$token) = @_; + my $result; + my $arg=$token->[2]{$name}; + $result=''; + return $result; +} + +sub checked_arg { + my ($description,$name,$list,$token) = @_; + my $result; + my $optionlist=""; + my $allselected=$token->[2]{$name}; + $result=$description; + foreach my $option (@$list) { + my ($value,$text); + if ( ref($option) eq 'ARRAY') { + $value='value="'.$$option[0].'"'; + $text=$$option[1]; + $option=$$option[0]; + } else { + $text=$option; + $value='value="'.$option.'"'; + } + $result.=""); + if ( $selected eq $option ) { + $result.=" checked='on' "; + last; + } + } + $result.=" />$text\n"; + } + return $result; +} + sub text_arg { my ($description,$name,$token,$size) = @_; my $result; if (!defined $size) { $size=20; } my $arg=$token->[2]{$name}; - $result=$description.''; - return $result; + return ''.$result.''; } sub select_arg { - my ($description,$name,$list,$token) = @_; - my $result; - my $optionlist=""; - my $selected=$token->[2]{$name}; - foreach my $option (@$list) { - if ( $selected eq $option ) { - $optionlist.="\n"; - } else { - $optionlist.="\n"; + my ($description,$name,$list,$token) = @_; + my $result; + my $optionlist=""; + my $selected=$token->[2]{$name}; + foreach my $option (@$list) { + my $value; + if ( ref($option) eq 'ARRAY') { + $value='value="'.$$option[0].'"'; + $option=$$option[1]; + } else { + $value='value="'.$option.'"'; + } + if ( $selected eq $option ) { + $optionlist.="\n"; + } else { + $optionlist.="\n"; + } } - } - $result.=$description.' '.$optionlist.' - '; - return $result; + '; + return $result; } sub select_or_text_arg { - my ($description,$name,$list,$token,$size) = @_; - my $result; - my $optionlist=""; - my $found=0; - my $selected=$token->[2]{$name}; - foreach my $option (@$list) { - if ( $selected eq $option ) { - $optionlist.="\n"; - $found=1; - } else { - $optionlist.="\n"; + my ($description,$name,$list,$token,$size) = @_; + my $result; + my $optionlist=""; + my $found=0; + my $selected=$token->[2]{$name}; + foreach my $option (@$list) { + my $value; + if ( ref($option) eq 'ARRAY') { + $value='value="'.$$option[0].'"'; + $option=$$option[1]; + } else { + $value='value="'.$option.'"'; + } + if ( $selected eq $option ) { + $optionlist.="\n"; + $found=1; + } else { + $optionlist.="\n"; + } + } + $optionlist.="\n"; +# + my $element=&html_element_name($name); + my $selectelement='select_list_'.$element; + my $typeinelement='type_in_'.$element; + my $typeinvalue=($found?'':$selected); +# + my $hiddenvalue='this.form.'.$element.'.value'; + my $selectedindex='this.form.'.$selectelement.'.selectedIndex'; + my $selectedvalue='this.form.'.$selectelement. + '.options['.$selectedindex.'].value'; + my $typedinvalue='this.form.'.$typeinelement.'.value'; + my $selecttypeinindex='this.form.'.$selectelement.'.options.length'; +# + return (< +$description +  + + +ENDSELECTORTYPE +} + +#----------------------------------------------------- image coordinates +# single image coordinates, x, y +sub entercoords { + my ($idx,,$idy,$mode,$width,$height) = @_; + unless ($Apache::edit::bgimgsrc) { return ''; } + if ($idx) { $idx.='_'; } + if ($idy) { $idy.='_'; } + my $bgfile=&Apache::lonnet::escape($Apache::edit::bgimgsrc); + my $form = 'lonhomework'; + my $element; + if (! defined($mode) || $mode eq 'attribute') { + $element = &Apache::lonnet::escape("$Apache::lonxml::curdepth"); + } elsif ($mode eq 'textnode') { # for data between ... + $element = &Apache::lonnet::escape('homework_edit_'. + $Apache::lonxml::curdepth); + } + my $formheight=''; + if ($height) { + $formheight='&formheight='.$height.'_'.$Apache::edit::bgimgsrccurdepth; + } + my $formwidth=''; + if ($width) { + $formwidth='&formwidth='.$width.'_'.$Apache::edit::bgimgsrccurdepth; } - } - $optionlist.="\n"; - if ($found) { - $result.=$description.''; - } else { - $result.=&text_arg($description,$name,$token,$size); - } - return $result; + my $result = <<"ENDBUTTON"; +Click Coordinates +ENDBUTTON + return $result; } +# coordinate pair (x1,y1)-(x2,y2) +sub entercoordpair { + my ($id,$mode,$width,$height) = @_; + unless ($Apache::edit::bgimgsrc) { return ''; } + my $bgfile=&Apache::lonnet::escape($Apache::edit::bgimgsrc); + my $form = 'lonhomework'; + my $element; + if (! defined($mode) || $mode eq 'attribute') { + $element = &Apache::lonnet::escape("$id\_$Apache::lonxml::curdepth"); + } elsif ($mode eq 'textnode') { # for data between ... + $element = &Apache::lonnet::escape('homework_edit_'. + $Apache::lonxml::curdepth); + } + my $formheight=''; + if ($height) { + $formheight='&formheight='.$height.'_'.$Apache::edit::bgimgsrccurdepth; + } + my $formwidth=''; + if ($width) { + $formwidth='&formwidth='.$width.'_'.$Apache::edit::bgimgsrccurdepth; + } + my $result = <<"ENDBUTTON"; +Click Coordinate Pair +ENDBUTTON + return $result; +} #----------------------------------------------------- browse sub browse { # insert a link to call up the filesystem browser (lonindexer) - $_ = shift; + my ($id, $mode) = @_; my $form = 'lonhomework'; - my $element = &Apache::lonnet::escape("$Apache::lonxml::curdepth.$_"); + my $element; + if (! defined($mode) || $mode eq 'attribute') { + $element = &Apache::lonnet::escape("$id\_$Apache::lonxml::curdepth"); + } elsif ($mode eq 'textnode') { # for data between ... + $element = &Apache::lonnet::escape('homework_edit_'. + $Apache::lonxml::curdepth); + } my $result = <<"ENDBUTTON"; -Browse +Select ENDBUTTON return $result; } @@ -444,9 +720,15 @@ ENDBUTTON #----------------------------------------------------- browse sub search { # insert a link to call up the filesystem browser (lonindexer) - $_ = shift; + my ($id, $mode) = @_; my $form = 'lonhomework'; - my $element = &Apache::lonnet::escape("$Apache::lonxml::curdepth.$_"); + my $element; + if (! defined($mode) || $mode eq 'attribute') { + $element = &Apache::lonnet::escape("$id\_$Apache::lonxml::curdepth"); + } elsif ($mode eq 'textnode') { # for data between ... + $element = &Apache::lonnet::escape('homework_edit_'. + $Apache::lonxml::curdepth); + } my $result = <<"ENDBUTTON"; Search ENDBUTTON @@ -563,8 +845,8 @@ search($elementname) : provide a link wh searcher (lonsearchcat) and, once a file is selected, place the result in the form element $elementname. -= item * -textfield(tag,data,description,size): Provide a for +=item * +editline(tag,data,description,size): Provide a for single-line text entry. This is to be used for text enclosed by tags, not arguements/parameters associated with a tag.