');
@@ -163,8 +173,6 @@ sub getData {
my ($showPoints,$uname,$udom)=@_;
- &Apache::lonnet::logthis("About to call with $uname $udom");
-
# Create the nav map
my $navmap = Apache::lonnavmaps::navmap->new($uname,$udom);
@@ -366,7 +374,7 @@ sub outputTable {
# If there were any problems at the top level, print an extra "catchall"
if ($topLevelParts > 0) {
my $ratio = $topLevelRight / $topLevelParts;
- my $color = mixColors(\@start, \@end, $ratio);
+ my $color = &mixColors(\@start, \@end, $ratio);
$r->print(&Apache::loncommon::start_data_table_row()
.'');
$r->print(&mt("Problems Not Contained In A Folder")." ");
@@ -378,7 +386,7 @@ sub outputTable {
# show totals (if applicable), close table
#
if ($showPoints) {
- my $maxHelpLink = Apache::loncommon::help_open_topic("Quick_Grades_Possibly_Correct");
+ my $maxHelpLink = &Apache::loncommon::help_open_topic("Quick_Grades_Possibly_Correct");
$title = $showPoints ? "Points" : "Parts Done";
my $totaltitle = $showPoints ? &mt("Awarded Total Points") : &mt("Total Parts Done");
@@ -396,15 +404,340 @@ sub outputTable {
}
#
-# Outputting category-based grades.
+# === Outputting category-based grades.
+#
+# $category{'order'}: output order of categories by id
+# $category{'all'}: complete list of all categories
+# $category{$id.'_name'}: display-name of category
#
sub outputCategories {
my ($r,$showPoints,$notshowTotals,
$navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,$topLevelParts,$topLevelRight,$topLevelAttempted)=@_;
+# Take care of storing and retrieving categories
+
+ my $cangrade=&Apache::lonnet::allowed('mgr');
+
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my %categories=();
+# Loading old categories
+ %categories=&Apache::lonnet::dump('grading_categories',$cdom,$cnum);
+# Storing
+ if (($cangrade) && (($env{'form.storechanges'}) || ($env{'form.storemove'} ne ''))) {
+# Process the changes
+ %categories=&process_category_edits($r,$cangrade,%categories);
+# Actually store
+ &Apache::lonnet::logthis("Storing ".$categories{'order'});
+ &Apache::lonnet::put('grading_categories',\%categories,$cdom,$cnum);
+ }
+# new categories loaded now
+# Form only generated if user can change the grading categories
+ if ($cangrade) {
+ $r->print('');
+ }
+}
+
+#
+# Process editing commands, update category hash
+#
+
+sub process_category_edits {
+ my ($r,$cangrade,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+ my $cmd=$env{'form.cmd'};
+ if ($cmd eq 'createnewcat') {
+ %categories=&make_new_category($r,$cangrade,undef,%categories);
+ } elsif ($cmd=~/^delcat\_(.+)$/) {
+ %categories=&del_category($1,$cangrade,%categories);
+ } else {
+# Simply store the rest of the stuff
+ foreach my $id (split(/\,/,$categories{'order'})) {
+ %categories=&set_category_name($cangrade,$id,$env{'form.name_'.$id},%categories);
+ %categories=&set_category_total($cangrade,$id,$env{'form.totaltype_'.$id},$env{'form.total_'.$id},%categories);
+ %categories=&set_category_weight($cangrade,$id,$env{'form.weight_'.$id},%categories);
+# More changes here
+ }
+ }
+ return %categories;
+}
+
+#
+# Output the table
+#
+
+sub output_category_table {
+ my ($r,$cangrade,$navmaps,%categories)=@_;
+ my $sum=0;
+ my $total=0;
+ $r->print(&Apache::loncommon::start_data_table());
+#
+ &output_category_table_header($r,$cangrade);
+#
+ my @order=split(/\,/,$categories{'order'});
+#
+ my $maxpos=$#order;
+ for (my $i=0;$i<=$maxpos;$i++) {
+ my ($value,$weight)=&output_and_calc_category($r,$cangrade,$navmaps,$order[$i],$i,$maxpos,%categories);
+ $sum+=$value*$weight;
+ $total+=$weight;
+ }
+#
+ &bottom_line_category($r,$cangrade,$sum,$total);
+#
+ $r->print(&Apache::loncommon::end_data_table());
+ return $sum;
+}
+
+sub output_category_table_header {
+ my ($r,$cangrade)=@_;
+ $r->print(&Apache::loncommon::start_data_table_header_row());
+ if ($cangrade) {
+ $r->print(' '.&mt("Move").' '.&mt('Action').' ');
+ }
+ $r->print(''.&mt('Category').' '.
+ ''.&mt('Contents').' '.
+ ''.&mt('Calculation').' '.
+ ''.&mt('Total Points').' '.
+ ''.&mt('Relative Weight').' ');
+ $r->print(&Apache::loncommon::end_data_table_header_row());
+}
+
+
+#
+# Output one category to table
+#
+
+sub output_and_calc_category {
+ my ($r,$cangrade,$navmaps,$id,$currentpos,$maxpos,%categories)=@_;
+ my $value=0;
+ my $weight=0;
+ my $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/");
+ my %lt=&Apache::lonlocal::texthash(
+ 'up' => 'Move Up',
+ 'dw' => 'Move Down');
+ $r->print("\n".&Apache::loncommon::start_data_table_row());
+
+ if ($cangrade) {
+ $r->print(<
+\n\n \n");
+ $r->print(''.&mt('Delete').' ');
+ $r->print(' ');
+ } else {
+ $r->print(''.$categories{$id.'_name'}.' ');
+ }
+# Content
+# FIXME: just placeholders
+ if ($cangrade) {
+ $r->print("Content Edit ");
+ } else {
+ $r->print("Content ");
+ }
+# Calculation
+# FIXME: just placeholders
+ if ($cangrade) {
+ $r->print("Calculation Edit ");
+ } else {
+ $r->print("Calculation ");
+ }
+# Total
+ if ($cangrade) {
+ $r->print(''.
+ ''.
+ ' ');
+ } else {
+ $r->print(''.($categories{$id.'_totaltype'} eq 'default'?&mt('default'):$categories{$id.'_total'}).' ');
+ }
+# Weight
+ if ($cangrade) {
+ $r->print(''.
+ ' ');
+ } else {
+ $r->print(''.$categories{$id.'_weight'}.' ');
+ }
+
+ return ($value,$weight);
}
+#
+# Bottom line with grades
+#
+
+sub bottom_line_category {
+ my ($r,$cangrade,$sum,$total)=@_;
+ $r->print(&Apache::loncommon::start_data_table_row());
+ if ($cangrade) {
+ $r->print(''.&mt('Create New Category').' ');
+ }
+ $r->print(''.&mt('Current:').$sum.'
'.&mt('Total:').$total.'
');
+}
+
+#
+# Make one new category
+#
+
+sub make_new_category {
+ my ($r,$cangrade,$ordernum,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+# Generate new ID
+ my $id=time.'_'.$$.'_'.rand(10000);
+# Add new ID to list of all IDs ever created in this course
+ $categories{'all'}.=','.$id;
+ $categories{'all'}=~s/^\,//;
+# Add new ID to ordered list of displayed and evaluated categories
+ $categories{'order'}.=','.$id;
+ $categories{'order'}=~s/^\,//;
+# Move it into desired space
+ if (defined($ordernum)) {
+ %categories=&move_category($id,$cangrade,$ordernum,%categories);
+ }
+ $categories{$id.'_weight'}=0;
+ $categories{$id.'_totaltype'}='default';
+ return %categories;
+}
+
+#
+# Delete category
+#
+
+sub del_category {
+ my ($id,$cangrade,%categories)=@_;
+ my @neworder=();
+ foreach my $currentid (split(/\,/,$categories{'order'})) {
+ unless ($currentid eq $id) {
+ push(@neworder,$currentid);
+ }
+ }
+ $categories{'order'}=join(',',@neworder);
+ return %categories;
+}
+
+#
+# Move a category to a desired position n the display order
+#
+
+sub move_category {
+ my ($id,$cangrade,$ordernum,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+ my @order=split(/\,/,$categories{'order'});
+# Where is the index currently?
+ my $currentpos=¤t_pos_category($id,%categories);
+ if (defined($currentpos)) {
+ if ($currentpos<$ordernum) {
+# This is moving to a higher index
+# ....X1234....
+# ....1234X....
+ for (my $i=$currentpos;$i<$ordernum;$i++) {
+ $order[$i]=$order[$i+1];
+ }
+ $order[$ordernum]=$id;
+ }
+ if ($currentpos>$ordernum) {
+# This is moving to a lower index
+# ....1234X....
+# ....X1234....
+ for (my $i=$currentpos;$i>$ordernum;$i--) {
+ $order[$i]=$order[$i-1];
+ }
+ $order[$ordernum]=$id;
+ }
+ }
+ $categories{'order'}=join(',',@order);
+ return %categories;
+}
+
+#
+# Find current postion of a category in the order
+#
+
+sub current_pos_category {
+ my ($id,%categories)=@_;
+ my @order=split(/\,/,$categories{'order'});
+ for (my $i=0;$i<=$#order;$i++) {
+ if ($order[$i] eq $id) { return $i; }
+ }
+# not found
+ return undef;
+}
+
+#
+# Set name of a category
+#
+sub set_category_name {
+ my ($cangrade,$id,$name,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+ $categories{$id.'_name'}=$name;
+ return %categories;
+}
+
+#
+# Set total of a category
+#
+sub set_category_total {
+ my ($cangrade,$id,$totaltype,$total,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+ if (($categories{$id.'_total'} eq '') && ($total=~/\d/)) {
+ $totaltype='typein';
+ }
+ $categories{$id.'_totaltype'}=$totaltype;
+ if ($totaltype eq 'default') {
+ $categories{$id.'_total'}='';
+ } else {
+ $total=~s/\D//gs;
+ unless ($total) { $total=0; }
+ $categories{$id.'_total'}=$total;
+ }
+ return %categories;
+}
+
+sub set_category_weight {
+ my ($cangrade,$id,$weight,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+ $weight=~s/\D//gs;
+ unless ($weight) { $weight=0; }
+ $categories{$id.'_weight'}=$weight;
+ return %categories;
+}
+
+#
+# === end category-related
+#
+#
# Pass this two refs to arrays for the start and end color, and a number
# from 0 to 1 for how much of the latter you want to mix in. It will
# return a string ready to show ("#FFC309");
+
+
+
+
+
+
+
+
+
+
+ENDMOVE
+ $r->print("\n'.&mt('Total:').$total.'