| 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-2006 The WeBWorK Project, http://openwebwork.sf.net/ |
| 4 | # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v 1.49 2005/08/10 18:02:31 sh002i Exp $ |
4 | # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v 1.76 2006/10/30 20:51:25 sh002i 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. |
| … | |
… | |
| 18 | package WeBWorK::ContentGenerator::Instructor::SetMaker; |
18 | package WeBWorK::ContentGenerator::Instructor::SetMaker; |
| 19 | use base qw(WeBWorK::ContentGenerator::Instructor); |
19 | use base qw(WeBWorK::ContentGenerator::Instructor); |
| 20 | |
20 | |
| 21 | =head1 NAME |
21 | =head1 NAME |
| 22 | |
22 | |
| 23 | WeBWorK::ContentGenerator::Instructor::SetMaker - Make problem sets. |
23 | WeBWorK::ContentGenerator::Instructor::SetMaker - Make homework sets. |
| 24 | |
24 | |
| 25 | =cut |
25 | =cut |
| 26 | |
26 | |
| 27 | use strict; |
27 | use strict; |
| 28 | use warnings; |
28 | use warnings; |
| 29 | |
29 | |
| 30 | use CGI::Pretty qw(); |
30 | |
|
|
31 | #use CGI qw(-nosticky); |
|
|
32 | use WeBWorK::CGI; |
| 31 | use WeBWorK::Debug; |
33 | use WeBWorK::Debug; |
| 32 | use WeBWorK::Form; |
34 | use WeBWorK::Form; |
| 33 | use WeBWorK::Utils qw(readDirectory max sortByName); |
35 | use WeBWorK::Utils qw(readDirectory max sortByName); |
| 34 | use WeBWorK::Utils::Tasks qw(renderProblems); |
36 | use WeBWorK::Utils::Tasks qw(renderProblems); |
| 35 | use File::Find; |
37 | use File::Find; |
| … | |
… | |
| 39 | use constant MAX_SHOW_DEFAULT => 20; |
41 | use constant MAX_SHOW_DEFAULT => 20; |
| 40 | use constant NO_LOCAL_SET_STRING => 'No sets in this course yet'; |
42 | use constant NO_LOCAL_SET_STRING => 'No sets in this course yet'; |
| 41 | use constant SELECT_SET_STRING => 'Select a Set from this Course'; |
43 | use constant SELECT_SET_STRING => 'Select a Set from this Course'; |
| 42 | use constant SELECT_LOCAL_STRING => 'Select a Problem Collection'; |
44 | use constant SELECT_LOCAL_STRING => 'Select a Problem Collection'; |
| 43 | use constant MY_PROBLEMS => ' My Problems '; |
45 | use constant MY_PROBLEMS => ' My Problems '; |
| 44 | use constant MAIN_PROBLEMS => ' Main Problems '; |
46 | use constant MAIN_PROBLEMS => ' Unclassified Problems '; |
| 45 | use constant CREATE_SET_BUTTON => 'Create New Set'; |
47 | use constant CREATE_SET_BUTTON => 'Create New Set'; |
| 46 | use constant ALL_CHAPTERS => 'All Chapters'; |
48 | use constant ALL_CHAPTERS => 'All Chapters'; |
| 47 | use constant ALL_SUBJECTS => 'All Subjects'; |
49 | use constant ALL_SUBJECTS => 'All Subjects'; |
| 48 | use constant ALL_SECTIONS => 'All Sections'; |
50 | use constant ALL_SECTIONS => 'All Sections'; |
| 49 | use constant ALL_TEXTBOOKS => 'All Textbooks'; |
51 | use constant ALL_TEXTBOOKS => 'All Textbooks'; |
| … | |
… | |
| 65 | use constant SUCCESS => (1 << 2); |
67 | use constant SUCCESS => (1 << 2); |
| 66 | |
68 | |
| 67 | ## for additional problib buttons |
69 | ## for additional problib buttons |
| 68 | my %problib; ## filled in in global.conf |
70 | my %problib; ## filled in in global.conf |
| 69 | my %ignoredir = ( |
71 | my %ignoredir = ( |
| 70 | '.' => 1, '..' => 1, 'Library' => 1, |
72 | '.' => 1, '..' => 1, 'Library' => 1, 'CVS' => 1, 'tmpEdit' => 1, |
| 71 | 'headers' => 1, 'macros' => 1, 'email' => 1, |
73 | 'headers' => 1, 'macros' => 1, 'email' => 1, |
| 72 | ); |
74 | ); |
| 73 | |
75 | |
|
|
76 | sub prepare_activity_entry { |
|
|
77 | my $self=shift; |
|
|
78 | my $r = $self->r; |
|
|
79 | my $user = $self->r->param('user') || 'NO_USER'; |
|
|
80 | return("In SetMaker as user $user"); |
|
|
81 | } |
|
|
82 | |
| 74 | ## This is for searching the disk for directories containing pg files. |
83 | ## This is for searching the disk for directories containing pg files. |
| 75 | ## to make the recursion work, this returns an array where the first |
84 | ## to make the recursion work, this returns an array where the first |
| 76 | ## item is the number of pg files in the directory. The second is a |
85 | ## item is the number of pg files in the directory. The second is a |
| 77 | ## list of directories which contain pg files. |
86 | ## list of directories which contain pg files. |
| 78 | ## |
87 | ## |
| 79 | ## If a directory contains only one pg file and at least one other |
88 | ## If a directory contains only one pg file and the directory name |
| 80 | ## file, the directory is considered to be part of the parent |
89 | ## is the same as the file name, then the directory is considered |
| 81 | ## directory (it is probably in a separate directory only because |
90 | ## to be part of the parent directory (it is probably in a separate |
| 82 | ## it has auxiliarly files that want to be kept together with the |
91 | ## directory only because it has auxiliary files that want to be |
| 83 | ## pg file). |
92 | ## kept together with the pg file). |
| 84 | ## |
93 | ## |
| 85 | ## If a directory has a file named "=library-ignore", it is never |
94 | ## If a directory has a file named "=library-ignore", it is never |
| 86 | ## included in the directory menu. If a directory contains a file |
95 | ## included in the directory menu. If a directory contains a file |
| 87 | ## called "=library-combine-up", then its pg are included with those |
96 | ## called "=library-combine-up", then its pg are included with those |
| 88 | ## in the parent directory (and the directory does not appear in the |
97 | ## in the parent directory (and the directory does not appear in the |
| 89 | ## menu). If it has a file called "=library-no-combine" then it is |
98 | ## menu). If it has a file called "=library-no-combine" then it is |
| 90 | ## always listed as a separate directory even if it contains only one |
99 | ## always listed as a separate directory even if it contains only one |
| 91 | ## pg file. |
100 | ## pg file. |
| 92 | |
101 | |
| 93 | sub get_library_sets { |
102 | sub get_library_sets { |
| 94 | my $top = shift; my $dir = shift; |
103 | my $top = shift; my $dir = shift; |
| 95 | # ignore directories that give us an error |
104 | # ignore directories that give us an error |
| 96 | my @lis = eval { readDirectory($dir) }; |
105 | my @lis = eval { readDirectory($dir) }; |
| 97 | if ($@) { |
106 | if ($@) { |
| 98 | warn $@; |
107 | warn $@; |
| 99 | return (0); |
108 | return (0); |
| 100 | } |
109 | } |
| 101 | return (0) if grep /^=library-ignore$/, @lis; |
110 | return (0) if grep /^=library-ignore$/, @lis; |
| 102 | |
111 | |
|
|
112 | my @pgfiles = grep { m/\.pg$/ and (not m/(Header|-text)\.pg$/) and -f "$dir/$_"} @lis; |
|
|
113 | my $pgcount = scalar(@pgfiles); |
|
|
114 | my $pgname = $dir; $pgname =~ s!.*/!!; $pgname .= '.pg'; |
|
|
115 | my $combineUp = ($pgcount == 1 && $pgname eq $pgfiles[0] && !(grep /^=library-no-combine$/, @lis)); |
|
|
116 | |
| 103 | my @pgdirs; |
117 | my @pgdirs; |
| 104 | |
|
|
| 105 | my $pgcount = scalar(grep { m/\.pg$/ and (not m/(Header|-text)\.pg$/) and -f "$dir/$_"} @lis); |
|
|
| 106 | my $others = scalar(grep { (!m/\.pg$/ || m/(Header|-text)\.pg$/) && |
|
|
| 107 | !m/(\.(tmp|bak)|~)$/ && -f "$dir/$_" } @lis); |
|
|
| 108 | |
|
|
| 109 | my @dirs = grep {!$ignoredir{$_} and -d "$dir/$_"} @lis; |
118 | my @dirs = grep {!$ignoredir{$_} and -d "$dir/$_"} @lis; |
| 110 | if ($top == 1) {@dirs = grep {!$problib{$_}} @dirs} |
119 | if ($top == 1) {@dirs = grep {!$problib{$_}} @dirs} |
| 111 | foreach my $subdir (@dirs) { |
120 | foreach my $subdir (@dirs) { |
| 112 | my @results = get_library_sets(0, "$dir/$subdir"); |
121 | my @results = get_library_sets(0, "$dir/$subdir"); |
| 113 | $pgcount += shift @results; push(@pgdirs,@results); |
122 | $pgcount += shift @results; push(@pgdirs,@results); |
| 114 | } |
123 | } |
| 115 | |
124 | |
| 116 | return ($pgcount, @pgdirs) if $top || $pgcount == 0 || grep /^=library-combine-up$/, @lis; |
125 | return ($pgcount, @pgdirs) if $top || $combineUp || grep /^=library-combine-up$/, @lis; |
| 117 | return (0,@pgdirs,$dir) if $pgcount > 1 || $others == 0 || grep /^=library-no-combine$/, @lis; |
126 | return (0,@pgdirs,$dir); |
| 118 | return ($pgcount, @pgdirs); |
|
|
| 119 | } |
127 | } |
| 120 | |
128 | |
| 121 | sub get_library_pgs { |
129 | sub get_library_pgs { |
| 122 | my $top = shift; my $base = shift; my $dir = shift; |
130 | my $top = shift; my $base = shift; my $dir = shift; |
| 123 | my @lis = readDirectory("$base/$dir"); |
131 | my @lis = readDirectory("$base/$dir"); |
| 124 | return () if grep /^=library-ignore$/, @lis; |
132 | return () if grep /^=library-ignore$/, @lis; |
| 125 | return () if !$top && grep /^=library-no-combine$/, @lis; |
133 | return () if !$top && grep /^=library-no-combine$/, @lis; |
| 126 | |
134 | |
| 127 | my @pgs = grep { m/\.pg$/ and (not m/(Header|-text)\.pg$/) and -f "$base/$dir/$_"} @lis; |
135 | my @pgs = grep { m/\.pg$/ and (not m/(Header|-text)\.pg$/) and -f "$base/$dir/$_"} @lis; |
| … | |
… | |
| 148 | sub get_set_defs { |
156 | sub get_set_defs { |
| 149 | my $topdir = shift; |
157 | my $topdir = shift; |
| 150 | my @found_set_defs; |
158 | my @found_set_defs; |
| 151 | # get_set_defs_wanted is a closure over @found_set_defs |
159 | # get_set_defs_wanted is a closure over @found_set_defs |
| 152 | my $get_set_defs_wanted = sub { |
160 | my $get_set_defs_wanted = sub { |
| 153 | my $fn = $_; |
161 | #my $fn = $_; |
| 154 | my $fdir = $File::Find::dir; |
162 | #my $fdir = $File::Find::dir; |
| 155 | return() if($fn !~ /^set.*\.def$/); |
163 | #return() if($fn !~ /^set.*\.def$/); |
| 156 | #return() if(not -T $fn); |
164 | ##return() if(not -T $fn); |
| 157 | push @found_set_defs, "$fdir/$fn"; |
165 | #push @found_set_defs, "$fdir/$fn"; |
|
|
166 | push @found_set_defs, $_ if m|/set[^/]*\.def$|; |
| 158 | }; |
167 | }; |
| 159 | find({ wanted => $get_set_defs_wanted, follow_fast=>1}, $topdir); |
168 | find({ wanted => $get_set_defs_wanted, follow_fast=>1, no_chdir=>1}, $topdir); |
| 160 | map { $_ =~ s|^$topdir/?|| } @found_set_defs; |
169 | map { $_ =~ s|^$topdir/?|| } @found_set_defs; |
| 161 | return @found_set_defs; |
170 | return @found_set_defs; |
| 162 | } |
171 | } |
| 163 | |
172 | |
| 164 | ## Try to make reading of set defs more flexible. Additional strategies |
173 | ## Try to make reading of set defs more flexible. Additional strategies |
| … | |
… | |
| 242 | my $db = shift; |
251 | my $db = shift; |
| 243 | my $setName = shift; |
252 | my $setName = shift; |
| 244 | my @past_problems = @{$self->{past_problems}}; |
253 | my @past_problems = @{$self->{past_problems}}; |
| 245 | my @selected = @past_problems; |
254 | my @selected = @past_problems; |
| 246 | my (@path, $file, $selected, $freeProblemID); |
255 | my (@path, $file, $selected, $freeProblemID); |
|
|
256 | # DBFIXME count would work just as well |
| 247 | $freeProblemID = max($db->listGlobalProblems($setName)) + 1; |
257 | $freeProblemID = max($db->listGlobalProblems($setName)) + 1; |
| 248 | my $addedcount=0; |
258 | my $addedcount=0; |
| 249 | |
259 | |
| 250 | for $selected (@selected) { |
260 | for $selected (@selected) { |
| 251 | if($selected->[1] & ADDED) { |
261 | if($selected->[1] & ADDED) { |
| … | |
… | |
| 292 | my @active_modes = grep { exists $display_modes{$_} } |
302 | my @active_modes = grep { exists $display_modes{$_} } |
| 293 | @{$r->ce->{pg}->{displayModes}}; |
303 | @{$r->ce->{pg}->{displayModes}}; |
| 294 | push @active_modes, 'None'; |
304 | push @active_modes, 'None'; |
| 295 | # We have our own displayMode since its value may be None, which is illegal |
305 | # We have our own displayMode since its value may be None, which is illegal |
| 296 | # in other modules. |
306 | # in other modules. |
| 297 | my $displayMode = $r->param('displayMode') || $r->ce->{pg}->{options}->{displayMode}; |
307 | my $mydisplayMode = $r->param('mydisplayMode') || $r->ce->{pg}->{options}->{displayMode}; |
| 298 | $result .= ' Display Mode: '.CGI::popup_menu(-name=> 'displayMode', |
308 | $result .= ' Display Mode: '.CGI::popup_menu(-name=> 'mydisplayMode', |
| 299 | -values=>\@active_modes, |
309 | -values=>\@active_modes, |
| 300 | -default=> $displayMode); |
310 | -default=> $mydisplayMode); |
| 301 | # Now we give a choice of the number of problems to show |
311 | # Now we give a choice of the number of problems to show |
| 302 | my $defaultMax = $r->param('max_shown') || MAX_SHOW_DEFAULT; |
312 | my $defaultMax = $r->param('max_shown') || MAX_SHOW_DEFAULT; |
| 303 | $result .= ' Max. Shown: '. |
313 | $result .= ' Max. Shown: '. |
| 304 | CGI::popup_menu(-name=> 'max_shown', |
314 | CGI::popup_menu(-name=> 'max_shown', |
| 305 | -values=>[5,10,15,20,25,30,50,'All'], |
315 | -values=>[5,10,15,20,25,30,50,'All'], |
| … | |
… | |
| 314 | sub browse_local_panel { |
324 | sub browse_local_panel { |
| 315 | my $self = shift; |
325 | my $self = shift; |
| 316 | my $library_selected = shift; |
326 | my $library_selected = shift; |
| 317 | my $lib = shift || ''; $lib =~ s/^browse_//; |
327 | my $lib = shift || ''; $lib =~ s/^browse_//; |
| 318 | my $name = ($lib eq '')? 'Local' : $problib{$lib}; |
328 | my $name = ($lib eq '')? 'Local' : $problib{$lib}; |
| 319 | |
329 | |
| 320 | my $list_of_prob_dirs= get_problem_directories($self->r->ce,$lib); |
330 | my $list_of_prob_dirs= get_problem_directories($self->r->ce,$lib); |
| 321 | if(scalar(@$list_of_prob_dirs) == 0) { |
331 | if(scalar(@$list_of_prob_dirs) == 0) { |
| 322 | $library_selected = "Found no directories containing problems"; |
332 | $library_selected = "Found no directories containing problems"; |
| 323 | unshift @{$list_of_prob_dirs}, $library_selected; |
333 | unshift @{$list_of_prob_dirs}, $library_selected; |
| 324 | } else { |
334 | } else { |
| … | |
… | |
| 326 | if (not $library_selected or $library_selected eq $default_value) { |
336 | if (not $library_selected or $library_selected eq $default_value) { |
| 327 | unshift @{$list_of_prob_dirs}, $default_value; |
337 | unshift @{$list_of_prob_dirs}, $default_value; |
| 328 | $library_selected = $default_value; |
338 | $library_selected = $default_value; |
| 329 | } |
339 | } |
| 330 | } |
340 | } |
|
|
341 | debug("library is $lib and sets are $library_selected"); |
| 331 | my $view_problem_line = view_problems_line('view_local_set', 'View Problems', $self->r); |
342 | my $view_problem_line = view_problems_line('view_local_set', 'View Problems', $self->r); |
| 332 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "$name Problems: ", |
343 | print CGI::Tr({}, CGI::td({-class=>"InfoPanel", -align=>"left"}, "$name Problems: ", |
| 333 | CGI::popup_menu(-name=> 'library_sets', |
344 | CGI::popup_menu(-name=> 'library_sets', |
| 334 | -values=>$list_of_prob_dirs, |
345 | -values=>$list_of_prob_dirs, |
| 335 | -default=> $library_selected), |
346 | -default=> $library_selected), |
| 336 | CGI::br(), |
347 | CGI::br(), |
| 337 | $view_problem_line, |
348 | $view_problem_line, |
| 338 | )); |
349 | )); |
| 339 | } |
350 | } |
| 340 | |
351 | |
| 341 | ##### Version 2 is local problem sets |
352 | ##### Version 2 is local homework sets |
| 342 | sub browse_mysets_panel { |
353 | sub browse_mysets_panel { |
| 343 | my $self = shift; |
354 | my $self = shift; |
| 344 | my $library_selected = shift; |
355 | my $library_selected = shift; |
| 345 | my $list_of_local_sets = shift; |
356 | my $list_of_local_sets = shift; |
| 346 | my $default_value = "Select a Homework Set"; |
357 | my $default_value = "Select a Homework Set"; |
| … | |
… | |
| 351 | unshift @{$list_of_local_sets}, $default_value; |
362 | unshift @{$list_of_local_sets}, $default_value; |
| 352 | $library_selected = $default_value; |
363 | $library_selected = $default_value; |
| 353 | } |
364 | } |
| 354 | |
365 | |
| 355 | my $view_problem_line = view_problems_line('view_mysets_set', 'View Problems', $self->r); |
366 | my $view_problem_line = view_problems_line('view_mysets_set', 'View Problems', $self->r); |
|
|
367 | print CGI::Tr({}, |
| 356 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "Browse from: ", |
368 | CGI::td({-class=>"InfoPanel", -align=>"left"}, "Browse from: ", |
| 357 | CGI::popup_menu(-name=> 'library_sets', |
369 | CGI::popup_menu(-name=> 'library_sets', |
| 358 | -values=>$list_of_local_sets, |
370 | -values=>$list_of_local_sets, |
| 359 | -default=> $library_selected), |
371 | -default=> $library_selected), |
| 360 | CGI::br(), |
372 | CGI::br(), |
| 361 | $view_problem_line |
373 | $view_problem_line |
| … | |
… | |
| 428 | |
440 | |
| 429 | my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r); |
441 | my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r); |
| 430 | |
442 | |
| 431 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, |
443 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, |
| 432 | CGI::start_table(), |
444 | CGI::start_table(), |
| 433 | CGI::Tr( |
445 | CGI::Tr({}, |
| 434 | CGI::td(["Chapter:", |
446 | CGI::td(["Chapter:", |
| 435 | CGI::popup_menu(-name=> 'library_chapters', |
447 | CGI::popup_menu(-name=> 'library_chapters', |
| 436 | -values=>\@chaps, |
448 | -values=>\@chaps, |
| 437 | -default=> $chapter_selected, |
449 | -default=> $chapter_selected, |
| 438 | -onchange=>"submit();return true" |
450 | -onchange=>"submit();return true" |
| 439 | ), |
451 | ), |
| 440 | CGI::submit(-name=>"lib_select_chapter", -value=>"Update Section List")])), |
452 | CGI::submit(-name=>"lib_select_chapter", -value=>"Update Section List")])), |
| 441 | CGI::Tr( |
453 | CGI::Tr({}, |
| 442 | CGI::td("Section:"), |
454 | CGI::td("Section:"), |
| 443 | CGI::td({-colspan=>2}, |
455 | CGI::td({-colspan=>2}, |
| 444 | CGI::popup_menu(-name=> 'library_sections', |
456 | CGI::popup_menu(-name=> 'library_sections', |
| 445 | -values=>\@sects, |
457 | -values=>\@sects, |
| 446 | -default=> $section_selected |
458 | -default=> $section_selected |
| … | |
… | |
| 477 | $count_line = "There are no matching pg files"; |
489 | $count_line = "There are no matching pg files"; |
| 478 | } else { |
490 | } else { |
| 479 | $count_line = "There are $count_line matching WeBWorK problem files"; |
491 | $count_line = "There are $count_line matching WeBWorK problem files"; |
| 480 | } |
492 | } |
| 481 | |
493 | |
|
|
494 | print CGI::Tr({}, |
| 482 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, |
495 | CGI::td({-class=>"InfoPanel", -align=>"left"}, |
| 483 | CGI::hidden(-name=>"library_is_basic", -default=>[1]), |
496 | CGI::hidden(-name=>"library_is_basic", -default=>1,-override=>1), |
| 484 | CGI::start_table({-width=>"100%"}), |
497 | CGI::start_table({-width=>"100%"}), |
| 485 | CGI::Tr( |
498 | CGI::Tr({}, |
| 486 | CGI::td(["Subject:", |
499 | CGI::td(["Subject:", |
| 487 | CGI::popup_menu(-name=> 'library_subjects', |
500 | CGI::popup_menu(-name=> 'library_subjects', |
| 488 | -values=>\@subjs, |
501 | -values=>\@subjs, |
| 489 | -default=> $subject_selected, |
502 | -default=> $subject_selected, |
| 490 | -onchange=>"submit();return true" |
503 | -onchange=>"submit();return true" |
| 491 | )]), |
504 | )]), |
| 492 | CGI::td({-colspan=>2, -align=>"right"}, |
505 | CGI::td({-colspan=>2, -align=>"right"}, |
| 493 | CGI::submit(-name=>"lib_select_subject", -value=>"Update Chapter/Section Lists")) |
506 | CGI::submit(-name=>"lib_select_subject", -value=>"Update Chapter/Section Lists")) |
| 494 | ), |
507 | ), |
| 495 | CGI::Tr( |
508 | CGI::Tr({}, |
| 496 | CGI::td(["Chapter:", |
509 | CGI::td(["Chapter:", |
| 497 | CGI::popup_menu(-name=> 'library_chapters', |
510 | CGI::popup_menu(-name=> 'library_chapters', |
| 498 | -values=>\@chaps, |
511 | -values=>\@chaps, |
| 499 | -default=> $chapter_selected, |
512 | -default=> $chapter_selected, |
| 500 | -onchange=>"submit();return true" |
513 | -onchange=>"submit();return true" |
| 501 | )]), |
514 | )]), |
| 502 | CGI::td({-colspan=>2, -align=>"right"}, |
515 | CGI::td({-colspan=>2, -align=>"right"}, |
| 503 | CGI::submit(-name=>"library_advanced", -value=>"Advanced Search")) |
516 | CGI::submit(-name=>"library_advanced", -value=>"Advanced Search")) |
| 504 | ), |
517 | ), |
| 505 | CGI::Tr( |
518 | CGI::Tr({}, |
| 506 | CGI::td(["Section:", |
519 | CGI::td(["Section:", |
| 507 | CGI::popup_menu(-name=> 'library_sections', |
520 | CGI::popup_menu(-name=> 'library_sections', |
| 508 | -values=>\@sects, |
521 | -values=>\@sects, |
| 509 | -default=> $section_selected, |
522 | -default=> $section_selected, |
| 510 | -onchange=>"submit();return true" |
523 | -onchange=>"submit();return true" |
| … | |
… | |
| 588 | $count_line = "There are no matching pg files"; |
601 | $count_line = "There are no matching pg files"; |
| 589 | } else { |
602 | } else { |
| 590 | $count_line = "There are $count_line matching WeBWorK problem files"; |
603 | $count_line = "There are $count_line matching WeBWorK problem files"; |
| 591 | } |
604 | } |
| 592 | |
605 | |
|
|
606 | print CGI::Tr({}, |
| 593 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, |
607 | CGI::td({-class=>"InfoPanel", -align=>"left"}, |
| 594 | CGI::hidden(-name=>"library_is_basic", -default=>[2]), |
608 | CGI::hidden(-name=>"library_is_basic", -default=>2,-override=>1), |
| 595 | CGI::start_table({-width=>"100%"}), |
609 | CGI::start_table({-width=>"100%"}), |
| 596 | # Html done by hand since it is temporary |
610 | # Html done by hand since it is temporary |
| 597 | CGI::Tr(CGI::td({-colspan=>4, -align=>"center"}, 'All Selected Constraints Joined by "And"')), |
611 | CGI::Tr(CGI::td({-colspan=>4, -align=>"center"}, 'All Selected Constraints Joined by "And"')), |
| 598 | CGI::Tr( |
612 | CGI::Tr({}, |
| 599 | CGI::td(["Subject:", |
613 | CGI::td(["Subject:", |
| 600 | CGI::popup_menu(-name=> 'library_subjects', |
614 | CGI::popup_menu(-name=> 'library_subjects', |
| 601 | -values=>\@subjs, |
615 | -values=>\@subjs, |
| 602 | -default=> $selected{dbsubject}, |
616 | -default=> $selected{dbsubject}, |
| 603 | -onchange=>"submit();return true" |
617 | -onchange=>"submit();return true" |
| 604 | )]), |
618 | )]), |
| 605 | CGI::td({-colspan=>2, -align=>"right"}, |
619 | CGI::td({-colspan=>2, -align=>"right"}, |
| 606 | CGI::submit(-name=>"lib_select_subject", -value=>"Update Menus", |
620 | CGI::submit(-name=>"lib_select_subject", -value=>"Update Menus", |
| 607 | -style=> $right_button_style))), |
621 | -style=> $right_button_style))), |
| 608 | CGI::Tr( |
622 | CGI::Tr({}, |
| 609 | CGI::td(["Chapter:", |
623 | CGI::td(["Chapter:", |
| 610 | CGI::popup_menu(-name=> 'library_chapters', |
624 | CGI::popup_menu(-name=> 'library_chapters', |
| 611 | -values=>\@chaps, |
625 | -values=>\@chaps, |
| 612 | -default=> $selected{dbchapter}, |
626 | -default=> $selected{dbchapter}, |
| 613 | -onchange=>"submit();return true" |
627 | -onchange=>"submit();return true" |
| 614 | )]), |
628 | )]), |
| 615 | CGI::td({-colspan=>2, -align=>"right"}, |
629 | CGI::td({-colspan=>2, -align=>"right"}, |
| 616 | CGI::submit(-name=>"library_reset", -value=>"Reset", |
630 | CGI::submit(-name=>"library_reset", -value=>"Reset", |
| 617 | -style=>$right_button_style)) |
631 | -style=>$right_button_style)) |
| 618 | ), |
632 | ), |
| 619 | CGI::Tr( |
633 | CGI::Tr({}, |
| 620 | CGI::td(["Section:", |
634 | CGI::td(["Section:", |
| 621 | CGI::popup_menu(-name=> 'library_sections', |
635 | CGI::popup_menu(-name=> 'library_sections', |
| 622 | -values=>\@sects, |
636 | -values=>\@sects, |
| 623 | -default=> $selected{dbsection}, |
637 | -default=> $selected{dbsection}, |
| 624 | -onchange=>"submit();return true" |
638 | -onchange=>"submit();return true" |
| 625 | )]), |
639 | )]), |
| 626 | CGI::td({-colspan=>2, -align=>"right"}, |
640 | CGI::td({-colspan=>2, -align=>"right"}, |
| 627 | CGI::submit(-name=>"library_basic", -value=>"Basic Search", |
641 | CGI::submit(-name=>"library_basic", -value=>"Basic Search", |
| 628 | -style=>$right_button_style)) |
642 | -style=>$right_button_style)) |
| 629 | ), |
643 | ), |
| 630 | CGI::Tr( |
644 | CGI::Tr({}, |
| 631 | CGI::td(["Textbook:", $text_popup]), |
645 | CGI::td(["Textbook:", $text_popup]), |
| 632 | ), |
646 | ), |
| 633 | CGI::Tr( |
647 | CGI::Tr({}, |
| 634 | CGI::td(["Text chapter:", |
648 | CGI::td(["Text chapter:", |
| 635 | CGI::popup_menu(-name=> 'library_textchapter', |
649 | CGI::popup_menu(-name=> 'library_textchapter', |
| 636 | -values=>\@textchaps, |
650 | -values=>\@textchaps, |
| 637 | -default=> $selected{textchapter}, |
651 | -default=> $selected{textchapter}, |
| 638 | -onchange=>"submit();return true" |
652 | -onchange=>"submit();return true" |
| 639 | )]), |
653 | )]), |
| 640 | ), |
654 | ), |
| 641 | CGI::Tr( |
655 | CGI::Tr({}, |
| 642 | CGI::td(["Text section:", |
656 | CGI::td(["Text section:", |
| 643 | CGI::popup_menu(-name=> 'library_textsection', |
657 | CGI::popup_menu(-name=> 'library_textsection', |
| 644 | -values=>\@textsecs, |
658 | -values=>\@textsecs, |
| 645 | -default=> $selected{textsection}, |
659 | -default=> $selected{textsection}, |
| 646 | -onchange=>"submit();return true" |
660 | -onchange=>"submit();return true" |
| 647 | )]), |
661 | )]), |
| 648 | ), |
662 | ), |
|
|
663 | CGI::Tr({}, |
| 649 | CGI::Tr(CGI::td("Keywords:"),CGI::td({-colspan=>2}, |
664 | CGI::td("Keywords:"),CGI::td({-colspan=>2}, |
| 650 | CGI::textfield(-name=>"library_keywords", |
665 | CGI::textfield(-name=>"library_keywords", |
| 651 | -default=>$library_keywords, |
666 | -default=>$library_keywords, |
| 652 | -override=>1, |
667 | -override=>1, |
| 653 | -size=>40))), |
668 | -size=>40))), |
| 654 | CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)), |
669 | CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)), |
| … | |
… | |
| 665 | my $self = shift; |
680 | my $self = shift; |
| 666 | my $r = $self->r; |
681 | my $r = $self->r; |
| 667 | my $ce = $r->ce; |
682 | my $ce = $r->ce; |
| 668 | my $library_selected = shift; |
683 | my $library_selected = shift; |
| 669 | my $default_value = "Select a Set Definition File"; |
684 | my $default_value = "Select a Set Definition File"; |
|
|
685 | # in the following line, the parens after sort are important. if they are |
|
|
686 | # omitted, sort will interpret get_set_defs as the name of the comparison |
|
|
687 | # function, and ($ce->{courseDirs}{templates}) as a single element list to |
|
|
688 | # be sorted. *barf* |
| 670 | my @list_of_set_defs = get_set_defs($ce->{courseDirs}{templates}); |
689 | my @list_of_set_defs = sort(get_set_defs($ce->{courseDirs}{templates})); |
| 671 | if(scalar(@list_of_set_defs) == 0) { |
690 | if(scalar(@list_of_set_defs) == 0) { |
| 672 | @list_of_set_defs = (NO_LOCAL_SET_STRING); |
691 | @list_of_set_defs = (NO_LOCAL_SET_STRING); |
| 673 | } elsif (not $library_selected or $library_selected eq $default_value) { |
692 | } elsif (not $library_selected or $library_selected eq $default_value) { |
| 674 | unshift @list_of_set_defs, $default_value; |
693 | unshift @list_of_set_defs, $default_value; |
| 675 | $library_selected = $default_value; |
694 | $library_selected = $default_value; |
| … | |
… | |
| 694 | my %data = @_; |
713 | my %data = @_; |
| 695 | |
714 | |
| 696 | my $list_of_local_sets = $data{all_db_sets}; |
715 | my $list_of_local_sets = $data{all_db_sets}; |
| 697 | my $have_local_sets = scalar(@$list_of_local_sets); |
716 | my $have_local_sets = scalar(@$list_of_local_sets); |
| 698 | my $browse_which = $data{browse_which}; |
717 | my $browse_which = $data{browse_which}; |
| 699 | my $library_selected = $r->param('library_sets'); |
718 | my $library_selected = $self->{current_library_set}; |
| 700 | my $set_selected = $r->param('local_sets'); |
719 | my $set_selected = $r->param('local_sets'); |
| 701 | |
|
|
| 702 | my ($dis1, $dis2, $dis3, $dis4) = ("","","", ""); |
720 | my (@dis1, @dis2, @dis3, @dis4) = (); |
| 703 | $dis1 = '-disabled' if($browse_which eq 'browse_library'); |
721 | @dis1 = (-disabled=>1) if($browse_which eq 'browse_library'); |
| 704 | $dis2 = '-disabled' if($browse_which eq 'browse_local'); |
722 | @dis2 = (-disabled=>1) if($browse_which eq 'browse_local'); |
| 705 | $dis3 = '-disabled' if($browse_which eq 'browse_mysets'); |
723 | @dis3 = (-disabled=>1) if($browse_which eq 'browse_mysets'); |
| 706 | $dis4 = '-disabled' if($browse_which eq 'browse_setdefs'); |
724 | @dis4 = (-disabled=>1) if($browse_which eq 'browse_setdefs'); |
| 707 | |
725 | |
| 708 | ## Make buttons for additional problem libraries |
726 | ## Make buttons for additional problem libraries |
| 709 | my $libs = ''; |
727 | my $libs = ''; |
| 710 | foreach my $lib (sort(keys(%problib))) { |
728 | foreach my $lib (sort(keys(%problib))) { |
| 711 | $libs .= ' '. CGI::submit(-name=>"browse_$lib", -value=>$problib{$lib}, |
729 | $libs .= ' '. CGI::submit(-name=>"browse_$lib", -value=>$problib{$lib}, |
| 712 | ($browse_which eq "browse_$lib")? '-disabled': '') |
730 | ($browse_which eq "browse_$lib")? (-disabled=>1): ()) |
| 713 | if (-d "$ce->{courseDirs}{templates}/$lib"); |
731 | if (-d "$ce->{courseDirs}{templates}/$lib"); |
| 714 | } |
732 | } |
| 715 | $libs = CGI::br()."or Problems from".$libs if $libs ne ''; |
733 | $libs = CGI::br()."or Problems from".$libs if $libs ne ''; |
| 716 | |
734 | |
| 717 | my $these_widths = "width: 23ex"; |
735 | my $these_widths = "width: 23ex"; |
| 718 | |
736 | |
| 719 | if($have_local_sets ==0) { |
737 | if($have_local_sets ==0) { |
| 720 | $list_of_local_sets = [NO_LOCAL_SET_STRING]; |
738 | $list_of_local_sets = [NO_LOCAL_SET_STRING]; |
| 721 | } elsif (not $set_selected or $set_selected eq SELECT_SET_STRING) { |
739 | } elsif (not defined($set_selected) or $set_selected eq "" |
|
|
740 | or $set_selected eq SELECT_SET_STRING) { |
| 722 | unshift @{$list_of_local_sets}, SELECT_SET_STRING; |
741 | unshift @{$list_of_local_sets}, SELECT_SET_STRING; |
| 723 | $set_selected = SELECT_SET_STRING; |
742 | $set_selected = SELECT_SET_STRING; |
| 724 | } |
743 | } |
| 725 | 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;'; |
744 | 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;'; |
| 726 | |
745 | |
| 727 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "Add problems to ", |
746 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "Add problems to ", |
| 728 | CGI::b("Target Set: "), |
747 | CGI::b("Target Set: "), |
| 729 | CGI::popup_menu(-name=> 'local_sets', |
748 | CGI::popup_menu(-name=> 'local_sets', |
| 730 | -values=>$list_of_local_sets, |
749 | -values=>$list_of_local_sets, |
| 731 | -default=> $set_selected), |
750 | -default=> $set_selected, |
|
|
751 | -override=>1), |
| 732 | CGI::submit(-name=>"edit_local", -value=>"Edit Target Set"), |
752 | CGI::submit(-name=>"edit_local", -value=>"Edit Target Set"), |
| 733 | CGI::hidden(-name=>"selfassign", -default=>[0]). |
753 | CGI::hidden(-name=>"selfassign", -default=>0,-override=>1). |
| 734 | CGI::br(), |
754 | CGI::br(), |
| 735 | CGI::br(), |
755 | CGI::br(), |
| 736 | CGI::submit(-name=>"new_local_set", -value=>"Create a New Set in This Course:", |
756 | CGI::submit(-name=>"new_local_set", -value=>"Create a New Set in This Course:", |
| 737 | -onclick=>$myjs |
757 | -onclick=>$myjs |
| 738 | ), |
758 | ), |
| … | |
… | |
| 749 | shift @{$list_of_local_sets}; |
769 | shift @{$list_of_local_sets}; |
| 750 | } |
770 | } |
| 751 | |
771 | |
| 752 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, |
772 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, |
| 753 | "Browse ", |
773 | "Browse ", |
| 754 | CGI::submit(-name=>"browse_library", -value=>"Problem Library", -style=>$these_widths, $dis1), |
774 | CGI::submit(-name=>"browse_library", -value=>"Problem Library", -style=>$these_widths, @dis1), |
| 755 | CGI::submit(-name=>"browse_local", -value=>"Local Problems", -style=>$these_widths, $dis2), |
775 | CGI::submit(-name=>"browse_local", -value=>"Local Problems", -style=>$these_widths, @dis2), |
| 756 | CGI::submit(-name=>"browse_mysets", -value=>"From This Course", -style=>$these_widths, $dis3), |
776 | CGI::submit(-name=>"browse_mysets", -value=>"From This Course", -style=>$these_widths, @dis3), |
| 757 | CGI::submit(-name=>"browse_setdefs", -value=>"Set Definition Files", -style=>$these_widths, $dis4), |
777 | CGI::submit(-name=>"browse_setdefs", -value=>"Set Definition Files", -style=>$these_widths, @dis4), |
| 758 | $libs, |
778 | $libs, |
| 759 | )); |
779 | )); |
| 760 | |
780 | |
| 761 | #print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
781 | #print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
| 762 | print CGI::hr(); |
782 | print CGI::hr(); |
| … | |
… | |
| 773 | $self->browse_local_panel($library_selected,$browse_which); |
793 | $self->browse_local_panel($library_selected,$browse_which); |
| 774 | } |
794 | } |
| 775 | |
795 | |
| 776 | print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
796 | print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
| 777 | |
797 | |
|
|
798 | print CGI::Tr({}, |
| 778 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, |
799 | CGI::td({-class=>"InfoPanel", -align=>"center"}, |
| 779 | CGI::start_table({-border=>"0"}), |
800 | CGI::start_table({-border=>"0"}), |
| 780 | CGI::Tr( CGI::td({ -align=>"center"}, |
801 | CGI::Tr({}, CGI::td({ -align=>"center"}, |
| 781 | CGI::submit(-name=>"select_all", -style=>$these_widths, |
802 | CGI::submit(-name=>"select_all", -style=>$these_widths, |
| 782 | -value=>"Mark All For Adding"), |
803 | -value=>"Mark All For Adding"), |
| 783 | CGI::submit(-name=>"select_none", -style=>$these_widths, |
804 | CGI::submit(-name=>"select_none", -style=>$these_widths, |
| 784 | -value=>"Clear All Marks"), |
805 | -value=>"Clear All Marks"), |
| 785 | )), |
806 | )), |
| 786 | CGI::Tr(CGI::td( |
807 | CGI::Tr({}, |
|
|
808 | CGI::td({}, |
| 787 | CGI::submit(-name=>"update", -style=>$these_widths. "; font-weight:bold", |
809 | CGI::submit(-name=>"update", -style=>$these_widths. "; font-weight:bold", |
| 788 | -value=>"Update Set"), |
810 | -value=>"Update Set"), |
| 789 | CGI::submit(-name=>"rerandomize", |
811 | CGI::submit(-name=>"rerandomize", |
| 790 | -style=>$these_widths, |
812 | -style=>$these_widths, |
| 791 | -value=>"Rerandomize"), |
813 | -value=>"Rerandomize"), |
| 792 | CGI::submit(-name=>"cleardisplay", |
814 | CGI::submit(-name=>"cleardisplay", |
| 793 | -style=>$these_widths, |
815 | -style=>$these_widths, |
| 794 | -value=>"Clear Problem Display") |
816 | -value=>"Clear Problem Display") |
| 795 | )), |
817 | )), |
| 796 | CGI::end_table())); |
818 | CGI::end_table())); |
| 797 | } |
819 | } |
| … | |
… | |
| 807 | |
829 | |
| 808 | my $urlpath = $self->r->urlpath; |
830 | my $urlpath = $self->r->urlpath; |
| 809 | my $problem_output = $pg->{flags}->{error_flag} ? |
831 | my $problem_output = $pg->{flags}->{error_flag} ? |
| 810 | CGI::div({class=>"ResultsWithError"}, CGI::em("This problem produced an error")) |
832 | CGI::div({class=>"ResultsWithError"}, CGI::em("This problem produced an error")) |
| 811 | : CGI::div({class=>"RenderSolo"}, $pg->{body_text}); |
833 | : CGI::div({class=>"RenderSolo"}, $pg->{body_text}); |
|
|
834 | $problem_output .= $pg->{flags}->{comment} if($pg->{flags}->{comment}); |
| 812 | |
835 | |
| 813 | |
836 | |
| 814 | #if($self->{r}->param('browse_which') ne 'browse_library') { |
837 | #if($self->{r}->param('browse_which') ne 'browse_library') { |
| 815 | my $problem_seed = $self->{r}->param('problem_seed') || 0; |
838 | my $problem_seed = $self->{'problem_seed'} || 1234; |
| 816 | my $edit_link = CGI::a({href=>$self->systemLink( |
839 | my $edit_link = CGI::a({href=>$self->systemLink( |
| 817 | $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", |
840 | $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", |
| 818 | courseID =>$urlpath->arg("courseID"), |
841 | courseID =>$urlpath->arg("courseID"), |
| 819 | setID=>"Undefined_Set", |
842 | setID=>"Undefined_Set", |
| 820 | problemID=>"1"), |
843 | problemID=>"1"), |
| 821 | params=>{sourceFilePath => "$sourceFileName", problemSeed=> $problem_seed} |
844 | params=>{sourceFilePath => "$sourceFileName", problemSeed=> $problem_seed} |
| 822 | )}, "Edit it" ); |
845 | ), target=>"WW_Editor"}, "Edit it" ); |
| 823 | |
846 | |
| 824 | my $displayMode = $self->r->param("displayMode"); |
847 | my $displayMode = $self->r->param("mydisplayMode"); |
| 825 | $displayMode = $self->r->ce->{pg}->{options}->{displayMode} |
848 | $displayMode = $self->r->ce->{pg}->{options}->{displayMode} |
| 826 | if not defined $displayMode or $displayMode eq "None"; |
849 | if not defined $displayMode or $displayMode eq "None"; |
| 827 | my $try_link = CGI::a({href=>$self->systemLink( |
850 | my $try_link = CGI::a({href=>$self->systemLink( |
| 828 | $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem", |
851 | $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem", |
| 829 | courseID =>$urlpath->arg("courseID"), |
852 | courseID =>$urlpath->arg("courseID"), |
| … | |
… | |
| 834 | editMode => "SetMaker", |
857 | editMode => "SetMaker", |
| 835 | problemSeed=> $problem_seed, |
858 | problemSeed=> $problem_seed, |
| 836 | sourceFilePath => "$sourceFileName", |
859 | sourceFilePath => "$sourceFileName", |
| 837 | displayMode => $displayMode, |
860 | displayMode => $displayMode, |
| 838 | } |
861 | } |
| 839 | )}, "Try it"); |
862 | ), target=>"WW_View"}, "Try it"); |
| 840 | |
863 | |
| 841 | my %add_box_data = ( -name=>"trial$cnt",-value=>1,-label=>"Add this problem to the current set on the next update"); |
864 | my %add_box_data = ( -name=>"trial$cnt",-value=>1,-label=>"Add this problem to the target set on the next update"); |
| 842 | if($mark & SUCCESS) { |
865 | if($mark & SUCCESS) { |
| 843 | $add_box_data{ -label } .= " (just added this problem)"; |
866 | $add_box_data{ -label } .= " (just added this problem)"; |
| 844 | } elsif($mark & ADDED) { |
867 | } elsif($mark & ADDED) { |
| 845 | $add_box_data{ -checked } = 1; |
868 | $add_box_data{ -checked } = 1; |
| 846 | } |
869 | } |
|
|
870 | |
|
|
871 | my $inSet = ($self->{isInSet}{$sourceFileName})? |
|
|
872 | CGI::span({-style=>"float:right; text-align: right"}, |
|
|
873 | CGI::i(CGI::b("(This problem is in the target set)"))) : ""; |
| 847 | |
874 | |
| 848 | print CGI::Tr({-align=>"left"}, CGI::td( |
875 | print CGI::Tr({-align=>"left"}, CGI::td( |
| 849 | CGI::div({-style=>"background-color: #DDDDDD; margin: 0px auto"}, |
876 | CGI::div({-style=>"background-color: #DDDDDD; margin: 0px auto"}, |
| 850 | CGI::span({-style=>"float:left ; text-align: left"},"File name: $sourceFileName "), |
877 | CGI::span({-style=>"float:left ; text-align: left"},"File name: $sourceFileName "), |
| 851 | CGI::span({-style=>"float:right ; text-align: right"}, $edit_link, " ", $try_link) |
878 | CGI::span({-style=>"float:right ; text-align: right"}, $edit_link, " ", $try_link) |
| 852 | ), CGI::br(), |
879 | ), CGI::br(), |
| 853 | CGI::checkbox(-name=>"hideme$cnt",-value=>1,-label=>"Don't show this problem on the next update"), |
880 | CGI::checkbox(-name=>"hideme$cnt",-value=>1,-label=>"Don't show this problem on the next update",-override=>1), |
| 854 | CGI::br(), |
881 | CGI::br(), |
|
|
882 | $inSet, |
| 855 | CGI::checkbox((%add_box_data)), |
883 | CGI::checkbox((%add_box_data),-override=>1), |
| 856 | CGI::hidden(-name=>"filetrial$cnt", -default=>[$sourceFileName]). |
884 | CGI::hidden(-name=>"filetrial$cnt", -default=>$sourceFileName,-override=>1). |
| 857 | CGI::p($problem_output), |
885 | CGI::p($problem_output), |
| 858 | )); |
886 | )); |
| 859 | } |
887 | } |
| 860 | |
888 | |
| 861 | sub clear_default { |
889 | sub clear_default { |
| … | |
… | |
| 875 | my $ce = $r->ce; |
903 | my $ce = $r->ce; |
| 876 | my $db = $r->db; |
904 | my $db = $r->db; |
| 877 | my $maxShown = $r->param('max_shown') || MAX_SHOW_DEFAULT; |
905 | my $maxShown = $r->param('max_shown') || MAX_SHOW_DEFAULT; |
| 878 | $maxShown = 10000000 if($maxShown eq 'All'); # let's hope there aren't more |
906 | $maxShown = 10000000 if($maxShown eq 'All'); # let's hope there aren't more |
| 879 | my $library_basic = $r->param('library_is_basic') || 1; |
907 | my $library_basic = $r->param('library_is_basic') || 1; |
| 880 | |
908 | $self->{problem_seed} = $r->param('problem_seed') || 1234; |
| 881 | ## Fix some parameters |
909 | ## Fix some parameters |
| 882 | clear_default($r,'library_subjects', ALL_SUBJECTS); |
910 | for my $key (keys(%{ LIB2_DATA() })) { |
| 883 | clear_default($r,'library_chapters', ALL_CHAPTERS); |
911 | clear_default($r, LIB2_DATA->{$key}->{name}, LIB2_DATA->{$key}->{all} ); |
| 884 | clear_default($r,'library_sections', ALL_SECTIONS); |
912 | } |
| 885 | clear_default($r,'library_textbook', ALL_TEXTBOOKS); |
913 | ## Grab library sets to display from parameters list. We will modify this |
| 886 | |
914 | ## as we go through the if/else tree |
|
|
915 | $self->{current_library_set} = $r->param('library_sets'); |
|
|
916 | |
| 887 | ## These directories will have individual buttons |
917 | ## These directories will have individual buttons |
| 888 | %problib = %{$ce->{courseFiles}{problibs}} if $ce->{courseFiles}{problibs}; |
918 | %problib = %{$ce->{courseFiles}{problibs}} if $ce->{courseFiles}{problibs}; |
| 889 | |
919 | |
| 890 | my $userName = $r->param('user'); |
920 | my $userName = $r->param('user'); |
| 891 | my $user = $db->getUser($userName); # checked |
921 | my $user = $db->getUser($userName); # checked |
| … | |
… | |
| 921 | my @past_marks = map {$_->[1]} @{$self->{past_problems}}; |
951 | my @past_marks = map {$_->[1]} @{$self->{past_problems}}; |
| 922 | my $none_shown = scalar(@{$self->{past_problems}})==0; |
952 | my $none_shown = scalar(@{$self->{past_problems}})==0; |
| 923 | my @pg_files=(); |
953 | my @pg_files=(); |
| 924 | my $use_previous_problems = 1; |
954 | my $use_previous_problems = 1; |
| 925 | my $first_shown = $r->param('first_shown') || 0; |
955 | my $first_shown = $r->param('first_shown') || 0; |
| 926 | my $last_shown = $r->param('last_shown'); |
956 | my $last_shown = $r->param('last_shown'); |
| 927 | if (not defined($last_shown)) { |
957 | if (not defined($last_shown)) { |
| 928 | $last_shown = -1; |
958 | $last_shown = -1; |
| 929 | } |
959 | } |
| 930 | my @all_past_list = (); # these are include requested, but not shown |
960 | my @all_past_list = (); # these are include requested, but not shown |
| 931 | my $j = 0; |
961 | my $j = 0; |
| 932 | while (defined($r->param("all_past_list$j"))) { |
962 | while (defined($r->param("all_past_list$j"))) { |
| 933 | push @all_past_list, $r->param("all_past_list$j"); |
963 | push @all_past_list, $r->param("all_past_list$j"); |
| … | |
… | |
| 936 | |
966 | |
| 937 | ############# Default of which problem selector to display |
967 | ############# Default of which problem selector to display |
| 938 | |
968 | |
| 939 | my $browse_which = $r->param('browse_which') || 'browse_local'; |
969 | my $browse_which = $r->param('browse_which') || 'browse_local'; |
| 940 | |
970 | |
| 941 | my $problem_seed = $r->param('problem_seed') || 0; |
971 | |
| 942 | $r->param('problem_seed', $problem_seed); # if it wasn't defined before |
|
|
| 943 | |
972 | |
| 944 | ## check for problem lib buttons |
973 | ## check for problem lib buttons |
| 945 | my $browse_lib = ''; |
974 | my $browse_lib = ''; |
| 946 | foreach my $lib (keys %problib) { |
975 | foreach my $lib (keys %problib) { |
| 947 | if ($r->param("browse_$lib")) { |
976 | if ($r->param("browse_$lib")) { |
| … | |
… | |
| 949 | last; |
978 | last; |
| 950 | } |
979 | } |
| 951 | } |
980 | } |
| 952 | |
981 | |
| 953 | ########### Start the logic through if elsif elsif ... |
982 | ########### Start the logic through if elsif elsif ... |
| 954 | |
983 | debug("browse_lib", $r->param("$browse_lib")); |
|
|
984 | debug("browse_library", $r->param("browse_library")); |
|
|
985 | debug("browse_mysets", $r->param("browse_mysets")); |
|
|
986 | debug("browse_setdefs", $r->param("browse_setdefs")); |
| 955 | ##### Asked to browse certain problems |
987 | ##### Asked to browse certain problems |
| 956 | if ($browse_lib ne '') { |
988 | if ($browse_lib ne '') { |
| 957 | $browse_which = $browse_lib; |
989 | $browse_which = $browse_lib; |
| 958 | $r->param('library_sets', ""); |
990 | $self->{current_library_set} = ""; |
| 959 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
991 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
| 960 | } elsif ($r->param('browse_library')) { |
992 | } elsif ($r->param('browse_library')) { |
| 961 | $browse_which = 'browse_library'; |
993 | $browse_which = 'browse_library'; |
| 962 | $r->param('library_sets', ""); |
994 | $self->{current_library_set} = ""; |
| 963 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
995 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
| 964 | } elsif ($r->param('browse_local')) { |
996 | } elsif ($r->param('browse_local')) { |
| 965 | $browse_which = 'browse_local'; |
997 | $browse_which = 'browse_local'; |
| 966 | $r->param('library_sets', ""); |
998 | #$self->{current_library_set} = ""; |
| 967 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
999 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
| 968 | } elsif ($r->param('browse_mysets')) { |
1000 | } elsif ($r->param('browse_mysets')) { |
| 969 | $browse_which = 'browse_mysets'; |
1001 | $browse_which = 'browse_mysets'; |
| 970 | $r->param('library_sets', ""); |
1002 | $self->{current_library_set} = ""; |
| 971 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
1003 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
| 972 | } elsif ($r->param('browse_setdefs')) { |
1004 | } elsif ($r->param('browse_setdefs')) { |
| 973 | $browse_which = 'browse_setdefs'; |
1005 | $browse_which = 'browse_setdefs'; |
| 974 | $r->param('library_sets', ""); |
1006 | $self->{current_library_set} = ""; |
| 975 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
1007 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
| 976 | |
1008 | |
| 977 | ##### Change the seed value |
1009 | ##### Change the seed value |
| 978 | |
1010 | |
| 979 | } elsif ($r->param('rerandomize')) { |
1011 | } elsif ($r->param('rerandomize')) { |
| 980 | $problem_seed++; |
1012 | $self->{problem_seed}= 1+$self->{problem_seed}; |
| 981 | $r->param('problem_seed', $problem_seed); |
1013 | #$r->param('problem_seed', $problem_seed); |
| 982 | $self->addbadmessage('Changing the problem seed for display, but there are no problems showing.') if $none_shown; |
1014 | $self->addbadmessage('Changing the problem seed for display, but there are no problems showing.') if $none_shown; |
| 983 | |
1015 | |
| 984 | ##### Clear the display |
1016 | ##### Clear the display |
| 985 | |
1017 | |
| 986 | } elsif ($r->param('cleardisplay')) { |
1018 | } elsif ($r->param('cleardisplay')) { |
| … | |
… | |
| 990 | |
1022 | |
| 991 | ##### View problems selected from the local list |
1023 | ##### View problems selected from the local list |
| 992 | |
1024 | |
| 993 | } elsif ($r->param('view_local_set')) { |
1025 | } elsif ($r->param('view_local_set')) { |
| 994 | |
1026 | |
| 995 | my $set_to_display = $r->param('library_sets'); |
1027 | my $set_to_display = $self->{current_library_set}; |
| 996 | if (not defined($set_to_display) or $set_to_display eq SELECT_LOCAL_STRING or $set_to_display eq "Found no directories containing problems") { |
1028 | if (not defined($set_to_display) or $set_to_display eq SELECT_LOCAL_STRING or $set_to_display eq "Found no directories containing problems") { |
| 997 | $self->addbadmessage('You need to select a set to view.'); |
1029 | $self->addbadmessage('You need to select a set to view.'); |
| 998 | } else { |
1030 | } else { |
| 999 | $set_to_display = '.' if $set_to_display eq MY_PROBLEMS; |
1031 | $set_to_display = '.' if $set_to_display eq MY_PROBLEMS; |
| 1000 | $set_to_display = substr($browse_which,7) if $set_to_display eq MAIN_PROBLEMS; |
1032 | $set_to_display = substr($browse_which,7) if $set_to_display eq MAIN_PROBLEMS; |
| … | |
… | |
| 1005 | |
1037 | |
| 1006 | ##### View problems selected from the a set in this course |
1038 | ##### View problems selected from the a set in this course |
| 1007 | |
1039 | |
| 1008 | } elsif ($r->param('view_mysets_set')) { |
1040 | } elsif ($r->param('view_mysets_set')) { |
| 1009 | |
1041 | |
| 1010 | my $set_to_display = $r->param('library_sets'); |
1042 | my $set_to_display = $self->{current_library_set}; |
|
|
1043 | debug("set_to_display is $set_to_display"); |
| 1011 | if (not defined($set_to_display) |
1044 | if (not defined($set_to_display) |
| 1012 | or $set_to_display eq "Select a Homework Set" |
1045 | or $set_to_display eq "Select a Homework Set" |
| 1013 | or $set_to_display eq NO_LOCAL_SET_STRING) { |
1046 | or $set_to_display eq NO_LOCAL_SET_STRING) { |
| 1014 | $self->addbadmessage("You need to select a set from this course to view."); |
1047 | $self->addbadmessage("You need to select a set from this course to view."); |
| 1015 | } else { |
1048 | } else { |
|
|
1049 | # DBFIXME don't use ID list, use an iterator |
| 1016 | my @problemList = $db->listGlobalProblems($set_to_display); |
1050 | my @problemList = $db->listGlobalProblems($set_to_display); |
| 1017 | my $problem; |
1051 | my $problem; |
| 1018 | @pg_files=(); |
1052 | @pg_files=(); |
| 1019 | for $problem (@problemList) { |
1053 | for $problem (@problemList) { |
| 1020 | my $problemRecord = $db->getGlobalProblem($set_to_display, $problem); # checked |
1054 | my $problemRecord = $db->getGlobalProblem($set_to_display, $problem); # checked |
| 1021 | die "global $problem for set $set_to_display not found." unless |
1055 | die "global $problem for set $set_to_display not found." unless |
| 1022 | $problemRecord; |
1056 | $problemRecord; |
| 1023 | push @pg_files, $problemRecord->source_file; |
1057 | push @pg_files, $problemRecord->source_file; |
| 1024 | |
1058 | |
| 1025 | } |
1059 | } |
|
|
1060 | @pg_files = sortByName(undef,@pg_files); |
| 1026 | $use_previous_problems=0; |
1061 | $use_previous_problems=0; |
| 1027 | } |
1062 | } |
| 1028 | |
1063 | |
| 1029 | ##### View from the library database |
1064 | ##### View from the library database |
| 1030 | |
1065 | |
| … | |
… | |
| 1043 | |
1078 | |
| 1044 | ##### View a set from a set*.def |
1079 | ##### View a set from a set*.def |
| 1045 | |
1080 | |
| 1046 | } elsif ($r->param('view_setdef_set')) { |
1081 | } elsif ($r->param('view_setdef_set')) { |
| 1047 | |
1082 | |
| 1048 | my $set_to_display = $r->param('library_sets'); |
1083 | my $set_to_display = $self->{current_library_set}; |
|
|
1084 | debug("set_to_display is $set_to_display"); |
| 1049 | if (not defined($set_to_display) |
1085 | if (not defined($set_to_display) |
| 1050 | or $set_to_display eq "Select a Set Definition File" |
1086 | or $set_to_display eq "Select a Set Definition File" |
| 1051 | or $set_to_display eq NO_LOCAL_SET_STRING) { |
1087 | or $set_to_display eq NO_LOCAL_SET_STRING) { |
| 1052 | $self->addbadmessage("You need to select a set from this course to view."); |
1088 | $self->addbadmessage("You need to select a set definition file to view."); |
| 1053 | } else { |
1089 | } else { |
| 1054 | @pg_files= $self->read_set_def($set_to_display); |
1090 | @pg_files= $self->read_set_def($set_to_display); |
| 1055 | } |
1091 | } |
| 1056 | $use_previous_problems=0; |
1092 | $use_previous_problems=0; |
| 1057 | |
1093 | |
| 1058 | ##### Edit the current local problem set |
1094 | ##### Edit the current local homework set |
| 1059 | |
1095 | |
| 1060 | } elsif ($r->param('edit_local')) { ## Jump to set edit page |
1096 | } elsif ($r->param('edit_local')) { ## Jump to set edit page |
| 1061 | |
1097 | |
| 1062 | ; # already handled |
1098 | ; # already handled |
| 1063 | |
1099 | |
| 1064 | |
1100 | |
| 1065 | ##### Make a new local problem set |
1101 | ##### Make a new local homework set |
| 1066 | |
1102 | |
| 1067 | } elsif ($r->param('new_local_set')) { |
1103 | } elsif ($r->param('new_local_set')) { |
| 1068 | if ($r->param('new_set_name') !~ /^[\w .-]*$/) { |
1104 | if ($r->param('new_set_name') !~ /^[\w .-]*$/) { |
| 1069 | $self->addbadmessage("The name ".$r->param('new_set_name')." is not a valid set name. Use only letters, digits, -, _, and ."); |
1105 | $self->addbadmessage("The name ".$r->param('new_set_name')." is not a valid set name. Use only letters, digits, -, _, and ."); |
| 1070 | } else { |
1106 | } else { |
| 1071 | my $newSetName = $r->param('new_set_name'); |
1107 | my $newSetName = $r->param('new_set_name'); |
| 1072 | # if we want to munge the input set name, do it here |
1108 | # if we want to munge the input set name, do it here |
| 1073 | $newSetName =~ s/\s/_/g; |
1109 | $newSetName =~ s/\s/_/g; |
| 1074 | $r->param('local_sets',$newSetName); |
1110 | debug("local_sets was ", $r->param('local_sets')); |
|
|
1111 | $r->param('local_sets',$newSetName); ## use of two parameter param |
|
|
1112 | debug("new value of local_sets is ", $r->param('local_sets')); |
| 1075 | my $newSetRecord = $db->getGlobalSet($newSetName); |
1113 | my $newSetRecord = $db->getGlobalSet($newSetName); |
| 1076 | if (defined($newSetRecord)) { |
1114 | if (defined($newSetRecord)) { |
| 1077 | $self->addbadmessage("The set name $newSetName is already in use. Pick a different name if you would like to start a new set."); |
1115 | $self->addbadmessage("The set name $newSetName is already in use. |
|
|
1116 | Pick a different name if you would like to start a new set."); |
| 1078 | } else { # Do it! |
1117 | } else { # Do it! |
|
|
1118 | # DBFIXME use $db->newGlobalSet |
| 1079 | $newSetRecord = $db->{set}->{record}->new(); |
1119 | $newSetRecord = $db->{set}->{record}->new(); |
| 1080 | $newSetRecord->set_id($newSetName); |
1120 | $newSetRecord->set_id($newSetName); |
| 1081 | $newSetRecord->set_header(""); |
1121 | $newSetRecord->set_header(""); |
| 1082 | $newSetRecord->hardcopy_header(""); |
1122 | $newSetRecord->hardcopy_header(""); |
| 1083 | $newSetRecord->open_date(time()+60*60*24*7); # in one week |
1123 | $newSetRecord->open_date(time()+60*60*24*7); # in one week |
| … | |
… | |
| 1115 | |
1155 | |
| 1116 | if (scalar(@selected)>0) { # if some are to be added, they need a place to go |
1156 | if (scalar(@selected)>0) { # if some are to be added, they need a place to go |
| 1117 | $localSet = $r->param('local_sets'); |
1157 | $localSet = $r->param('local_sets'); |
| 1118 | if (not defined($localSet) or |
1158 | if (not defined($localSet) or |
| 1119 | $localSet eq SELECT_SET_STRING or |
1159 | $localSet eq SELECT_SET_STRING or |
| 1120 | $localSet eq NO_LOCAL_SET_STRING) { |
1160 | $localSet eq NO_LOCAL_SET_STRING) { |
| 1121 | $self->addbadmessage('You are trying to add problems to something, but you did not select a "Target Set" name as a target.'); |
1161 | $self->addbadmessage('You are trying to add problems to something, |
|
|
1162 | but you did not select a "Target Set" name as a target.'); |
| 1122 | } else { |
1163 | } else { |
| 1123 | my $newSetRecord = $db->getGlobalSet($localSet); |
1164 | my $newSetRecord = $db->getGlobalSet($localSet); |
| 1124 | if (not defined($newSetRecord)) { |
1165 | if (not defined($newSetRecord)) { |
| 1125 | $self->addbadmessage("You are trying to add problems to $localSet, but that set does not seem to exist! I bet you used your \"Back\" button."); |
1166 | $self->addbadmessage("You are trying to add problems to $localSet, |
|
|
1167 | but that set does not seem to exist! I bet you used your \"Back\" button."); |
| 1126 | } else { |
1168 | } else { |
| 1127 | my $addcount = add_selected($self, $db, $localSet); |
1169 | my $addcount = add_selected($self, $db, $localSet); |
| 1128 | if($addcount > 0) { |
1170 | if($addcount > 0) { |
| 1129 | $self->addgoodmessage("Added $addcount problem".(($addcount>1)?'s':''). |
1171 | $self->addgoodmessage("Added $addcount problem".(($addcount>1)?'s':''). |
| 1130 | " to $localSet."); |
1172 | " to $localSet."); |
|
|
1173 | } |
| 1131 | } |
1174 | } |
| 1132 | } |
|
|
| 1133 | } |
1175 | } |
| 1134 | } |
1176 | } |
| 1135 | ## now handle problems to be hidden |
1177 | ## now handle problems to be hidden |
| 1136 | |
1178 | |
| 1137 | ## only keep the ones which are not hidden |
1179 | ## only keep the ones which are not hidden |
| … | |
… | |
| 1139 | @past_marks = map {$_->[1]} @pg_files; |
1181 | @past_marks = map {$_->[1]} @pg_files; |
| 1140 | @pg_files = map {$_->[0]} @pg_files; |
1182 | @pg_files = map {$_->[0]} @pg_files; |
| 1141 | @all_past_list = (@all_past_list[0..($first_shown-1)], |
1183 | @all_past_list = (@all_past_list[0..($first_shown-1)], |
| 1142 | @pg_files, |
1184 | @pg_files, |
| 1143 | @all_past_list[($last_shown+1)..(scalar(@all_past_list)-1)]); |
1185 | @all_past_list[($last_shown+1)..(scalar(@all_past_list)-1)]); |
| 1144 | $last_shown = $first_shown+$maxShown -1; |
1186 | $last_shown = $first_shown+$maxShown -1; debug("last_shown 3: ", $last_shown); |
| 1145 | $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); |
1187 | $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); debug("last_shown 4: ", $last_shown); |
| 1146 | |
1188 | |
| 1147 | } elsif ($r->param('next_page')) { |
1189 | } elsif ($r->param('next_page')) { |
| 1148 | $first_shown = $last_shown+1; |
1190 | $first_shown = $last_shown+1; |
| 1149 | $last_shown = $first_shown+$maxShown-1; |
1191 | $last_shown = $first_shown+$maxShown-1; debug("last_shown 5: ", $last_shown); |
| 1150 | $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); |
1192 | $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); debug("last_shown 6: ", $last_shown); |
| 1151 | @past_marks = (); |
1193 | @past_marks = (); |
| 1152 | } elsif ($r->param('prev_page')) { |
1194 | } elsif ($r->param('prev_page')) { |
| 1153 | $last_shown = $first_shown-1; |
1195 | $last_shown = $first_shown-1; |
| 1154 | $first_shown = $last_shown - $maxShown+1; |
1196 | $first_shown = $last_shown - $maxShown+1; |
| 1155 | |
1197 | |
| 1156 | $first_shown = 0 if($first_shown<0); |
1198 | $first_shown = 0 if($first_shown<0); |
| 1157 | @past_marks = (); |
1199 | @past_marks = (); |
| 1158 | |
1200 | |
| … | |
… | |
| 1169 | for my $jj (qw(chapters sections subjects textbook keywords)) { |
1211 | for my $jj (qw(chapters sections subjects textbook keywords)) { |
| 1170 | $r->param('library_'.$jj,''); |
1212 | $r->param('library_'.$jj,''); |
| 1171 | } |
1213 | } |
| 1172 | } elsif ($r->param('select_none')) { |
1214 | } elsif ($r->param('select_none')) { |
| 1173 | @past_marks = (); |
1215 | @past_marks = (); |
| 1174 | |
1216 | } else { |
| 1175 | ##### No action requested, probably our first time here |
1217 | ##### No action requested, probably our first time here |
| 1176 | |
|
|
| 1177 | } else { |
|
|
| 1178 | #my $c = $r->connection; |
|
|
| 1179 | #print "Debug info: ". $r->get_remote_host ."<p>". $c->remote_ip ; |
|
|
| 1180 | ; |
|
|
| 1181 | } ##### end of the if elsif ... |
1218 | } ##### end of the if elsif ... |
| 1182 | |
1219 | |
| 1183 | |
1220 | |
| 1184 | ############# List of local sets |
1221 | ############# List of local sets |
| 1185 | |
1222 | |
|
|
1223 | # DBFIXME sorting in database, please! |
| 1186 | my @all_db_sets = $db->listGlobalSets; |
1224 | my @all_db_sets = $db->listGlobalSets; |
| 1187 | @all_db_sets = sortByName(undef, @all_db_sets); |
1225 | @all_db_sets = sortByName(undef, @all_db_sets); |
| 1188 | |
1226 | |
| 1189 | if ($use_previous_problems) { |
1227 | if ($use_previous_problems) { |
| 1190 | @pg_files = @all_past_list; |
1228 | @pg_files = @all_past_list; |
| 1191 | } else { |
1229 | } else { |
| 1192 | $first_shown = 0; |
1230 | $first_shown = 0; |
| 1193 | $last_shown = scalar(@pg_files)<$maxShown ? scalar(@pg_files) : $maxShown; |
1231 | $last_shown = scalar(@pg_files)<$maxShown ? scalar(@pg_files) : $maxShown; |
| 1194 | $last_shown--; # to make it an array index |
1232 | $last_shown--; # to make it an array index |
| 1195 | @past_marks = (); |
1233 | @past_marks = (); |
| 1196 | } |
1234 | } |
| 1197 | ############# Now store data in self for retreival by body |
1235 | ############# Now store data in self for retreival by body |
| 1198 | $self->{first_shown} = $first_shown; |
1236 | $self->{first_shown} = $first_shown; |
| 1199 | $self->{last_shown} = $last_shown; |
1237 | $self->{last_shown} = $last_shown; |
| 1200 | $self->{browse_which} = $browse_which; |
1238 | $self->{browse_which} = $browse_which; |
| 1201 | $self->{problem_seed} = $problem_seed; |
1239 | #$self->{problem_seed} = $problem_seed; |
| 1202 | $self->{pg_files} = \@pg_files; |
1240 | $self->{pg_files} = \@pg_files; |
| 1203 | $self->{past_marks} = \@past_marks; |
1241 | $self->{past_marks} = \@past_marks; |
| 1204 | $self->{all_db_sets} = \@all_db_sets; |
1242 | $self->{all_db_sets} = \@all_db_sets; |
| 1205 | $self->{library_basic} = $library_basic; |
1243 | $self->{library_basic} = $library_basic; |
|
|
1244 | debug("past_marks is ", join(" ", @{$self->{past_marks}})); |
| 1206 | } |
1245 | } |
| 1207 | |
1246 | |
| 1208 | |
1247 | |
| 1209 | sub title { |
1248 | sub title { |
| 1210 | return "Library Browser"; |
1249 | return "Library Browser"; |
| … | |
… | |
| 1240 | } |
1279 | } |
| 1241 | |
1280 | |
| 1242 | ########## Extract information computed in pre_header_initialize |
1281 | ########## Extract information computed in pre_header_initialize |
| 1243 | |
1282 | |
| 1244 | my $first_shown = $self->{first_shown}; |
1283 | my $first_shown = $self->{first_shown}; |
| 1245 | my $last_shown = $self->{last_shown}; |
1284 | my $last_shown = $self->{last_shown}; |
| 1246 | my $browse_which = $self->{browse_which}; |
1285 | my $browse_which = $self->{browse_which}; |
| 1247 | my $problem_seed = $self->{problem_seed}; |
1286 | my $problem_seed = $self->{problem_seed}||1234; |
| 1248 | my @pg_files = @{$self->{pg_files}}; |
1287 | my @pg_files = @{$self->{pg_files}}; |
| 1249 | my @all_db_sets = @{$self->{all_db_sets}}; |
1288 | my @all_db_sets = @{$self->{all_db_sets}}; |
| 1250 | |
1289 | |
| 1251 | my @pg_html=($last_shown>=$first_shown) ? |
1290 | my @pg_html=($last_shown>=$first_shown) ? |
| 1252 | renderProblems(r=> $r, |
1291 | renderProblems(r=> $r, |
| 1253 | user => $user, |
1292 | user => $user, |
| 1254 | problem_list => [@pg_files[$first_shown..$last_shown]], |
1293 | problem_list => [@pg_files[$first_shown..$last_shown]], |
| 1255 | displayMode => $r->param('displayMode')) : (); |
1294 | displayMode => $r->param('mydisplayMode')) : (); |
|
|
1295 | |
|
|
1296 | my %isInSet; |
|
|
1297 | my $setName = $r->param("local_sets"); |
|
|
1298 | if ($setName) { |
|
|
1299 | # DBFIXME where clause, iterator |
|
|
1300 | # DBFIXME maybe instead of hashing here, query when checking source files? |
|
|
1301 | # DBFIXME definitely don't need to be making full record objects |
|
|
1302 | # DBFIXME SELECT source_file FROM whatever_problem WHERE set_id=? GROUP BY source_file ORDER BY NULL; |
|
|
1303 | # DBFIXME (and stick result directly into hash) |
|
|
1304 | foreach my $problem ($db->listGlobalProblems($setName)) { |
|
|
1305 | my $problemRecord = $db->getGlobalProblem($setName, $problem); |
|
|
1306 | $isInSet{$problemRecord->source_file} = 1; |
|
|
1307 | } |
|
|
1308 | } |
|
|
1309 | $self->{isInSet} = \%isInSet; |
| 1256 | |
1310 | |
| 1257 | ########## Top part |
1311 | ########## Top part |
| 1258 | print CGI::startform({-method=>"POST", -action=>$r->uri, -name=>'mainform'}), |
1312 | print CGI::start_form({-method=>"POST", -action=>$r->uri, -name=>'mainform'}), |
| 1259 | $self->hidden_authen_fields, |
1313 | $self->hidden_authen_fields, |
| 1260 | '<div align="center">', |
1314 | '<div align="center">', |
| 1261 | CGI::start_table({-border=>2}); |
1315 | CGI::start_table({-border=>2}); |
| 1262 | $self->make_top_row('all_db_sets'=>\@all_db_sets, |
1316 | $self->make_top_row('all_db_sets'=>\@all_db_sets, |
| 1263 | 'browse_which'=> $browse_which); |
1317 | 'browse_which'=> $browse_which); |
| 1264 | print CGI::hidden(-name=>'browse_which', -default=>[$browse_which]), |
1318 | print CGI::hidden(-name=>'browse_which', -value=>$browse_which,-override=>1), |
| 1265 | CGI::hidden(-name=>'problem_seed', -default=>[$problem_seed]); |
1319 | CGI::hidden(-name=>'problem_seed', -value=>$problem_seed, -override=>1); |
| 1266 | for ($j = 0 ; $j < scalar(@pg_files) ; $j++) { |
1320 | for ($j = 0 ; $j < scalar(@pg_files) ; $j++) { |
| 1267 | print CGI::hidden(-name=>"all_past_list$j", -default=>$pg_files[$j]); |
1321 | print CGI::hidden(-name=>"all_past_list$j", -value=>$pg_files[$j],-override=>1); |
| 1268 | } |
1322 | } |
| 1269 | |
1323 | |
| 1270 | print CGI::hidden(-name=>'first_shown', -default=>[$first_shown]); |
1324 | print CGI::hidden(-name=>'first_shown', -value=>$first_shown,-override=>1); |
|
|
1325 | |
| 1271 | print CGI::hidden(-name=>'last_shown', -default=>[$last_shown]); |
1326 | print CGI::hidden(-name=>'last_shown', -value=>$last_shown, -override=>1); |
| 1272 | |
1327 | |
| 1273 | |
1328 | |
| 1274 | ########## Now print problems |
1329 | ########## Now print problems |
| 1275 | my $jj; |
1330 | my $jj; |
| 1276 | for ($jj=0; $jj<scalar(@pg_html); $jj++) { |
1331 | for ($jj=0; $jj<scalar(@pg_html); $jj++) { |
| 1277 | $pg_files[$jj] =~ s|^$ce->{courseDirs}->{templates}/?||; |
1332 | $pg_files[$jj] =~ s|^$ce->{courseDirs}->{templates}/?||; |
| 1278 | $self->make_data_row($pg_files[$jj+$first_shown], $pg_html[$jj], $jj+1, $self->{past_marks}->[$jj]); |
1333 | $self->make_data_row($pg_files[$jj+$first_shown], $pg_html[$jj], $jj+1, $self->{past_marks}->[$jj]); |
|
|
1334 | #$self->make_data_row($pg_files[$jj+$first_shown], $pg_html[$jj], $jj+1, $self->{past_marks}->[$jj+$first_shown]); #MEG |
| 1279 | } |
1335 | } |
| 1280 | |
1336 | |
| 1281 | ########## Finish things off |
1337 | ########## Finish things off |
| 1282 | print CGI::end_table(); |
1338 | print CGI::end_table(); |
| 1283 | print '</div>'; |
1339 | print '</div>'; |