[system] / branches / rel-2-4-patches / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / SetMaker.pm Repository:
ViewVC logotype

Diff of /branches/rel-2-4-patches/webwork2/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 3401 Revision 3402
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v 1.38 2005/07/22 22:34:53 jj Exp $ 4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v 1.39 2005/07/22 22:54:57 jj Exp $
5# 5#
6# This program is free software; you can redistribute it and/or modify it under 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 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 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. 9# version, or (b) the "Artistic License" which comes with this package.
29 29
30use CGI::Pretty qw(); 30use CGI::Pretty qw();
31use WeBWorK::Form; 31use WeBWorK::Form;
32use WeBWorK::Utils qw(readDirectory max sortByName); 32use WeBWorK::Utils qw(readDirectory max sortByName);
33use WeBWorK::Utils::Tasks qw(renderProblems); 33use WeBWorK::Utils::Tasks qw(renderProblems);
34use File::Find;
34 35
35require WeBWorK::Utils::ListingDB; 36require WeBWorK::Utils::ListingDB;
36 37
37use constant MAX_SHOW_DEFAULT => 20; 38use constant MAX_SHOW_DEFAULT => 20;
38use constant NO_LOCAL_SET_STRING => 'No sets in this course yet'; 39use constant NO_LOCAL_SET_STRING => 'No sets in this course yet';
39use constant SELECT_SET_STRING => 'Select a Set for This Course'; 40use constant SELECT_SET_STRING => 'Select a Set from this Course';
40use constant SELECT_LOCAL_STRING => 'Select a Problem Collection'; 41use constant SELECT_LOCAL_STRING => 'Select a Problem Collection';
41use constant MY_PROBLEMS => ' My Problems '; 42use constant MY_PROBLEMS => ' My Problems ';
42use constant MAIN_PROBLEMS => ' Main Problems '; 43use constant MAIN_PROBLEMS => ' Main Problems ';
43use constant CREATE_SET_BUTTON => 'Create New Set'; 44use constant CREATE_SET_BUTTON => 'Create New Set';
44 45
127 my $top = ($dir eq '.')? 1 : 2; 128 my $top = ($dir eq '.')? 1 : 2;
128 my @pgs = get_library_pgs($top,$templates,$dir); 129 my @pgs = get_library_pgs($top,$templates,$dir);
129 return sortByName(undef,@pgs); 130 return sortByName(undef,@pgs);
130} 131}
131 132
133## Search for set definition files
134
135# initialize global variable for search
136my @found_set_defs = ();
137
138sub get_set_defs_wanted {
139 my $fn = $_;
140 my $fdir = $File::Find::dir;
141 return() if($fn !~ /^set.*\.def$/);
142 #return() if(not -T $fn);
143 push @found_set_defs, "$fdir/$fn";
144}
145
146sub get_set_defs {
147 my $topdir = shift;
148 @found_set_defs = ();
149 find({ wanted => \&get_set_defs_wanted, follow_fast=>1}, $topdir);
150 map { $_ =~ s|^$topdir/?|| } @found_set_defs;
151 return @found_set_defs;
152}
153
154## Try to make reading of set defs more flexible. Additional strategies
155## for fixing a path can be added here.
156
157sub munge_pg_file_path {
158 my $self = shift;
159 my $pg_path = shift;
160 my $path_to_set_def = shift;
161 my $end_path = $pg_path;
162 # if the path is ok, don't fix it
163 return($pg_path) if(-e $self->r->ce->{courseDirs}{templates}."/$pg_path");
164 # if we have followed a link into a self contained course to get
165 # to the set.def file, we need to insert the start of the path to
166 # the set.def file
167 $end_path = "$path_to_set_def/$pg_path";
168 return($end_path) if(-e $self->r->ce->{courseDirs}{templates}."/$end_path");
169 # if we got this far, this path is bad, but we let it produce
170 # an error so the user knows there is a troublesome path in the
171 # set.def file.
172 return($pg_path);
173}
174
175## Read a set definition file. This could be abstracted since it happens
176## elsewhere. Here we don't have to process so much of the file.
177
178sub read_set_def {
179 my $self = shift;
180 my $r = $self->r;
181 my $filePathOrig = shift;
182 my $filePath = $r->ce->{courseDirs}{templates}."/$filePathOrig";
183 $filePathOrig =~ s/set.*\.def$//;
184 $filePathOrig =~ s|/$||;
185 $filePathOrig = "." if ($filePathOrig !~ /\S/);
186 my @pg_files = ();
187 my ($line, $got_to_pgs, $name, @rest) = ("", 0, "");
188 if ( open (SETFILENAME, "$filePath") ) {
189 while($line = <SETFILENAME>) {
190 chomp($line);
191 $line =~ s|(#.*)||; # don't read past comments
192 if($got_to_pgs) {
193 unless ($line =~ /\S/) {next;} # skip blank lines
194 ($name,@rest) = split (/\s*,\s*/,$line);
195 $name =~ s/\s*//g;
196 push @pg_files, $name;
197 } else {
198 $got_to_pgs = 1 if ($line =~ /problemList\s*=/);
199 }
200 }
201 } else {
202 $self->addbadmessage("Cannot open $filePath");
203 }
204 # This is where we would potentially munge the pg file paths
205 # One possibility
206 @pg_files = map { $self->munge_pg_file_path($_, $filePathOrig) } @pg_files;
207 return(@pg_files);
208}
209
132## go through past page getting a list of identifiers for the problems 210## go through past page getting a list of identifiers for the problems
133## and whether or not they are selected, and whether or not they should 211## and whether or not they are selected, and whether or not they should
134## be hidden 212## be hidden
135 213
136sub get_past_problem_files { 214sub get_past_problem_files {
361 CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)), 439 CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)),
362 CGI::end_table(), 440 CGI::end_table(),
363 )); 441 ));
364} 442}
365 443
444##### Version 4 is the set definition file panel
445
446sub browse_setdef_panel {
447 my $self = shift;
448 my $r = $self->r;
449 my $ce = $r->ce;
450 my $library_selected = shift;
451 my $default_value = "Select a Set Definition File";
452 my @list_of_set_defs = get_set_defs($ce->{courseDirs}{templates});
453 if(scalar(@list_of_set_defs) == 0) {
454 @list_of_set_defs = (NO_LOCAL_SET_STRING);
455 } elsif (not $library_selected or $library_selected eq $default_value) {
456 unshift @list_of_set_defs, $default_value;
457 $library_selected = $default_value;
458 }
459 my $view_problem_line = view_problems_line('view_setdef_set', 'View Problems', $self->r);
460 my $popupetc = CGI::popup_menu(-name=> 'library_sets',
461 -values=>\@list_of_set_defs,
462 -default=> $library_selected).
463 CGI::br(). $view_problem_line;
464 if($list_of_set_defs[0] eq NO_LOCAL_SET_STRING) {
465 $popupetc = "there are no set definition files in this course to look at."
466 }
467 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "Browse from: ",
468 $popupetc
469 ));
470}
471
366sub make_top_row { 472sub make_top_row {
367 my $self = shift; 473 my $self = shift;
368 my $r = $self->r; 474 my $r = $self->r;
369 my $ce = $r->ce; 475 my $ce = $r->ce;
370 my %data = @_; 476 my %data = @_;
371 477
372 my $list_of_local_sets = $data{all_set_defs}; 478 my $list_of_local_sets = $data{all_db_sets};
373 my $have_local_sets = scalar(@$list_of_local_sets); 479 my $have_local_sets = scalar(@$list_of_local_sets);
374 my $browse_which = $data{browse_which}; 480 my $browse_which = $data{browse_which};
375 my $library_selected = $r->param('library_sets'); 481 my $library_selected = $r->param('library_sets');
376 my $set_selected = $r->param('local_sets'); 482 my $set_selected = $r->param('local_sets');
377 483
378 my ($dis1, $dis2, $dis3) = ("","",""); 484 my ($dis1, $dis2, $dis3, $dis4) = ("","","", "");
379 $dis1 = '-disabled' if($browse_which eq 'browse_library'); 485 $dis1 = '-disabled' if($browse_which eq 'browse_library');
380 $dis2 = '-disabled' if($browse_which eq 'browse_local'); 486 $dis2 = '-disabled' if($browse_which eq 'browse_local');
381 $dis3 = '-disabled' if($browse_which eq 'browse_mysets'); 487 $dis3 = '-disabled' if($browse_which eq 'browse_mysets');
488 $dis4 = '-disabled' if($browse_which eq 'browse_setdefs');
382 489
383 ## Make buttons for additional problem libraries 490 ## Make buttons for additional problem libraries
384 my $libs = ''; 491 my $libs = '';
385 foreach my $lib (sort(keys(%problib))) { 492 foreach my $lib (sort(keys(%problib))) {
386 $libs .= ' '. CGI::submit(-name=>"browse_$lib", -value=>$problib{$lib}, 493 $libs .= ' '. CGI::submit(-name=>"browse_$lib", -value=>$problib{$lib},
392 my $these_widths = "width: 23ex"; 499 my $these_widths = "width: 23ex";
393 500
394 if($have_local_sets ==0) { 501 if($have_local_sets ==0) {
395 $list_of_local_sets = [NO_LOCAL_SET_STRING]; 502 $list_of_local_sets = [NO_LOCAL_SET_STRING];
396 } elsif (not $set_selected or $set_selected eq SELECT_SET_STRING) { 503 } elsif (not $set_selected or $set_selected eq SELECT_SET_STRING) {
397 if ($list_of_local_sets->[0] eq "Select a Homework Set") {
398 shift @{$list_of_local_sets};
399 }
400 unshift @{$list_of_local_sets}, SELECT_SET_STRING; 504 unshift @{$list_of_local_sets}, SELECT_SET_STRING;
401 $set_selected = SELECT_SET_STRING; 505 $set_selected = SELECT_SET_STRING;
402 } 506 }
403 my $myjs = 'document.mainform.selfassign.value=confirm("Should I assign the new set to you now?\nUse OK for yes and Cancel for no.");true;'; 507 my $myjs = 'document.mainform.selfassign.value=confirm("Should I assign the new set to you now?\nUse OK for yes and Cancel for no.");true;';
404 508
420 -override=>1, -size=>30), 524 -override=>1, -size=>30),
421 )); 525 ));
422 526
423 print CGI::Tr(CGI::td({-bgcolor=>"black"})); 527 print CGI::Tr(CGI::td({-bgcolor=>"black"}));
424 528
529 # Tidy this list up since it is used in two different places
530 if ($list_of_local_sets->[0] eq SELECT_SET_STRING) {
531 shift @{$list_of_local_sets};
532 }
533
425 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, 534 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"},
426 "Browse ", 535 "Browse ",
427 CGI::submit(-name=>"browse_library", -value=>"Problem Library", -style=>$these_widths, $dis1), 536 CGI::submit(-name=>"browse_library", -value=>"Problem Library", -style=>$these_widths, $dis1),
428 CGI::submit(-name=>"browse_local", -value=>"Local Problems", -style=>$these_widths, $dis2), 537 CGI::submit(-name=>"browse_local", -value=>"Local Problems", -style=>$these_widths, $dis2),
429 CGI::submit(-name=>"browse_mysets", -value=>"From This Course", -style=>$these_widths, $dis3), 538 CGI::submit(-name=>"browse_mysets", -value=>"From This Course", -style=>$these_widths, $dis3),
539 CGI::submit(-name=>"browse_setdefs", -value=>"Set Definition Files", -style=>$these_widths, $dis4),
430 $libs, 540 $libs,
431 )); 541 ));
432 542
433 print CGI::Tr(CGI::td({-bgcolor=>"black"})); 543 print CGI::Tr(CGI::td({-bgcolor=>"black"}));
434 544
436 $self->browse_local_panel($library_selected); 546 $self->browse_local_panel($library_selected);
437 } elsif ($browse_which eq 'browse_mysets') { 547 } elsif ($browse_which eq 'browse_mysets') {
438 $self->browse_mysets_panel($library_selected, $list_of_local_sets); 548 $self->browse_mysets_panel($library_selected, $list_of_local_sets);
439 } elsif ($browse_which eq 'browse_library') { 549 } elsif ($browse_which eq 'browse_library') {
440 $self->browse_library_panel(); 550 $self->browse_library_panel();
551 } elsif ($browse_which eq 'browse_setdefs') {
552 $self->browse_setdef_panel($library_selected);
441 } else { ## handle other problem libraries 553 } else { ## handle other problem libraries
442 $self->browse_local_panel($library_selected,$browse_which); 554 $self->browse_local_panel($library_selected,$browse_which);
443 } 555 }
444 556
445 print CGI::Tr(CGI::td({-bgcolor=>"black"})); 557 print CGI::Tr(CGI::td({-bgcolor=>"black"}));
620 $use_previous_problems = 0; @pg_files = (); ## clear old problems 732 $use_previous_problems = 0; @pg_files = (); ## clear old problems
621 } elsif ($r->param('browse_mysets')) { 733 } elsif ($r->param('browse_mysets')) {
622 $browse_which = 'browse_mysets'; 734 $browse_which = 'browse_mysets';
623 $r->param('library_sets', ""); 735 $r->param('library_sets', "");
624 $use_previous_problems = 0; @pg_files = (); ## clear old problems 736 $use_previous_problems = 0; @pg_files = (); ## clear old problems
737 } elsif ($r->param('browse_setdefs')) {
738 $browse_which = 'browse_setdefs';
739 $r->param('library_sets', "");
740 $use_previous_problems = 0; @pg_files = (); ## clear old problems
625 741
626 ##### Change the seed value 742 ##### Change the seed value
627 743
628 } elsif ($r->param('rerandomize')) { 744 } elsif ($r->param('rerandomize')) {
629 $problem_seed++; 745 $problem_seed++;
664 } else { 780 } else {
665 my @problemList = $db->listGlobalProblems($set_to_display); 781 my @problemList = $db->listGlobalProblems($set_to_display);
666 my $problem; 782 my $problem;
667 @pg_files=(); 783 @pg_files=();
668 for $problem (@problemList) { 784 for $problem (@problemList) {
669 my $problemRecord = $db->getGlobalProblem($set_to_display, $problem); # checked 785 my $problemRecord = $db->getGlobalProblem($set_to_display, $problem); # checked
670 die "global $problem for set $set_to_display not found." unless 786 die "global $problem for set $set_to_display not found." unless
671 $problemRecord; 787 $problemRecord;
672 push @pg_files, $problemRecord->source_file; 788 push @pg_files, $problemRecord->source_file;
673 789
674 } 790 }
675 $use_previous_problems=0; 791 $use_previous_problems=0;
676 } 792 }
677 793
690 for $result (@dbsearch) { 806 for $result (@dbsearch) {
691 $tolibpath = "Library/$result->{path}/$result->{filename}"; 807 $tolibpath = "Library/$result->{path}/$result->{filename}";
692 808
693 ## Too clunky!!!! 809 ## Too clunky!!!!
694 push @pg_files, $tolibpath; 810 push @pg_files, $tolibpath;
811 }
812 $use_previous_problems=0;
813
814 ##### View a set from a set*.def
815
816 } elsif ($r->param('view_setdef_set')) {
817
818 my $set_to_display = $r->param('library_sets');
819 if (not defined($set_to_display)
820 or $set_to_display eq "Select a Set Definition File"
821 or $set_to_display eq NO_LOCAL_SET_STRING) {
822 $self->addbadmessage("You need to select a set from this course to view.");
823 } else {
824 @pg_files= $self->read_set_def($set_to_display);
695 } 825 }
696 $use_previous_problems=0; 826 $use_previous_problems=0;
697 827
698 ##### Edit the current local problem set 828 ##### Edit the current local problem set
699 829
810 } ##### end of the if elsif ... 940 } ##### end of the if elsif ...
811 941
812 942
813 ############# List of local sets 943 ############# List of local sets
814 944
815 my @all_set_defs = $db->listGlobalSets; 945 my @all_db_sets = $db->listGlobalSets;
816 @all_set_defs = sortByName(undef, @all_set_defs); 946 @all_db_sets = sortByName(undef, @all_db_sets);
817 947
818 if ($use_previous_problems) { 948 if ($use_previous_problems) {
819 @pg_files = @all_past_list; 949 @pg_files = @all_past_list;
820 } else { 950 } else {
821 $first_shown = 0; 951 $first_shown = 0;
828 $self->{last_shown} = $last_shown; 958 $self->{last_shown} = $last_shown;
829 $self->{browse_which} = $browse_which; 959 $self->{browse_which} = $browse_which;
830 $self->{problem_seed} = $problem_seed; 960 $self->{problem_seed} = $problem_seed;
831 $self->{pg_files} = \@pg_files; 961 $self->{pg_files} = \@pg_files;
832 $self->{past_marks} = \@past_marks; 962 $self->{past_marks} = \@past_marks;
833 $self->{all_set_defs} = \@all_set_defs; 963 $self->{all_db_sets} = \@all_db_sets;
834 964
835} 965}
836 966
837 967
838sub title { 968sub title {
868 my $first_shown = $self->{first_shown}; 998 my $first_shown = $self->{first_shown};
869 my $last_shown = $self->{last_shown}; 999 my $last_shown = $self->{last_shown};
870 my $browse_which = $self->{browse_which}; 1000 my $browse_which = $self->{browse_which};
871 my $problem_seed = $self->{problem_seed}; 1001 my $problem_seed = $self->{problem_seed};
872 my @pg_files = @{$self->{pg_files}}; 1002 my @pg_files = @{$self->{pg_files}};
873 my @all_set_defs = @{$self->{all_set_defs}}; 1003 my @all_db_sets = @{$self->{all_db_sets}};
874 1004
875 my @pg_html=($last_shown>=$first_shown) ? 1005 my @pg_html=($last_shown>=$first_shown) ?
876 renderProblems(r=> $r, 1006 renderProblems(r=> $r,
877 user => $user, 1007 user => $user,
878 problem_list => [@pg_files[$first_shown..$last_shown]], 1008 problem_list => [@pg_files[$first_shown..$last_shown]],
881 ########## Top part 1011 ########## Top part
882 print CGI::startform({-method=>"POST", -action=>$r->uri, -name=>'mainform'}), 1012 print CGI::startform({-method=>"POST", -action=>$r->uri, -name=>'mainform'}),
883 $self->hidden_authen_fields, 1013 $self->hidden_authen_fields,
884 '<div align="center">', 1014 '<div align="center">',
885 CGI::start_table({-border=>2}); 1015 CGI::start_table({-border=>2});
886 $self->make_top_row('all_set_defs'=>\@all_set_defs, 1016 $self->make_top_row('all_db_sets'=>\@all_db_sets,
887 'browse_which'=> $browse_which); 1017 'browse_which'=> $browse_which);
888 print CGI::hidden(-name=>'browse_which', -default=>[$browse_which]), 1018 print CGI::hidden(-name=>'browse_which', -default=>[$browse_which]),
889 CGI::hidden(-name=>'problem_seed', -default=>[$problem_seed]); 1019 CGI::hidden(-name=>'problem_seed', -default=>[$problem_seed]);
890 for ($j = 0 ; $j < scalar(@pg_files) ; $j++) { 1020 for ($j = 0 ; $j < scalar(@pg_files) ; $j++) {
891 print CGI::hidden(-name=>"all_past_list$j", -default=>$pg_files[$j]); 1021 print CGI::hidden(-name=>"all_past_list$j", -default=>$pg_files[$j]);

Legend:
Removed from v.3401  
changed lines
  Added in v.3402

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9