[system] / branches / rel-2-3-dev / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / ProblemList.pm Repository:
ViewVC logotype

View of /branches/rel-2-3-dev/webwork2/lib/WeBWorK/ContentGenerator/Instructor/ProblemList.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4396 - (download) (as text) (annotate)
Thu Aug 24 21:07:52 2006 UTC (6 years, 9 months ago)
File size: 21852 byte(s)
This commit was manufactured by cvs2svn to create branch 'rel-2-3-dev'.

    1 ################################################################################
    2 # WeBWorK Online Homework Delivery System
    3 # Copyright © 2000-2006 The WeBWorK Project, http://openwebwork.sf.net/
    4 # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/Instructor/ProblemList.pm,v 1.37 2006/07/12 01:19:15 gage Exp $
    5 #
    6 # This program is free software; you can redistribute it and/or modify it under
    7 # the terms of either: (a) the GNU General Public License as published by the
    8 # Free Software Foundation; either version 2, or (at your option) any later
    9 # version, or (b) the "Artistic License" which comes with this package.
   10 #
   11 # This program is distributed in the hope that it will be useful, but WITHOUT
   12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   13 # FOR A PARTICULAR PURPOSE.  See either the GNU General Public License or the
   14 # Artistic License for more details.
   15 ################################################################################
   16 
   17 package WeBWorK::ContentGenerator::Instructor::ProblemList;
   18 use base qw(WeBWorK::ContentGenerator::Instructor);
   19 
   20 =head1 NAME
   21 
   22 WeBWorK::ContentGenerator::Instructor::ProblemList - List and edit problems in a set
   23 
   24 =cut
   25 
   26 # This file is currently in an intermediate form, at best.  The look
   27 # for global editting has changed significantly.  The look for dealing
   28 # with a single student is pretty much the same as before, except for
   29 # rendering the problems.
   30 
   31 # For now, this leaves the code in a clumsy state, with the two versions
   32 # given in their entirety different clauses of an if-then-else.
   33 
   34 use strict;
   35 use warnings;
   36 #use CGI qw(-nosticky );
   37 use WeBWorK::CGI;
   38 use WeBWorK::Utils qw(readDirectory list2hash max);
   39 use WeBWorK::DB::Record::Set;
   40 use WeBWorK::Utils::Tasks qw(renderProblems);
   41 
   42 
   43 use constant PROBLEM_FIELDS =>[qw(source_file value max_attempts)];
   44 use constant PROBLEM_USER_FIELDS => [qw(problem_seed status num_correct num_incorrect)];
   45 
   46 sub problemElementHTML {
   47   my ($fieldName, $fieldValue, $size, $override, $overrideValue) = @_;
   48   my $attributeHash = {type => "text", name => $fieldName, value => $fieldValue};
   49   $attributeHash->{size} = $size if defined $size;
   50   my $html;
   51 # my $html = CGI::input($attributeHash);
   52 
   53   unless (defined $override) {
   54     $html = CGI::input($attributeHash);
   55   } else {
   56     $html = $fieldValue;
   57     $attributeHash->{name} = "${fieldName}.override";
   58     $attributeHash->{value} = ($override ? $overrideValue : "");
   59     $html = "default:" . CGI::br() . $html . CGI::br()
   60       . CGI::checkbox({
   61         type => "checkbox",
   62         name => "override",
   63         label => "override:",
   64         value => $fieldName,
   65         checked => ($override ? 1 : 0)
   66       })
   67       . CGI::br()
   68       . CGI::input($attributeHash);
   69   }
   70 
   71   return $html;
   72 }
   73 
   74 sub problem_number_popup {
   75   my $num = shift;
   76   my $total = shift;
   77   return (CGI::popup_menu(-name => "problem_num_$num",
   78         -values => [1..$total],
   79         -default => $num));
   80 }
   81 
   82 sub handle_problem_numbers {
   83   my $newProblemNumbersref = shift;
   84   my %newProblemNumbers = %$newProblemNumbersref;
   85   my $maxNum = shift;
   86   my $db = shift;
   87   my $setName = shift;
   88   my $force = shift || 0;
   89   my @sortme=();
   90   my ($j, $val);
   91 
   92   foreach $j (keys %newProblemNumbers) {
   93     # what happens our first time on this page
   94     return "" if (not defined $newProblemNumbers{"$j"});
   95     if ($newProblemNumbers{"$j"} != $j) {
   96       $force = 1;
   97       $val = 1000 * $newProblemNumbers{$j} - $j;
   98     } else {
   99       $val = 1000 * $newProblemNumbers{$j};
  100     }
  101     push @sortme, [$j, $val];
  102     $newProblemNumbers{$j} = $db->getGlobalProblem($setName, $j);
  103     die "global $j for set $setName not found." unless $newProblemNumbers{$j};
  104   }
  105 
  106   return "" unless $force;
  107 
  108   @sortme = sort {$a->[1] <=> $b->[1]} @sortme;
  109   # now, for global and each user with this set, loop through problem list
  110   #   get all of the problem records
  111   # assign new problem numbers
  112   # loop - if number is new, put the problem record
  113   # print "Sorted to get ". join(', ', map {$_->[0] } @sortme) ."<p>\n";
  114 
  115 
  116   # Now, three stages.  First global values
  117 
  118   for ($j = 0; $j < scalar @sortme; $j++) {
  119     if($sortme[$j]->[0] == $j + 1) {
  120       # do nothing
  121     } elsif (not defined $newProblemNumbers{$j + 1}) {
  122       $newProblemNumbers{$sortme[$j]->[0]}->problem_id($j + 1);
  123       $db->addGlobalProblem($newProblemNumbers{$sortme[$j]->[0]});
  124     } else {
  125       $newProblemNumbers{$sortme[$j]->[0]}->problem_id($j + 1);
  126       $db->putGlobalProblem($newProblemNumbers{$sortme[$j]->[0]});
  127     }
  128   }
  129 
  130   my @setUsers = $db->listSetUsers($setName);
  131   my (@problist, $user);
  132 
  133   foreach $user (@setUsers) {
  134     for $j (keys %newProblemNumbers) {
  135       $problist[$j] = $db->getUserProblem($user, $setName, $j);
  136       die " problem $j for set $setName and effective user $user not found"
  137         unless $problist[$j];
  138     }
  139     # ok, now we have all problem data for $user
  140     for($j = 0; $j < scalar @sortme; $j++) {
  141       if ($sortme[$j]->[0] == $j + 1) {
  142         # do nothing
  143       } elsif (not defined $newProblemNumbers{$j + 1}) {
  144         $problist[$sortme[$j]->[0]]->problem_id($j + 1);
  145         $db->addUserProblem($problist[$sortme[$j]->[0]]);
  146       } else {
  147         $problist[$sortme[$j]->[0]]->problem_id($j + 1);
  148         $db->putUserProblem($problist[$sortme[$j]->[0]]);
  149       }
  150     }
  151   }
  152 
  153 
  154   foreach ($j = scalar @sortme; $j < $maxNum; $j++) {
  155     if (defined $newProblemNumbers{$j + 1}) {
  156       $db->deleteGlobalProblem($setName, $j+1);
  157     }
  158   }
  159 
  160   return join(', ', map {$_->[0]} @sortme);
  161 }
  162 
  163 # swap index given with next bigger index
  164 # leftover from when we had up/down buttons
  165 # maybe we will bring them back
  166 
  167 sub moveme {
  168   my $index = shift;
  169   my $db = shift;
  170   my $setName = shift;
  171   my (@problemList) = @_;
  172   my ($prob1, $prob2, $prob);
  173 
  174   foreach $prob (@problemList) {
  175     my $problemRecord = $db->getGlobalProblem($setName, $prob); # checked
  176     die "global $prob for set $setName not found." unless $problemRecord;
  177     if ($problemRecord->problem_id == $index) {
  178       $prob1 = $problemRecord;
  179     } elsif ($problemRecord->problem_id == $index + 1) {
  180       $prob2 = $problemRecord;
  181     }
  182   }
  183   if (not defined $prob1 or not defined $prob2) {
  184     die "cannot find problem $index or " . ($index + 1);
  185   }
  186 
  187   $prob1->problem_id($index + 1);
  188   $prob2->problem_id($index);
  189   $db->putGlobalProblem($prob1);
  190   $db->putGlobalProblem($prob2);
  191 
  192   my @setUsers = $db->listSetUsers($setName);
  193 
  194   my $user;
  195   foreach $user (@setUsers) {
  196     $prob1 = $db->getUserProblem($user, $setName, $index); #checked
  197     die " problem $index for set $setName and effective user $user not found"
  198       unless $prob1;
  199     $prob2 = $db->getUserProblem($user, $setName, $index+1); #checked
  200     die " problem $index for set $setName and effective user $user not found"
  201       unless $prob2;
  202         $prob1->problem_id($index+1);
  203     $prob2->problem_id($index);
  204     $db->putUserProblem($prob1);
  205     $db->putUserProblem($prob2);
  206   }
  207 }
  208 
  209 
  210 sub initialize {
  211   my ($self)    = @_;
  212   my $r         = $self->r;
  213   my $db        = $r->db;
  214   my $ce        = $r->ce;
  215   my $authz     = $r->authz;
  216   my $user      = $r->param('user');
  217   my $setName   = $r->urlpath->arg("setID");
  218   my $setRecord = $db->getGlobalSet($setName); # checked
  219   die "global set $setName  not found." unless $setRecord;
  220 
  221   $self->{set}  = $setRecord;
  222   my @editForUser = $r->param('editForUser');
  223   # some useful booleans
  224   my $forUsers   = scalar(@editForUser);
  225   my $forOneUser = $forUsers == 1;
  226 
  227   # Check permissions
  228   return unless ($authz->hasPermissions($user, "access_instructor_tools"));
  229   return unless ($authz->hasPermissions($user, "modify_problem_sets"));
  230 
  231   # build a quick lookup table
  232   my %overrides = list2hash $r->param('override');
  233 
  234   my @problemList = $db->listGlobalProblems($setName);  # the Problem form was submitted
  235   if (defined($r->param('submit_problem_changes'))) {
  236     foreach my $problem (@problemList) {
  237       my $problemRecord = $db->getGlobalProblem($setName, $problem); # checked
  238       die "global $problem for set $setName not found." unless $problemRecord;
  239 
  240       foreach my $field (@{PROBLEM_FIELDS()}) {
  241         my $paramName = "problem.${problem}.${field}";
  242         if (defined($r->param($paramName))) {
  243           my $pvalue = $r->param($paramName);
  244           if ($field eq "max_attempts") {
  245             $pvalue =~ s/[^-\d]//g;
  246             $pvalue = -1 if $pvalue eq "";
  247           }
  248           $problemRecord->$field($pvalue);
  249         }
  250       }
  251       $db->putGlobalProblem($problemRecord);
  252 
  253       if ($forOneUser) {
  254         my $userProblemRecord = $db->getUserProblem($editForUser[0], $setName, $problem); # checked
  255         die " problem $problem for set $setName and effective user $editForUser[0] not found" unless $userProblemRecord;
  256         foreach my $field (@{PROBLEM_USER_FIELDS()}) {
  257           my $paramName = "problem.${problem}.${field}";
  258           if (defined($r->param($paramName))) {
  259             $userProblemRecord->$field($r->param($paramName));
  260           }
  261         }
  262 
  263         foreach my $field (@{PROBLEM_FIELDS()}) {
  264           my $paramName = "problem.${problem}.${field}";
  265           if (defined($r->param("${paramName}.override"))) {
  266             if (exists $overrides{$paramName}) {
  267               $userProblemRecord->$field($r->param("${paramName}.override"));
  268             } else {
  269               $userProblemRecord->$field(undef);
  270             }
  271           }
  272         }
  273 
  274         # the attempted field has to be computed from num correct and num incorrect
  275         my $attempted = ($userProblemRecord->num_correct+$userProblemRecord->num_incorrect > 0) ? 1 : 0;
  276         $userProblemRecord->attempted($attempted);
  277         $db->putUserProblem($userProblemRecord);
  278       }
  279     }
  280 
  281     foreach my $problem ($r->param('deleteProblem')) {
  282       $db->deleteGlobalProblem($setName, $problem);
  283     }
  284 
  285   } else {
  286     # Look for up and down buttons
  287     my $index = 2;
  288     while ($index <= scalar @problemList) {
  289       if (defined $r->param("move.up.$index.x")) {
  290         moveme($index-1, $db, $setName, @problemList);
  291       }
  292       $index++;
  293     }
  294     $index = 1;
  295 
  296     while ($index < scalar @problemList) {
  297       if (defined $r->param("move.down.$index.x")) {
  298         moveme($index, $db, $setName, @problemList);
  299       }
  300       $index++;
  301     }
  302   }
  303 }
  304 
  305 sub title {
  306   my ($self)    = @_;
  307   my $r         = $self->r;
  308   my $setName   = $r->urlpath->arg("setID");
  309 
  310   #print "\n<!-- BEGIN " . __PACKAGE__ . "::title -->\n";
  311   print $r->urlpath->name. " for set $setName ";
  312   #print "<!-- END " . __PACKAGE__ . "::title -->\n";
  313 
  314   return "";
  315 }
  316 
  317 sub body {
  318   my ($self)      = @_;
  319   my $r           = $self->r;
  320   my $db          = $r->db;
  321   my $ce          = $r->ce;
  322   my $authz       = $r->authz;
  323   my $user        = $r->param('user');
  324   my $urlpath     = $r->urlpath;
  325   my $courseName  = $urlpath->arg("courseID");
  326   my $setName     = $urlpath->arg("setID");
  327   my $setRecord   = $db->getGlobalSet($setName);
  328   die "Global set $setName not found." unless $setRecord;
  329   my @editForUser = $r->param('editForUser');
  330 
  331   my $problemListPage  = $urlpath -> newFromModule($urlpath->module, courseID => $courseName, setID => $setName);
  332   my $problemListURL   = $self->systemLink($problemListPage,authen=>0);
  333   # some useful booleans
  334   my $forUsers    = scalar(@editForUser);
  335   my $forOneUser  = $forUsers == 1;
  336   my $editForUserName = $editForUser[0];
  337 
  338   # Check permissions
  339   return CGI::div({class=>"ResultsWithError"}, "You are not authorized to access the Instructor tools.")
  340     unless $authz->hasPermissions($r->param("user"), "access_instructor_tools");
  341 
  342   return CGI::div({class=>"ResultsWithError"}, "You are not authorized to modify problems.")
  343     unless $authz->hasPermissions($r->param("user"), "modify_problem_sets");
  344 
  345   my $userCount        = $db->listUsers();
  346   my $setUserCount     = $db->countSetUsers($setName);
  347   my $editUsersAssignedToSetURL = $self->systemLink(
  348         $urlpath->newFromModule(
  349                 "WeBWorK::ContentGenerator::Instructor::UsersAssignedToSet",
  350                   courseID => $courseName, setID => $setName));
  351 
  352   my $userCountMessage = CGI::a({href=>$editUsersAssignedToSetURL},
  353     $self->userCountMessage($setUserCount, $userCount));
  354 
  355   $userCountMessage = "The set $setName is assigned to " . $userCountMessage . ".";
  356 
  357   if (@editForUser) {
  358     print CGI::p("$userCountMessage  Editing user-specific overrides for ". CGI::b(join ", ", @editForUser));
  359   } else {
  360     print CGI::p($userCountMessage);
  361   }
  362 
  363   ## Problems Form ##
  364   my @problemList = $db->listGlobalProblems($setName);
  365   print CGI::a({name=>"problems"});
  366 #   print CGI::h2({}, "Problems");
  367 
  368   my %newProblemNumbers = ();
  369   my $maxProblemNumber = -1;
  370   for my $jj (@problemList) {
  371     $newProblemNumbers{$jj} = $r->param('problem_num_' . $jj);
  372     $maxProblemNumber = $jj if $jj > $maxProblemNumber;
  373   }
  374 
  375   my $forceRenumber = $r->param('force_renumber') || 0;
  376 #print "<p> old order: ".join(', ', @problemList);
  377 #print "<p> new order: ". handle_problem_numbers(\%newProblemNumbers, $maxProblemNumber, $db, $setName, $forceRenumber);
  378   handle_problem_numbers(\%newProblemNumbers, $maxProblemNumber, $db, $setName, $forceRenumber);
  379 
  380   @problemList = $db->listGlobalProblems($setName); #reload them
  381 
  382   if (scalar @problemList) {
  383     # This will contain the mode list control
  384     my $problemWord = 'Display&nbsp;Mode:&nbsp;';
  385     my %display_modes = %{WeBWorK::PG::DISPLAY_MODES()};
  386     my @active_modes = grep { exists $display_modes{$_} } @{$r->ce->{pg}->{displayModes}};
  387     push @active_modes, 'None';
  388     my $default_mode = $r->param('mydisplaymode') || 'None';
  389     $problemWord .= CGI::popup_menu(-name => "mydisplaymode",
  390             -values => \@active_modes,
  391             -default => $default_mode);
  392     $problemWord .= '&nbsp;'. CGI::input({type => "submit", name => "refresh", value => "Refresh"});
  393 
  394     if($forUsers) {
  395 ############### Order things differently.  This is for one user
  396     print CGI::start_form({method=>"POST", action=>$problemListURL.'#problems'});
  397     print CGI::start_table({border=>1, cellpadding=>4});
  398     print CGI::Tr({}, CGI::th({}, [
  399       ($forUsers ? () : ("Delete?")),
  400       "Problem",
  401       ($forUsers ? ("Status", "Problem Seed") : ()),
  402       #"Source File",
  403             $problemWord, "Max. Attempts", "Weight",
  404       ($forUsers ? ("Number Correct", "Number Incorrect") : ())
  405     ]));
  406     foreach my $problem (sort {$a <=> $b} @problemList) {
  407       my $problemRecord = $db->getGlobalProblem($setName, $problem); # checked
  408       die "global problem $problem in set $setName not found." unless $problemRecord;
  409       my $problemID = $problemRecord->problem_id;
  410       my $userProblemRecord;
  411       my %problemOverrideArgs;
  412       my @problem_html;
  413       my $userSet =  $db->getUserSet($editForUser[0], $setName); # checked
  414       die "user homework set $setName not found." unless $userSet;
  415 
  416       if ($forOneUser) {
  417         $userProblemRecord = $db->getUserProblem($editForUser[0], $setName, $problem); # checked
  418         die "problem $problem for set $setName and user $editForUser[0] not found. " unless $userProblemRecord;
  419         foreach my $field (@{PROBLEM_FIELDS()}) {
  420           $problemOverrideArgs{$field} = [defined $userProblemRecord->$field && $userProblemRecord->$field ne '', $userProblemRecord->$field];
  421         }
  422         @problem_html = renderProblems(r=> $r,
  423                               user => $db->getUser($editForUser[0]),
  424                               displayMode=> $default_mode,
  425                               problem_number=> $problem,
  426                               this_set=> $userSet,
  427                   problem_seed=> $userProblemRecord->problem_seed,
  428                               problem_list =>[$problemRecord->source_file]);
  429 
  430   #   } elsif ($forUsers) {
  431   #     foreach my $field (@{PROBLEM_FIELDS()}) {
  432   #       $problemOverrideArgs{$field} = ["", ""];
  433   #     }
  434       } else {
  435         foreach my $field (@{PROBLEM_FIELDS()}) {
  436           $problemOverrideArgs{$field} = [undef, undef];
  437         }
  438       }
  439 
  440       print CGI::Tr({},
  441         CGI::td({}, [
  442           ($forUsers ? () : (CGI::input({type=>"checkbox", name=>"deleteProblem", value=>$problemID}))),
  443           "$problemID "
  444             . CGI::a({href=>$self->systemLink( $urlpath->new(type=>'problem_detail',
  445                                                             args=>{courseID =>$courseName,setID=>$setName,problemID=>$problemID}
  446                                                             ),
  447                                                params =>{effectiveUser => $editForUserName}
  448                                              )}, "view"
  449             ) . " "
  450             . CGI::a({href=>$self->systemLink( $urlpath->new(type=>'instructor_problem_editor_withset_withproblem',
  451                                                             args=>{courseID =>$courseName,setID=>$setName,problemID=>$problemID}
  452                                                             )
  453                                              )}, "edit"
  454             ),
  455           ($forUsers ? (
  456             problemElementHTML("problem.${problemID}.status", $userProblemRecord->status, "7"),
  457             problemElementHTML("problem.${problemID}.problem_seed", $userProblemRecord->problem_seed, "7"),
  458           ) : ()),
  459           problemElementHTML("problem.${problemID}.source_file", $problemRecord->source_file, "40", @{$problemOverrideArgs{source_file}}) .
  460 
  461           CGI::br(). CGI::div({class=> "RenderSolo"}, $problem_html[0]->{body_text})
  462 ,
  463           problemElementHTML("problem.${problemID}.max_attempts",$problemRecord->max_attempts,"7", @{$problemOverrideArgs{max_attempts}}),
  464           problemElementHTML("problem.${problemID}.value",$problemRecord->value,"7", @{$problemOverrideArgs{value}}),
  465           ($forUsers ? (
  466             problemElementHTML("problem.${problemID}.num_correct", $userProblemRecord->num_correct, "7"),
  467             problemElementHTML("problem.${problemID}.num_incorrect", $userProblemRecord->num_incorrect, "7")
  468           ) : ())
  469         ])
  470 
  471       )
  472     }
  473     print CGI::end_table();
  474     print $self->hiddenEditForUserFields(@editForUser);
  475     print $self->hidden_authen_fields;
  476     print CGI::input({type=>"submit", name=>"submit_problem_changes", value=>"Save Problem Changes"});
  477     print CGI::end_form();
  478         } else {
  479 ################################ Second go for global version
  480 ################################ forUsers will be false
  481 
  482     print CGI::start_form({method=>"POST", action=>$problemListURL.'#problems'});
  483     print CGI::start_table({border=>1, cellpadding=>4});
  484     print CGI::Tr({}, CGI::th({}, [
  485       "Data",
  486       $problemWord
  487     ]));
  488     my (%shown_yet) = ();
  489     foreach my $problem (sort {$a <=> $b} @problemList) {
  490       my $problemRecord = $db->getGlobalProblem($setName, $problem); # checked
  491       die "global problem $problem in set $setName not found." unless $problemRecord;
  492       my $problemID = $problemRecord->problem_id;
  493       my $userProblemRecord;
  494       my %problemOverrideArgs;
  495       my $have_this_one = '';
  496       if(defined($shown_yet{$problemRecord->source_file})) {
  497         $have_this_one = "This problem uses the same source file as number " . $shown_yet{$problemRecord->source_file} . ".";
  498       } else {
  499         $shown_yet{$problemRecord->source_file} = $problemID;
  500       }
  501 
  502       my @problem_html = renderProblems(r=> $r,
  503                             user => $db->getUser($user),
  504                             displayMode=> $default_mode,
  505                             problem_number=> $problem,
  506                             problem_list =>[$problemRecord->source_file]);
  507 
  508 
  509       foreach my $field (@{PROBLEM_FIELDS()}) {
  510         $problemOverrideArgs{$field} = [undef, undef];
  511       }
  512 
  513       print CGI::Tr({},
  514         CGI::td({}, [
  515                 problem_number_popup($problemID, $maxProblemNumber) .
  516                 '&nbsp;'.
  517                 CGI::a({href=>$self->systemLink(
  518                   $urlpath->new(type=>'instructor_problem_editor_withset_withproblem',
  519                     args=>{courseID =>$courseName,setID=>$setName,problemID=>$problemID}
  520                   )
  521                 ), target=>"WW_Editor"}, "Edit it" ) .
  522                 '&nbsp;'.
  523               CGI::a({href=>$self->systemLink( $urlpath->new(type=>'problem_detail',
  524                 args=>{courseID =>$courseName,setID=>$setName,problemID=>$problemID}
  525                  ),
  526                 params =>{effectiveUser => $editForUserName}  ), target=>"WW_View"}, "Try it") .
  527 
  528               CGI::br() .
  529               CGI::start_table().
  530               CGI::Tr({}, CGI::td({-align=>"right"}, "Delete?"),
  531                 CGI::td({-align=>"left"}, CGI::input({type=>"checkbox",
  532                   name=>"deleteProblem", value=>$problemID}))).
  533                 CGI::Tr({}, CGI::td({-align=>"right"}, 'Max&nbsp;Attempts:'),
  534                   CGI::td({-align=>"left"}, CGI::input({type=>"text",
  535                     name=>"problem.${problemID}.max_attempts",
  536                     value=>
  537                       (($problemRecord->max_attempts<0)? "unlim": $problemRecord->max_attempts), size=>"4"}))).
  538                   CGI::Tr({}, CGI::td({-align=>"right"}, 'Weight:'),
  539                     CGI::td({-align=>"left"}, CGI::input({type=>"text",
  540                       name=>"problem.${problemID}.value",
  541                       value=>$problemRecord->value, size=>"4"}))).
  542               CGI::end_table(),
  543 
  544               problemElementHTML("problem.${problemID}.source_file",
  545                 $problemRecord->source_file, "50",
  546                 @{$problemOverrideArgs{source_file}}) .
  547 
  548               CGI::br().
  549               CGI::div({class=> "RenderSolo"}, $problem_html[0]->{body_text})
  550                 . ($have_this_one ? CGI::div({class=>"ResultsWithError",
  551                   style=>"font-weight: bold"}, $have_this_one) : '') ,
  552         ]) # end of table entry
  553       ) # end of table row
  554     } # end of loop over problems
  555     print CGI::end_table();
  556     print $self->hiddenEditForUserFields(@editForUser);
  557     print $self->hidden_authen_fields;
  558     print CGI::checkbox({
  559           label=> "Force problems to be numbered consecutively from one",
  560           name=>"force_renumber", value=>"1"}),
  561 
  562       CGI::br();
  563     print CGI::input({type=>"submit", name=>"submit_problem_changes", value=>"Save Problem Changes"});
  564     print CGI::p(<<HERE);
  565 Any time problem numbers are intentionally changed, the problems will
  566 always be renumbered consecutively, starting from one.  When deleting
  567 problems, gaps will be left in the numbering unless the box above is
  568 checked.
  569 HERE
  570                 print CGI::p("It is before the open date.  You probably want to renumber the problems if you are deleting some from the middle.") if ($setRecord->open_date>time());
  571     print CGI::p("When changing problem numbers, we will move
  572  the problem to be ", CGI::em("before"), " the chosen number.");
  573 
  574     print CGI::end_form();
  575 
  576         }
  577 
  578   } else {
  579     print CGI::p("This set doesn't contain any problems yet.");
  580   }
  581 
  582   return "";
  583 }
  584 
  585 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9