| 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.14 2004/05/22 01:50:35 jj Exp $ |
4 | # $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v 1.15 2004/05/22 16:46:03 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. |
| … | |
… | |
| 32 | use WeBWorK::Utils qw(readDirectory max); |
32 | use WeBWorK::Utils qw(readDirectory max); |
| 33 | use WeBWorK::Utils::Tasks qw(renderProblems); |
33 | use WeBWorK::Utils::Tasks qw(renderProblems); |
| 34 | |
34 | |
| 35 | require WeBWorK::Utils::ListingDB; |
35 | require WeBWorK::Utils::ListingDB; |
| 36 | |
36 | |
| 37 | use constant MAX_SHOW => 20; |
37 | use constant MAX_SHOW_DEFAULT => 20; |
| 38 | use constant NO_LOCAL_SET_STRING => 'There are no local sets yet'; |
38 | use constant NO_LOCAL_SET_STRING => 'There are no local sets yet'; |
| 39 | use constant SELECT_SET_STRING => 'Select a Set for This Course'; |
39 | use constant SELECT_SET_STRING => 'Select a Set for This Course'; |
| 40 | use constant SELECT_LOCAL_STRING => 'Select a Local Problem Collection'; |
40 | use constant SELECT_LOCAL_STRING => 'Select a Local Problem Collection'; |
| 41 | |
41 | |
| 42 | ## Flags for operations on files |
42 | ## Flags for operations on files |
| … | |
… | |
| 146 | @all_problem_directories = sort @all_problem_directories; |
146 | @all_problem_directories = sort @all_problem_directories; |
| 147 | unshift @all_problem_directories, ' -- Top -- ' if($includetop); |
147 | unshift @all_problem_directories, ' -- Top -- ' if($includetop); |
| 148 | return (\@all_problem_directories); |
148 | return (\@all_problem_directories); |
| 149 | } |
149 | } |
| 150 | |
150 | |
|
|
151 | ############# Everyone has a view problems line. Abstract it |
|
|
152 | sub view_problems_line { |
|
|
153 | my $internal_name = shift; |
|
|
154 | my $label = shift; |
|
|
155 | my $r = shift; # so we can get parameter values |
|
|
156 | my $result = CGI::submit(-name=>"$internal_name", -value=>$label); |
|
|
157 | |
|
|
158 | my %display_modes = %{WeBWorK::PG::DISPLAY_MODES()}; |
|
|
159 | my @active_modes = grep { exists $display_modes{$_} } |
|
|
160 | @{$r->ce->{pg}->{displayModes}}; |
|
|
161 | push @active_modes, 'None'; |
|
|
162 | # We have our own displayMode since its value may be None, which is illegal |
|
|
163 | # in other modules. |
|
|
164 | my $mydisplayMode = $r->param('mydisplayMode') || $r->ce->{pg}->{options}->{displayMode}; |
|
|
165 | $result .= ' Display Mode: '.CGI::popup_menu(-name=> 'mydisplayMode', |
|
|
166 | -values=>\@active_modes, |
|
|
167 | -default=> $mydisplayMode); |
|
|
168 | # Now we give a choice of the number of problems to show |
|
|
169 | my $defaultMax = $r->param('max_shown') || MAX_SHOW_DEFAULT; |
|
|
170 | $result .= ' Max. Shown: '. |
|
|
171 | CGI::popup_menu(-name=> 'max_shown', |
|
|
172 | -values=>[5,10,15,20,25,30,50,'All'], |
|
|
173 | -default=> $defaultMax); |
|
|
174 | |
|
|
175 | return($result); |
|
|
176 | } |
|
|
177 | |
|
|
178 | |
| 151 | ### The browsing panel has three versions |
179 | ### The browsing panel has three versions |
| 152 | ##### Version 1 is local problems |
180 | ##### Version 1 is local problems |
| 153 | sub browse_local_panel { |
181 | sub browse_local_panel { |
| 154 | my $self = shift; |
182 | my $self = shift; |
| 155 | my $library_selected = shift; |
183 | my $library_selected = shift; |
| … | |
… | |
| 163 | if (not $library_selected or $library_selected eq $default_value) { |
191 | if (not $library_selected or $library_selected eq $default_value) { |
| 164 | unshift @{$list_of_prob_dirs}, $default_value; |
192 | unshift @{$list_of_prob_dirs}, $default_value; |
| 165 | $library_selected = $default_value; |
193 | $library_selected = $default_value; |
| 166 | } |
194 | } |
| 167 | } |
195 | } |
| 168 | |
196 | my $view_problem_line = view_problems_line('view_local_set', 'View Problems', $self->r); |
| 169 | print CGI::Tr(CGI::td({-class=>"InfoPanel"}, "Local Problems: ", |
197 | print CGI::Tr(CGI::td({-class=>"InfoPanel"}, "Local Problems: ", |
| 170 | CGI::popup_menu(-name=> 'library_sets', |
198 | CGI::popup_menu(-name=> 'library_sets', |
| 171 | -values=>$list_of_prob_dirs, |
199 | -values=>$list_of_prob_dirs, |
| 172 | -default=> $library_selected), |
200 | -default=> $library_selected), |
| 173 | CGI::br(), |
201 | CGI::br(), |
| 174 | CGI::submit(-name=>"view_local_set", -value=>"View Problems"), |
202 | $view_problem_line, |
| 175 | )); |
203 | )); |
| 176 | } |
204 | } |
| 177 | |
205 | |
| 178 | ##### Version 2 is local problem sets |
206 | ##### Version 2 is local problem sets |
| 179 | sub browse_mysets_panel { |
207 | sub browse_mysets_panel { |
| … | |
… | |
| 187 | } elsif (not $library_selected or $library_selected eq $default_value) { |
215 | } elsif (not $library_selected or $library_selected eq $default_value) { |
| 188 | unshift @{$list_of_local_sets}, $default_value; |
216 | unshift @{$list_of_local_sets}, $default_value; |
| 189 | $library_selected = $default_value; |
217 | $library_selected = $default_value; |
| 190 | } |
218 | } |
| 191 | |
219 | |
|
|
220 | my $view_problem_line = view_problems_line('view_mysets_set', 'View Problems', $self->r); |
| 192 | print CGI::Tr(CGI::td({-class=>"InfoPanel"}, "Browse from: ", |
221 | print CGI::Tr(CGI::td({-class=>"InfoPanel"}, "Browse from: ", |
| 193 | CGI::popup_menu(-name=> 'library_sets', |
222 | CGI::popup_menu(-name=> 'library_sets', |
| 194 | -values=>$list_of_local_sets, |
223 | -values=>$list_of_local_sets, |
| 195 | -default=> $library_selected), |
224 | -default=> $library_selected), |
| 196 | CGI::br(), |
225 | CGI::br(), |
| 197 | CGI::submit(-name=>"view_mysets_set", -value=>"View This Set"), |
226 | $view_problem_line |
| 198 | )); |
227 | )); |
| 199 | } |
228 | } |
| 200 | |
229 | |
| 201 | ##### Version 3 is the problem library |
230 | ##### Version 3 is the problem library |
| 202 | |
231 | |
| … | |
… | |
| 245 | |
274 | |
| 246 | my @textbooks = ('Textbook info not ready'); |
275 | my @textbooks = ('Textbook info not ready'); |
| 247 | |
276 | |
| 248 | unshift @sects, $default_sect; |
277 | unshift @sects, $default_sect; |
| 249 | my $section_selected = $r->param('library_sections') || $default_sect; |
278 | my $section_selected = $r->param('library_sections') || $default_sect; |
|
|
279 | my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r); |
| 250 | |
280 | |
| 251 | print CGI::Tr(CGI::td({-class=>"InfoPanel"}, |
281 | print CGI::Tr(CGI::td({-class=>"InfoPanel"}, |
| 252 | CGI::start_table(), |
282 | CGI::start_table(), |
| 253 | CGI::Tr( |
283 | CGI::Tr( |
| 254 | CGI::td(["Chapter:", |
284 | CGI::td(["Chapter:", |
| … | |
… | |
| 277 | # CGI::Tr( |
307 | # CGI::Tr( |
| 278 | # CGI::td("Keywords:"), |
308 | # CGI::td("Keywords:"), |
| 279 | # CGI::td({-colspan=>2}, CGI::textfield(-name=>"keywords", |
309 | # CGI::td({-colspan=>2}, CGI::textfield(-name=>"keywords", |
| 280 | # -default=>"Keywords not implemented yet", |
310 | # -default=>"Keywords not implemented yet", |
| 281 | # -override=>1, -size=>60))), |
311 | # -override=>1, -size=>60))), |
| 282 | CGI::Tr(CGI::td({-colspan=>3},CGI::submit(-name=>"lib_view", -value=>"View Problems"))), |
312 | CGI::Tr(CGI::td({-colspan=>3}, |
|
|
313 | $view_problem_line)), |
| 283 | CGI::end_table(), |
314 | CGI::end_table(), |
| 284 | )); |
315 | )); |
| 285 | } |
316 | } |
| 286 | |
317 | |
| 287 | sub make_top_row { |
318 | sub make_top_row { |
| … | |
… | |
| 367 | |
398 | |
| 368 | $sourceFileName =~ s|^./||; # clean up top ugliness |
399 | $sourceFileName =~ s|^./||; # clean up top ugliness |
| 369 | |
400 | |
| 370 | my $urlpath = $self->r->urlpath; |
401 | my $urlpath = $self->r->urlpath; |
| 371 | my $problem_output = $pg->{flags}->{error_flag} ? |
402 | my $problem_output = $pg->{flags}->{error_flag} ? |
| 372 | CGI::em("This problem produced an error") |
403 | CGI::div({class=>"ResultsWithError"}, CGI::em("This problem produced an error")) |
| 373 | : CGI::div({class=>"RenderSolo"}, $pg->{body_text}); |
404 | : CGI::div({class=>"RenderSolo"}, $pg->{body_text}); |
| 374 | |
405 | |
| 375 | |
406 | |
| 376 | my $edit_link = ''; |
407 | my $edit_link = ''; |
| 377 | #if($self->{r}->param('browse_which') ne 'browse_library') { |
408 | #if($self->{r}->param('browse_which') ne 'browse_library') { |
| … | |
… | |
| 418 | my $r = $self->r; |
449 | my $r = $self->r; |
| 419 | ## For all cases, lets set some things |
450 | ## For all cases, lets set some things |
| 420 | $self->{error}=0; |
451 | $self->{error}=0; |
| 421 | my $ce = $r->ce; |
452 | my $ce = $r->ce; |
| 422 | my $db = $r->db; |
453 | my $db = $r->db; |
|
|
454 | my $maxShown = $r->param('max_shown') || MAX_SHOW_DEFAULT; |
|
|
455 | $maxShown = 10000000 if($maxShown eq 'All'); # let's hope there aren't more |
| 423 | |
456 | |
| 424 | |
457 | |
| 425 | my $userName = $r->param('user'); |
458 | my $userName = $r->param('user'); |
| 426 | my $user = $db->getUser($userName); # checked |
459 | my $user = $db->getUser($userName); # checked |
| 427 | die "record for user $userName (real user) does not exist." |
460 | die "record for user $userName (real user) does not exist." |
| … | |
… | |
| 628 | @pg_files = grep {($_->[1] & HIDDEN) ==0 } @{$self->{past_problems}}; |
661 | @pg_files = grep {($_->[1] & HIDDEN) ==0 } @{$self->{past_problems}}; |
| 629 | @pg_files = map {$_->[0]} @pg_files; |
662 | @pg_files = map {$_->[0]} @pg_files; |
| 630 | @all_past_list = (@all_past_list[0..($first_shown-1)], |
663 | @all_past_list = (@all_past_list[0..($first_shown-1)], |
| 631 | @pg_files, |
664 | @pg_files, |
| 632 | @all_past_list[($last_shown+1)..(scalar(@all_past_list)-1)]); |
665 | @all_past_list[($last_shown+1)..(scalar(@all_past_list)-1)]); |
| 633 | $last_shown = $first_shown+MAX_SHOW -1; |
666 | $last_shown = $first_shown+$maxShown -1; |
| 634 | $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); |
667 | $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); |
| 635 | |
668 | |
| 636 | ## FIXME: you should say something if no problems are selected |
669 | ## FIXME: you should say something if no problems are selected |
| 637 | ## maybe the add button should be disabled if there are no problems |
670 | ## maybe the add button should be disabled if there are no problems |
| 638 | ## showing |
671 | ## showing |
| 639 | |
672 | |
| 640 | |
673 | |
| 641 | } elsif ($r->param('next_page')) { |
674 | } elsif ($r->param('next_page')) { |
| 642 | $first_shown = $last_shown+1; |
675 | $first_shown = $last_shown+1; |
| 643 | $last_shown = $first_shown+MAX_SHOW-1; |
676 | $last_shown = $first_shown+$maxShown-1; |
| 644 | $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); |
677 | $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); |
| 645 | } elsif ($r->param('prev_page')) { |
678 | } elsif ($r->param('prev_page')) { |
| 646 | $last_shown = $first_shown-1; |
679 | $last_shown = $first_shown-1; |
| 647 | $first_shown = $last_shown - MAX_SHOW+1; |
680 | $first_shown = $last_shown - $maxShown+1; |
| 648 | |
681 | |
| 649 | $first_shown = 0 if($first_shown<0); |
682 | $first_shown = 0 if($first_shown<0); |
| 650 | |
683 | |
| 651 | ##### No action requested, probably our first time here |
684 | ##### No action requested, probably our first time here |
| 652 | |
685 | |
| … | |
… | |
| 667 | |
700 | |
| 668 | if ($use_previous_problems) { |
701 | if ($use_previous_problems) { |
| 669 | @pg_files = @all_past_list; |
702 | @pg_files = @all_past_list; |
| 670 | } else { |
703 | } else { |
| 671 | $first_shown = 0; |
704 | $first_shown = 0; |
| 672 | $last_shown = scalar(@pg_files)<MAX_SHOW ? scalar(@pg_files) : MAX_SHOW; |
705 | $last_shown = scalar(@pg_files)<$maxShown ? scalar(@pg_files) : $maxShown; |
| 673 | $last_shown--; # to make it an array index |
706 | $last_shown--; # to make it an array index |
| 674 | } |
707 | } |
| 675 | ############# Now store data in self for retreival by body |
708 | ############# Now store data in self for retreival by body |
| 676 | $self->{first_shown} = $first_shown; |
709 | $self->{first_shown} = $first_shown; |
| 677 | $self->{last_shown} = $last_shown; |
710 | $self->{last_shown} = $last_shown; |
| … | |
… | |
| 719 | my $problem_seed = $self->{problem_seed}; |
752 | my $problem_seed = $self->{problem_seed}; |
| 720 | my @pg_files = @{$self->{pg_files}}; |
753 | my @pg_files = @{$self->{pg_files}}; |
| 721 | my @all_set_defs = @{$self->{all_set_defs}}; |
754 | my @all_set_defs = @{$self->{all_set_defs}}; |
| 722 | |
755 | |
| 723 | my @pg_html=($last_shown>=$first_shown) ? |
756 | my @pg_html=($last_shown>=$first_shown) ? |
| 724 | renderProblems($r,$user, @pg_files[$first_shown..$last_shown]) : (); |
757 | renderProblems(r=> $r, |
|
|
758 | user => $user, |
|
|
759 | problem_list => [@pg_files[$first_shown..$last_shown]], |
|
|
760 | displayMode => $r->param('mydisplayMode')) : (); |
| 725 | |
761 | |
| 726 | ########## Top part |
762 | ########## Top part |
| 727 | print CGI::startform({-method=>"POST", -action=>$r->uri}), |
763 | print CGI::startform({-method=>"POST", -action=>$r->uri}), |
| 728 | $self->hidden_authen_fields, |
764 | $self->hidden_authen_fields, |
| 729 | '<div align="center">', |
765 | '<div align="center">', |