[system] / trunk / webwork-modperl / lib / WeBWorK / ContentGenerator / Instructor / SetMaker.pm Repository:
ViewVC logotype

Diff of /trunk/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm

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

Revision 3397 Revision 3431
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.37 2005/07/14 16:23:11 glarose Exp $ 4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v 1.46 2005/07/29 20:45:38 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';
45use constant ALL_CHAPTERS => 'All Chapters';
46use constant ALL_SUBJECTS => 'All Subjects';
47use constant ALL_SECTIONS => 'All Sections';
48use constant ALL_TEXTBOOKS => 'All Textbooks';
49
50#use constant LIB2_DATA => [
51 #[qw(dbchapter library_chapters), ALL_CHAPTERS],
52 #[qw(dbsection library_sections), ALL_SECTIONS],
53 #[qw(dbsubject library_subjects), ALL_SUBJECT],
54 #[qw(textbook library_textbook), ALL_TEXTBOOKS],
55 #];
44 56
45## Flags for operations on files 57## Flags for operations on files
46 58
47use constant ADDED => 1; 59use constant ADDED => 1;
48use constant HIDDEN => (1 << 1); 60use constant HIDDEN => (1 << 1);
53my %ignoredir = ( 65my %ignoredir = (
54 '.' => 1, '..' => 1, 'Library' => 1, 66 '.' => 1, '..' => 1, 'Library' => 1,
55 'headers' => 1, 'macros' => 1, 'email' => 1, 67 'headers' => 1, 'macros' => 1, 'email' => 1,
56); 68);
57 69
58##
59## This is for searching the disk for directories containing pg files. 70## This is for searching the disk for directories containing pg files.
60## to make the recursion work, this returns an array where the first 71## to make the recursion work, this returns an array where the first
61## item is the number of pg files in the directory. The second is a 72## item is the number of pg files in the directory. The second is a
62## list of directories which contain pg files. 73## list of directories which contain pg files.
63## 74##
72## called "=library-combine-up", then its pg are included with those 83## called "=library-combine-up", then its pg are included with those
73## in the parent directory (and the directory does not appear in the 84## in the parent directory (and the directory does not appear in the
74## menu). If it has a file called "=library-no-combine" then it is 85## menu). If it has a file called "=library-no-combine" then it is
75## always listed as a separate directory even if it contains only one 86## always listed as a separate directory even if it contains only one
76## pg file. 87## pg file.
77##
78 88
79sub get_library_sets { 89sub get_library_sets {
80 my $top = shift; my $dir = shift; 90 my $top = shift; my $dir = shift;
81 # ignore directories that give us an error 91 # ignore directories that give us an error
82 my @lis = eval { readDirectory($dir) }; 92 my @lis = eval { readDirectory($dir) };
125sub list_pg_files { 135sub list_pg_files {
126 my ($templates,$dir) = @_; 136 my ($templates,$dir) = @_;
127 my $top = ($dir eq '.')? 1 : 2; 137 my $top = ($dir eq '.')? 1 : 2;
128 my @pgs = get_library_pgs($top,$templates,$dir); 138 my @pgs = get_library_pgs($top,$templates,$dir);
129 return sortByName(undef,@pgs); 139 return sortByName(undef,@pgs);
140}
141
142## Search for set definition files
143
144# initialize global variable for search
145my @found_set_defs = ();
146
147sub get_set_defs_wanted {
148 my $fn = $_;
149 my $fdir = $File::Find::dir;
150 return() if($fn !~ /^set.*\.def$/);
151 #return() if(not -T $fn);
152 push @found_set_defs, "$fdir/$fn";
153}
154
155sub get_set_defs {
156 my $topdir = shift;
157 @found_set_defs = ();
158 find({ wanted => \&get_set_defs_wanted, follow_fast=>1}, $topdir);
159 map { $_ =~ s|^$topdir/?|| } @found_set_defs;
160 return @found_set_defs;
161}
162
163## Try to make reading of set defs more flexible. Additional strategies
164## for fixing a path can be added here.
165
166sub munge_pg_file_path {
167 my $self = shift;
168 my $pg_path = shift;
169 my $path_to_set_def = shift;
170 my $end_path = $pg_path;
171 # if the path is ok, don't fix it
172 return($pg_path) if(-e $self->r->ce->{courseDirs}{templates}."/$pg_path");
173 # if we have followed a link into a self contained course to get
174 # to the set.def file, we need to insert the start of the path to
175 # the set.def file
176 $end_path = "$path_to_set_def/$pg_path";
177 return($end_path) if(-e $self->r->ce->{courseDirs}{templates}."/$end_path");
178 # if we got this far, this path is bad, but we let it produce
179 # an error so the user knows there is a troublesome path in the
180 # set.def file.
181 return($pg_path);
182}
183
184## Read a set definition file. This could be abstracted since it happens
185## elsewhere. Here we don't have to process so much of the file.
186
187sub read_set_def {
188 my $self = shift;
189 my $r = $self->r;
190 my $filePathOrig = shift;
191 my $filePath = $r->ce->{courseDirs}{templates}."/$filePathOrig";
192 $filePathOrig =~ s/set.*\.def$//;
193 $filePathOrig =~ s|/$||;
194 $filePathOrig = "." if ($filePathOrig !~ /\S/);
195 my @pg_files = ();
196 my ($line, $got_to_pgs, $name, @rest) = ("", 0, "");
197 if ( open (SETFILENAME, "$filePath") ) {
198 while($line = <SETFILENAME>) {
199 chomp($line);
200 $line =~ s|(#.*)||; # don't read past comments
201 if($got_to_pgs) {
202 unless ($line =~ /\S/) {next;} # skip blank lines
203 ($name,@rest) = split (/\s*,\s*/,$line);
204 $name =~ s/\s*//g;
205 push @pg_files, $name;
206 } else {
207 $got_to_pgs = 1 if ($line =~ /problemList\s*=/);
208 }
209 }
210 } else {
211 $self->addbadmessage("Cannot open $filePath");
212 }
213 # This is where we would potentially munge the pg file paths
214 # One possibility
215 @pg_files = map { $self->munge_pg_file_path($_, $filePathOrig) } @pg_files;
216 return(@pg_files);
130} 217}
131 218
132## go through past page getting a list of identifiers for the problems 219## 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 220## and whether or not they are selected, and whether or not they should
134## be hidden 221## be hidden
273 $view_problem_line 360 $view_problem_line
274 )); 361 ));
275} 362}
276 363
277##### Version 3 is the problem library 364##### Version 3 is the problem library
365#
366# This comes in 3 forms, problem library version 1, and for version 2 there
367# is the basic, and the advanced interfaces. This function checks what we are
368# supposed to do, or aborts if the problem library has not been installed.
278 369
279
280# There a different levels, and you can pick a new chapter,
281# pick a new section, pick all from chapter, pick all from section
282#
283# Incoming data - current chapter, current section
284sub browse_library_panel { 370sub browse_library_panel {
285 my $self = shift; 371 my $self=shift;
286 my $r = $self->r; 372 my $r = $self->r;
287 my $ce = $r->ce; 373 my $ce = $r->ce;
288 374
375 # See if the problem library is installed
289 my $libraryRoot = $r->{ce}->{problemLibrary}->{root}; 376 my $libraryRoot = $r->{ce}->{problemLibrary}->{root};
290 377
291 unless($libraryRoot) { 378 unless($libraryRoot) {
292 print CGI::Tr(CGI::td(CGI::div({class=>'ResultsWithError', align=>"center"}, 379 print CGI::Tr(CGI::td(CGI::div({class=>'ResultsWithError', align=>"center"},
293 "The problem library has not been installed."))); 380 "The problem library has not been installed.")));
294 return; 381 return;
295 } 382 }
296 # Test if the Library directory exists. If not, try to make it 383 # Test if the Library directory link exists. If not, try to make it
297 unless(-d "$ce->{courseDirs}->{templates}/Library") { 384 unless(-d "$ce->{courseDirs}->{templates}/Library") {
298 unless(symlink($libraryRoot, "$ce->{courseDirs}->{templates}/Library")) { 385 unless(symlink($libraryRoot, "$ce->{courseDirs}->{templates}/Library")) {
299 my $msg = <<"HERE"; 386 my $msg = <<"HERE";
300You are missing the directory <code>templates/Library</code>, which is needed 387You are missing the directory <code>templates/Library</code>, which is needed
301for the Problem Library to function. It should be a link pointing to 388for the Problem Library to function. It should be a link pointing to
305HERE 392HERE
306 $self->addbadmessage($msg); 393 $self->addbadmessage($msg);
307 } 394 }
308 } 395 }
309 396
310 my $default_chap = "All Chapters"; 397 # Now check what version we are supposed to use
311 my $default_sect = "All Sections"; 398 my $libraryVersion = $r->{ce}->{problemLibrary}->{version} || 1;
399 if($libraryVersion == 1) {
400 return $self->browse_library_panel1;
401 } elsif($libraryVersion == 2) {
402 return $self->browse_library_panel2 if($self->{library_basic}==1);
403 return $self->browse_library_panel2adv;
404 } else {
405 print CGI::Tr(CGI::td(CGI::div({class=>'ResultsWithError', align=>"center"},
406 "The problem library version is set to an illegal value.")));
407 return;
408 }
409}
312 410
411sub browse_library_panel1 {
412 my $self = shift;
413 my $r = $self->r;
414 my $ce = $r->ce;
415
313 my @chaps = WeBWorK::Utils::ListingDB::getAllChapters($r->{ce}); 416 my @chaps = WeBWorK::Utils::ListingDB::getAllChapters($r->{ce});
314 unshift @chaps, $default_chap; 417 unshift @chaps, ALL_CHAPTERS;
315 my $chapter_selected = $r->param('library_chapters') || $default_chap; 418 my $chapter_selected = $r->param('library_chapters') || ALL_CHAPTERS;
316 419
317 my @sects=(); 420 my @sects=();
318 if ($chapter_selected ne $default_chap) { 421 if ($chapter_selected ne ALL_CHAPTERS) {
319 @sects = WeBWorK::Utils::ListingDB::getAllSections($r->{ce}, $chapter_selected); 422 @sects = WeBWorK::Utils::ListingDB::getAllSections($r->{ce}, $chapter_selected);
320 } 423 }
321 424
322 my @textbooks = ('Textbook info not ready'); 425 unshift @sects, ALL_SECTIONS;
323
324 unshift @sects, $default_sect;
325 my $section_selected = $r->param('library_sections') || $default_sect; 426 my $section_selected = $r->param('library_sections') || ALL_SECTIONS;
326 my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r); 427 my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r);
327 428
328 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, 429 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"},
329 CGI::start_table(), 430 CGI::start_table(),
330 CGI::Tr( 431 CGI::Tr(
341 CGI::popup_menu(-name=> 'library_sections', 442 CGI::popup_menu(-name=> 'library_sections',
342 -values=>\@sects, 443 -values=>\@sects,
343 -default=> $section_selected 444 -default=> $section_selected
344 ))), 445 ))),
345 446
346 #CGI::Tr(
347 # CGI::td("Textbook:"),
348 # CGI::td({-colspan=>2},
349 # CGI::popup_menu(-name=> 'library_textbooks',
350 # -values=>\@textbooks,
351 # #-default=> $section_selected
352 #))),
353
354 #CGI::Tr(
355 # CGI::td("Keywords:"),
356 # CGI::td({-colspan=>2},
357 # CGI::textfield(-name=>"keywords",
358 # -default=>"Keywords not implemented yet",
359 # -override=>1, -size=>60
360 #))),
361 CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)), 447 CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)),
362 CGI::end_table(), 448 CGI::end_table(),
363 )); 449 ));
450}
451
452sub browse_library_panel2 {
453 my $self = shift;
454 my $r = $self->r;
455 my $ce = $r->ce;
456
457 my @subjs = WeBWorK::Utils::ListingDB::getAllDBsubjects($r);
458 unshift @subjs, ALL_SUBJECTS;
459
460 my @chaps = WeBWorK::Utils::ListingDB::getAllDBchapters($r);
461 unshift @chaps, ALL_CHAPTERS;
462
463 my @sects=();
464 @sects = WeBWorK::Utils::ListingDB::getAllDBsections($r);
465 unshift @sects, ALL_SECTIONS;
466
467 my $subject_selected = $r->param('library_subjects') || ALL_SUBJECTS;
468 my $chapter_selected = $r->param('library_chapters') || ALL_CHAPTERS;
469 my $section_selected = $r->param('library_sections') || ALL_SECTIONS;
470
471 my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r);
472
473 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"},
474 CGI::hidden(-name=>"library_is_basic", -default=>[1]),
475 CGI::start_table({-width=>"100%"}),
476 CGI::Tr(
477 CGI::td(["Subject:",
478 CGI::popup_menu(-name=> 'library_subjects',
479 -values=>\@subjs,
480 -default=> $subject_selected,
481 -onchange=>"submit();return true"
482 )]),
483 CGI::td({-colspan=>2, -align=>"right"},
484 CGI::submit(-name=>"lib_select_subject", -value=>"Update Chapter/Section Lists"))
485 ),
486 CGI::Tr(
487 CGI::td(["Chapter:",
488 CGI::popup_menu(-name=> 'library_chapters',
489 -values=>\@chaps,
490 -default=> $chapter_selected,
491 -onchange=>"submit();return true"
492 )]),
493 CGI::td({-colspan=>2, -align=>"right"},
494 CGI::submit(-name=>"library_advanced", -value=>"Advanced Search"))
495 ),
496 CGI::Tr(
497 CGI::td(["Section:",
498 CGI::popup_menu(-name=> 'library_sections',
499 -values=>\@sects,
500 -default=> $section_selected
501 )]),
502 ),
503 CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)),
504 CGI::end_table(),
505 ));
506
507}
508
509sub browse_library_panel2adv {
510 my $self = shift;
511 my $r = $self->r;
512 my $ce = $r->ce;
513 my $right_button_style = "width: 18ex";
514
515 my @subjs = WeBWorK::Utils::ListingDB::getAllDBsubjects($r);
516 if(! grep { $_ eq $r->param('library_subjects') } @subjs) {
517 $r->param('library_subjects', '');
518 }
519 unshift @subjs, ALL_SUBJECTS;
520
521 my @chaps = WeBWorK::Utils::ListingDB::getAllDBchapters($r);
522 if(! grep { $_ eq $r->param('library_chapters') } @chaps) {
523 $r->param('library_chapters', '');
524 }
525 unshift @chaps, ALL_CHAPTERS;
526
527 my @sects = WeBWorK::Utils::ListingDB::getAllDBsections($r);
528 if(! grep { $_ eq $r->param('library_sections') } @sects) {
529 $r->param('library_sections', '');
530 }
531 unshift @sects, ALL_SECTIONS;
532
533 my $texts = WeBWorK::Utils::ListingDB::getDBTextbooks($r);
534 my @textarray = map { $_->[0] } @{$texts};
535 my %textlabels = ();
536 for my $ta (@{$texts}) {
537 $textlabels{$ta->[0]} = $ta->[1]." by ".$ta->[2]." (edition ".$ta->[3].")";
538 }
539 if(! grep { $_ eq $r->param('library_textbook') } @textarray) {
540 $r->param('library_textbook', '');
541 }
542 unshift @textarray, ALL_TEXTBOOKS;
543 my $atb = ALL_TEXTBOOKS; $textlabels{$atb} = ALL_TEXTBOOKS;
544
545 my $section_selected = $r->param('library_sections') || ALL_SECTIONS;
546 my $chapter_selected = $r->param('library_chapters') || ALL_CHAPTERS;
547 my $subject_selected = $r->param('library_subjects') || ALL_SUBJECTS;
548 my $textbook_selected = $r->param('library_textbook') || ALL_TEXTBOOKS;
549
550 my $text_popup = CGI::popup_menu(-name => 'library_textbook',
551 -values =>\@textarray,
552 -labels => \%textlabels,
553 -default=>$textbook_selected,
554 -onchange=>"submit();return true");
555
556 my $library_keywords = $r->param('library_keywords') || '';
557
558 my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r);
559
560 my $count_line = WeBWorK::Utils::ListingDB::countDBListings($r);
561 if($count_line==0) {
562 $count_line = "There are no matching pg files";
563 } else {
564 $count_line = "There are $count_line matching WeBWorK problem files";
565 }
566
567 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"},
568 CGI::hidden(-name=>"library_is_basic", -default=>[2]),
569 CGI::start_table({-width=>"100%"}),
570 # Html done by hand since it is temporary
571 CGI::Tr(CGI::td({-colspan=>4, -align=>"center"}, 'All Selected Constraints Joined by "And"')),
572 CGI::Tr(
573 CGI::td(["Subject:",
574 CGI::popup_menu(-name=> 'library_subjects',
575 -values=>\@subjs,
576 -default=> $subject_selected,
577 -onchange=>"submit();return true"
578 )]),
579 CGI::td({-colspan=>2, -align=>"right"},
580 CGI::submit(-name=>"lib_select_subject", -value=>"Update Menus",
581 -style=> $right_button_style))),
582 CGI::Tr(
583 CGI::td(["Chapter:",
584 CGI::popup_menu(-name=> 'library_chapters',
585 -values=>\@chaps,
586 -default=> $chapter_selected,
587 -onchange=>"submit();return true"
588 )]),
589 CGI::td({-colspan=>2, -align=>"right"},
590 CGI::submit(-name=>"library_reset", -value=>"Reset",
591 -style=>$right_button_style))
592 ),
593 CGI::Tr(
594 CGI::td(["Section:",
595 CGI::popup_menu(-name=> 'library_sections',
596 -values=>\@sects,
597 -default=> $section_selected,
598 -onchange=>"submit();return true"
599 )]),
600 CGI::td({-colspan=>2, -align=>"right"},
601 CGI::submit(-name=>"library_basic", -value=>"Basic Search",
602 -style=>$right_button_style))
603 ),
604 CGI::Tr(
605 CGI::td(["Textbook:", $text_popup]),
606 ),
607 CGI::Tr(CGI::td("Keywords:"),CGI::td({-colspan=>2},
608 CGI::textfield(-name=>"library_keywords",
609 -default=>$library_keywords,
610 -override=>1,
611 -size=>40))),
612 CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)),
613 CGI::Tr(CGI::td({-colspan=>3, -align=>"center"}, $count_line)),
614 CGI::end_table(),
615 ));
616
617}
618
619
620##### Version 4 is the set definition file panel
621
622sub browse_setdef_panel {
623 my $self = shift;
624 my $r = $self->r;
625 my $ce = $r->ce;
626 my $library_selected = shift;
627 my $default_value = "Select a Set Definition File";
628 my @list_of_set_defs = get_set_defs($ce->{courseDirs}{templates});
629 if(scalar(@list_of_set_defs) == 0) {
630 @list_of_set_defs = (NO_LOCAL_SET_STRING);
631 } elsif (not $library_selected or $library_selected eq $default_value) {
632 unshift @list_of_set_defs, $default_value;
633 $library_selected = $default_value;
634 }
635 my $view_problem_line = view_problems_line('view_setdef_set', 'View Problems', $self->r);
636 my $popupetc = CGI::popup_menu(-name=> 'library_sets',
637 -values=>\@list_of_set_defs,
638 -default=> $library_selected).
639 CGI::br(). $view_problem_line;
640 if($list_of_set_defs[0] eq NO_LOCAL_SET_STRING) {
641 $popupetc = "there are no set definition files in this course to look at."
642 }
643 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "Browse from: ",
644 $popupetc
645 ));
364} 646}
365 647
366sub make_top_row { 648sub make_top_row {
367 my $self = shift; 649 my $self = shift;
368 my $r = $self->r; 650 my $r = $self->r;
369 my $ce = $r->ce; 651 my $ce = $r->ce;
370 my %data = @_; 652 my %data = @_;
371 653
372 my $list_of_local_sets = $data{all_set_defs}; 654 my $list_of_local_sets = $data{all_db_sets};
373 my $have_local_sets = scalar(@$list_of_local_sets); 655 my $have_local_sets = scalar(@$list_of_local_sets);
374 my $browse_which = $data{browse_which}; 656 my $browse_which = $data{browse_which};
375 my $library_selected = $r->param('library_sets'); 657 my $library_selected = $r->param('library_sets');
376 my $set_selected = $r->param('local_sets'); 658 my $set_selected = $r->param('local_sets');
377 659
378 my ($dis1, $dis2, $dis3) = ("","",""); 660 my ($dis1, $dis2, $dis3, $dis4) = ("","","", "");
379 $dis1 = '-disabled' if($browse_which eq 'browse_library'); 661 $dis1 = '-disabled' if($browse_which eq 'browse_library');
380 $dis2 = '-disabled' if($browse_which eq 'browse_local'); 662 $dis2 = '-disabled' if($browse_which eq 'browse_local');
381 $dis3 = '-disabled' if($browse_which eq 'browse_mysets'); 663 $dis3 = '-disabled' if($browse_which eq 'browse_mysets');
664 $dis4 = '-disabled' if($browse_which eq 'browse_setdefs');
382 665
383 ## Make buttons for additional problem libraries 666 ## Make buttons for additional problem libraries
384 my $libs = ''; 667 my $libs = '';
385 foreach my $lib (sort(keys(%problib))) { 668 foreach my $lib (sort(keys(%problib))) {
386 $libs .= ' '. CGI::submit(-name=>"browse_$lib", -value=>$problib{$lib}, 669 $libs .= ' '. CGI::submit(-name=>"browse_$lib", -value=>$problib{$lib},
392 my $these_widths = "width: 23ex"; 675 my $these_widths = "width: 23ex";
393 676
394 if($have_local_sets ==0) { 677 if($have_local_sets ==0) {
395 $list_of_local_sets = [NO_LOCAL_SET_STRING]; 678 $list_of_local_sets = [NO_LOCAL_SET_STRING];
396 } elsif (not $set_selected or $set_selected eq SELECT_SET_STRING) { 679 } 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; 680 unshift @{$list_of_local_sets}, SELECT_SET_STRING;
401 $set_selected = SELECT_SET_STRING; 681 $set_selected = SELECT_SET_STRING;
402 } 682 }
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;'; 683 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 684
420 -override=>1, -size=>30), 700 -override=>1, -size=>30),
421 )); 701 ));
422 702
423 print CGI::Tr(CGI::td({-bgcolor=>"black"})); 703 print CGI::Tr(CGI::td({-bgcolor=>"black"}));
424 704
705 # Tidy this list up since it is used in two different places
706 if ($list_of_local_sets->[0] eq SELECT_SET_STRING) {
707 shift @{$list_of_local_sets};
708 }
709
425 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, 710 print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"},
426 "Browse ", 711 "Browse ",
427 CGI::submit(-name=>"browse_library", -value=>"Problem Library", -style=>$these_widths, $dis1), 712 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), 713 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), 714 CGI::submit(-name=>"browse_mysets", -value=>"From This Course", -style=>$these_widths, $dis3),
715 CGI::submit(-name=>"browse_setdefs", -value=>"Set Definition Files", -style=>$these_widths, $dis4),
430 $libs, 716 $libs,
431 )); 717 ));
432 718
433 print CGI::Tr(CGI::td({-bgcolor=>"black"})); 719 #print CGI::Tr(CGI::td({-bgcolor=>"black"}));
720 print CGI::hr();
434 721
435 if ($browse_which eq 'browse_local') { 722 if ($browse_which eq 'browse_local') {
436 $self->browse_local_panel($library_selected); 723 $self->browse_local_panel($library_selected);
437 } elsif ($browse_which eq 'browse_mysets') { 724 } elsif ($browse_which eq 'browse_mysets') {
438 $self->browse_mysets_panel($library_selected, $list_of_local_sets); 725 $self->browse_mysets_panel($library_selected, $list_of_local_sets);
439 } elsif ($browse_which eq 'browse_library') { 726 } elsif ($browse_which eq 'browse_library') {
440 $self->browse_library_panel(); 727 $self->browse_library_panel();
728 } elsif ($browse_which eq 'browse_setdefs') {
729 $self->browse_setdef_panel($library_selected);
441 } else { ## handle other problem libraries 730 } else { ## handle other problem libraries
442 $self->browse_local_panel($library_selected,$browse_which); 731 $self->browse_local_panel($library_selected,$browse_which);
443 } 732 }
444 733
445 print CGI::Tr(CGI::td({-bgcolor=>"black"})); 734 print CGI::Tr(CGI::td({-bgcolor=>"black"}));
478 my $problem_output = $pg->{flags}->{error_flag} ? 767 my $problem_output = $pg->{flags}->{error_flag} ?
479 CGI::div({class=>"ResultsWithError"}, CGI::em("This problem produced an error")) 768 CGI::div({class=>"ResultsWithError"}, CGI::em("This problem produced an error"))
480 : CGI::div({class=>"RenderSolo"}, $pg->{body_text}); 769 : CGI::div({class=>"RenderSolo"}, $pg->{body_text});
481 770
482 771
483 my $edit_link = '';
484 #if($self->{r}->param('browse_which') ne 'browse_library') { 772 #if($self->{r}->param('browse_which') ne 'browse_library') {
485 my $problem_seed = $self->{r}->param('problem_seed') || 0; 773 my $problem_seed = $self->{r}->param('problem_seed') || 0;
486 if($sourceFileName !~ /^Library\//) {
487 $edit_link = CGI::a({href=>$self->systemLink( 774 my $edit_link = CGI::a({href=>$self->systemLink(
488 $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", 775 $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor",
489 courseID =>$urlpath->arg("courseID"), 776 courseID =>$urlpath->arg("courseID"),
490 setID=>"Undefined_Set", 777 setID=>"Undefined_Set",
491 problemID=>"1"), 778 problemID=>"1"),
492 params=>{sourceFilePath => "$sourceFileName", problemSeed=> $problem_seed} 779 params=>{sourceFilePath => "$sourceFileName", problemSeed=> $problem_seed}
493 )}, "Edit it" ); 780 )}, "Edit it" );
494 }
495 781
496 my $try_link = CGI::a({href=>$self->systemLink( 782 my $try_link = CGI::a({href=>$self->systemLink(
497 $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem", 783 $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem",
498 courseID =>$urlpath->arg("courseID"), 784 courseID =>$urlpath->arg("courseID"),
499 setID=>"Undefined_Set", 785 setID=>"Undefined_Set",
524 CGI::hidden(-name=>"filetrial$cnt", -default=>[$sourceFileName]). 810 CGI::hidden(-name=>"filetrial$cnt", -default=>[$sourceFileName]).
525 CGI::p($problem_output), 811 CGI::p($problem_output),
526 )); 812 ));
527} 813}
528 814
815sub clear_default {
816 my $r = shift;
817 my $param = shift;
818 my $default = shift;
819 my $newvalue = $r->param($param) || '';
820 $newvalue = '' if($newvalue eq $default);
821 $r->param($param, $newvalue);
822}
529 823
530sub pre_header_initialize { 824sub pre_header_initialize {
531 my ($self) = @_; 825 my ($self) = @_;
532 my $r = $self->r; 826 my $r = $self->r;
533 ## For all cases, lets set some things 827 ## For all cases, lets set some things
534 $self->{error}=0; 828 $self->{error}=0;
535 my $ce = $r->ce; 829 my $ce = $r->ce;
536 my $db = $r->db; 830 my $db = $r->db;
537 my $maxShown = $r->param('max_shown') || MAX_SHOW_DEFAULT; 831 my $maxShown = $r->param('max_shown') || MAX_SHOW_DEFAULT;
538 $maxShown = 10000000 if($maxShown eq 'All'); # let's hope there aren't more 832 $maxShown = 10000000 if($maxShown eq 'All'); # let's hope there aren't more
833 my $library_basic = $r->param('library_is_basic') || 1;
834
835 ## Fix some parameters
836 clear_default($r,'library_subjects', ALL_SUBJECTS);
837 clear_default($r,'library_chapters', ALL_CHAPTERS);
838 clear_default($r,'library_sections', ALL_SECTIONS);
839 clear_default($r,'library_textbook', ALL_TEXTBOOKS);
539 840
540 ## These directories will have individual buttons 841 ## These directories will have individual buttons
541 %problib = %{$ce->{courseFiles}{problibs}} if $ce->{courseFiles}{problibs}; 842 %problib = %{$ce->{courseFiles}{problibs}} if $ce->{courseFiles}{problibs};
542 843
543 my $userName = $r->param('user'); 844 my $userName = $r->param('user');
620 $use_previous_problems = 0; @pg_files = (); ## clear old problems 921 $use_previous_problems = 0; @pg_files = (); ## clear old problems
621 } elsif ($r->param('browse_mysets')) { 922 } elsif ($r->param('browse_mysets')) {
622 $browse_which = 'browse_mysets'; 923 $browse_which = 'browse_mysets';
623 $r->param('library_sets', ""); 924 $r->param('library_sets', "");
624 $use_previous_problems = 0; @pg_files = (); ## clear old problems 925 $use_previous_problems = 0; @pg_files = (); ## clear old problems
926 } elsif ($r->param('browse_setdefs')) {
927 $browse_which = 'browse_setdefs';
928 $r->param('library_sets', "");
929 $use_previous_problems = 0; @pg_files = (); ## clear old problems
625 930
626 ##### Change the seed value 931 ##### Change the seed value
627 932
628 } elsif ($r->param('rerandomize')) { 933 } elsif ($r->param('rerandomize')) {
629 $problem_seed++; 934 $problem_seed++;
664 } else { 969 } else {
665 my @problemList = $db->listGlobalProblems($set_to_display); 970 my @problemList = $db->listGlobalProblems($set_to_display);
666 my $problem; 971 my $problem;
667 @pg_files=(); 972 @pg_files=();
668 for $problem (@problemList) { 973 for $problem (@problemList) {
669 my $problemRecord = $db->getGlobalProblem($set_to_display, $problem); # checked 974 my $problemRecord = $db->getGlobalProblem($set_to_display, $problem); # checked
670 die "global $problem for set $set_to_display not found." unless 975 die "global $problem for set $set_to_display not found." unless
671 $problemRecord; 976 $problemRecord;
672 push @pg_files, $problemRecord->source_file; 977 push @pg_files, $problemRecord->source_file;
673 978
674 } 979 }
675 $use_previous_problems=0; 980 $use_previous_problems=0;
676 } 981 }
677 982
678 ##### View whole chapter from the library 983 ##### View from the library database
679 ## This will change somewhat later
680 984
681 } elsif ($r->param('lib_view')) { 985 } elsif ($r->param('lib_view')) {
682 986
683 @pg_files=(); 987 @pg_files=();
684 my $chap = $r->param('library_chapters') || "";
685 $chap = "" if($chap eq "All Chapters");
686 my $sect = $r->param('library_sections') || "";
687 $sect = "" if($sect eq "All Sections");
688 my @dbsearch = WeBWorK::Utils::ListingDB::getSectionListings($r->{ce}, "$chap", "$sect"); 988 my @dbsearch = WeBWorK::Utils::ListingDB::getSectionListings($r);
689 my ($result, $tolibpath); 989 my ($result, $tolibpath);
690 for $result (@dbsearch) { 990 for $result (@dbsearch) {
691 $tolibpath = "Library/$result->{path}/$result->{filename}"; 991 $tolibpath = "Library/$result->{path}/$result->{filename}";
692 992
693 ## Too clunky!!!! 993 ## Too clunky!!!!
694 push @pg_files, $tolibpath; 994 push @pg_files, $tolibpath;
695 } 995 }
696 $use_previous_problems=0; 996 $use_previous_problems=0;
697 997
998 ##### View a set from a set*.def
999
1000 } elsif ($r->param('view_setdef_set')) {
1001
1002 my $set_to_display = $r->param('library_sets');
1003 if (not defined($set_to_display)
1004 or $set_to_display eq "Select a Set Definition File"
1005 or $set_to_display eq NO_LOCAL_SET_STRING) {
1006 $self->addbadmessage("You need to select a set from this course to view.");
1007 } else {
1008 @pg_files= $self->read_set_def($set_to_display);
1009 }
1010 $use_previous_problems=0;
1011
698 ##### Edit the current local problem set 1012 ##### Edit the current local problem set
699 1013
700 } elsif ($r->param('edit_local')) { ## Jump to set edit page 1014 } elsif ($r->param('edit_local')) { ## Jump to set edit page
701 1015
702 ; # already handled 1016 ; # already handled
703 1017
704 1018
705 ##### Make a new local problem set 1019 ##### Make a new local problem set
706 1020
707 } elsif ($r->param('new_local_set')) { 1021 } elsif ($r->param('new_local_set')) {
708 if ($r->param('new_set_name') !~ /^[\w.-]*$/) { 1022 if ($r->param('new_set_name') !~ /^[\w .-]*$/) {
709 $self->addbadmessage("The name ".$r->param('new_set_name')." is not a valid set name. Use only letters, digits, -, _, and ."); 1023 $self->addbadmessage("The name ".$r->param('new_set_name')." is not a valid set name. Use only letters, digits, -, _, and .");
710 } else { 1024 } else {
711 my $newSetName = $r->param('new_set_name'); 1025 my $newSetName = $r->param('new_set_name');
712 # if we want to munge the input set name, do it here 1026 # if we want to munge the input set name, do it here
1027 $newSetName =~ s/\s/_/g;
713 $r->param('local_sets',$newSetName); 1028 $r->param('local_sets',$newSetName);
714 my $newSetRecord = $db->getGlobalSet($newSetName); 1029 my $newSetRecord = $db->getGlobalSet($newSetName);
715 if (defined($newSetRecord)) { 1030 if (defined($newSetRecord)) {
716 $self->addbadmessage("The set name $newSetName is already in use. Pick a different name if you would like to start a new set."); 1031 $self->addbadmessage("The set name $newSetName is already in use. Pick a different name if you would like to start a new set.");
717 } else { # Do it! 1032 } else { # Do it!
718 $newSetRecord = $db->{set}->{record}->new(); 1033 $newSetRecord = $db->{set}->{record}->new();
719 $newSetRecord->set_id($newSetName); 1034 $newSetRecord->set_id($newSetName);
720 $newSetRecord->set_header(""); 1035 $newSetRecord->set_header("");
721 $newSetRecord->hardcopy_header(""); 1036 $newSetRecord->hardcopy_header("");
722 $newSetRecord->open_date(time()+60*60*24*7); # in one week 1037 $newSetRecord->open_date(time()+60*60*24*7); # in one week
723 $newSetRecord->due_date(time()+60*60*24*7*2); # in two weeks 1038 $newSetRecord->due_date(time()+60*60*24*7*2); # in two weeks
724 $newSetRecord->answer_date(time()+60*60*24*7*3); # in three weeks 1039 $newSetRecord->answer_date(time()+60*60*24*7*3); # in three weeks
725 eval {$db->addGlobalSet($newSetRecord)}; 1040 eval {$db->addGlobalSet($newSetRecord)};
1041 if ($@) {
1042 $self->addbadmessage("Problem creating set $newSetName<br> $@");
1043 } else {
726 $self->addgoodmessage("Set $newSetName has been created."); 1044 $self->addgoodmessage("Set $newSetName has been created.");
727 my $selfassign = $r->param('selfassign') || ""; 1045 my $selfassign = $r->param('selfassign') || "";
728 $selfassign = "" if($selfassign =~ /false/i); # deal with javascript false 1046 $selfassign = "" if($selfassign =~ /false/i); # deal with javascript false
729 if($selfassign) { 1047 if($selfassign) {
730 $self->assignSetToUser($userName, $newSetRecord); 1048 $self->assignSetToUser($userName, $newSetRecord);
731 $self->addgoodmessage("Set $newSetName was assigned to $userName."); 1049 $self->addgoodmessage("Set $newSetName was assigned to $userName.");
1050 }
732 } 1051 }
733 } 1052 }
734 } 1053 }
735 1054
736 ##### Add selected problems to the current local set 1055 ##### Add selected problems to the current local set
791 $first_shown = 0 if($first_shown<0); 1110 $first_shown = 0 if($first_shown<0);
792 @past_marks = (); 1111 @past_marks = ();
793 1112
794 } elsif ($r->param('select_all')) { 1113 } elsif ($r->param('select_all')) {
795 @past_marks = map {1} @past_marks; 1114 @past_marks = map {1} @past_marks;
1115 } elsif ($r->param('library_basic')) {
1116 $library_basic = 1;
1117 } elsif ($r->param('library_advanced')) {
1118 $library_basic = 2;
796 } elsif ($r->param('select_none')) { 1119 } elsif ($r->param('select_none')) {
797 @past_marks = (); 1120 @past_marks = ();
798 1121
799 ##### No action requested, probably our first time here 1122 ##### No action requested, probably our first time here
800 1123
805 } ##### end of the if elsif ... 1128 } ##### end of the if elsif ...
806 1129
807 1130
808 ############# List of local sets 1131 ############# List of local sets
809 1132
810 my @all_set_defs = $db->listGlobalSets; 1133 my @all_db_sets = $db->listGlobalSets;
811 @all_set_defs = sortByName(undef, @all_set_defs); 1134 @all_db_sets = sortByName(undef, @all_db_sets);
812 1135
813 if ($use_previous_problems) { 1136 if ($use_previous_problems) {
814 @pg_files = @all_past_list; 1137 @pg_files = @all_past_list;
815 } else { 1138 } else {
816 $first_shown = 0; 1139 $first_shown = 0;
823 $self->{last_shown} = $last_shown; 1146 $self->{last_shown} = $last_shown;
824 $self->{browse_which} = $browse_which; 1147 $self->{browse_which} = $browse_which;
825 $self->{problem_seed} = $problem_seed; 1148 $self->{problem_seed} = $problem_seed;
826 $self->{pg_files} = \@pg_files; 1149 $self->{pg_files} = \@pg_files;
827 $self->{past_marks} = \@past_marks; 1150 $self->{past_marks} = \@past_marks;
828 $self->{all_set_defs} = \@all_set_defs; 1151 $self->{all_db_sets} = \@all_db_sets;
829 1152 $self->{library_basic} = $library_basic;
830} 1153}
831 1154
832 1155
833sub title { 1156sub title {
834 return "Library Browser"; 1157 return "Library Browser";
863 my $first_shown = $self->{first_shown}; 1186 my $first_shown = $self->{first_shown};
864 my $last_shown = $self->{last_shown}; 1187 my $last_shown = $self->{last_shown};
865 my $browse_which = $self->{browse_which}; 1188 my $browse_which = $self->{browse_which};
866 my $problem_seed = $self->{problem_seed}; 1189 my $problem_seed = $self->{problem_seed};
867 my @pg_files = @{$self->{pg_files}}; 1190 my @pg_files = @{$self->{pg_files}};
868 my @all_set_defs = @{$self->{all_set_defs}}; 1191 my @all_db_sets = @{$self->{all_db_sets}};
869 1192
870 my @pg_html=($last_shown>=$first_shown) ? 1193 my @pg_html=($last_shown>=$first_shown) ?
871 renderProblems(r=> $r, 1194 renderProblems(r=> $r,
872 user => $user, 1195 user => $user,
873 problem_list => [@pg_files[$first_shown..$last_shown]], 1196 problem_list => [@pg_files[$first_shown..$last_shown]],
876 ########## Top part 1199 ########## Top part
877 print CGI::startform({-method=>"POST", -action=>$r->uri, -name=>'mainform'}), 1200 print CGI::startform({-method=>"POST", -action=>$r->uri, -name=>'mainform'}),
878 $self->hidden_authen_fields, 1201 $self->hidden_authen_fields,
879 '<div align="center">', 1202 '<div align="center">',
880 CGI::start_table({-border=>2}); 1203 CGI::start_table({-border=>2});
881 $self->make_top_row('all_set_defs'=>\@all_set_defs, 1204 $self->make_top_row('all_db_sets'=>\@all_db_sets,
882 'browse_which'=> $browse_which); 1205 'browse_which'=> $browse_which);
883 print CGI::hidden(-name=>'browse_which', -default=>[$browse_which]), 1206 print CGI::hidden(-name=>'browse_which', -default=>[$browse_which]),
884 CGI::hidden(-name=>'problem_seed', -default=>[$problem_seed]); 1207 CGI::hidden(-name=>'problem_seed', -default=>[$problem_seed]);
885 for ($j = 0 ; $j < scalar(@pg_files) ; $j++) { 1208 for ($j = 0 ; $j < scalar(@pg_files) ; $j++) {
886 print CGI::hidden(-name=>"all_past_list$j", -default=>$pg_files[$j]); 1209 print CGI::hidden(-name=>"all_past_list$j", -default=>$pg_files[$j]);
918 print CGI::endform(), "\n"; 1241 print CGI::endform(), "\n";
919 1242
920 return ""; 1243 return "";
921} 1244}
922 1245
923############################################## End of Body
924
925# SKEL: To emit your own HTTP header, uncomment this:
926#
927#sub header {
928# my ($self) = @_;
929#
930# # Generate your HTTP header here.
931#
932# # If you return something, it will be used as the HTTP status code for this
933# # request. The Apache::Constants module might be useful for gerating status
934# # codes. If you don't return anything, the status code "OK" will be used.
935# return "";
936#}
937
938# SKEL: If you need to do any processing after the HTTP header is sent, but before
939# any template processing occurs, or you need to calculate values that will be
940# used in multiple methods, do it in this method:
941#
942#sub initialize {
943#my ($self) = @_;
944#}
945
946# SKEL: If you need to add tags to the document <HEAD>, uncomment this method:
947#
948#sub head {
949# my ($self) = @_;
950#
951# # You can print head tags here, like <META>, <SCRIPT>, etc.
952#
953# return "";
954#}
955
956# SKEL: To fill in the "info" box (to the right of the main body), use this
957# method:
958#
959#sub info {
960# my ($self) = @_;
961#
962# # Print HTML here.
963#
964# return "";
965#}
966
967# SKEL: To provide navigation links, use this method:
968#
969#sub nav {
970# my ($self, $args) = @_;
971#
972# # See the documentation of path() and pathMacro() in
973# # WeBWorK::ContentGenerator for more information.
974#
975# return "";
976#}
977
978# SKEL: For a little box for display options, etc., use this method:
979#
980#sub options {
981# my ($self) = @_;
982#
983# # Print HTML here.
984#
985# return "";
986#}
987
988# SKEL: For a list of sibling objects, use this method:
989#
990#sub siblings {
991# my ($self, $args) = @_;
992#
993# # See the documentation of siblings() and siblingsMacro() in
994# # WeBWorK::ContentGenerator for more information.
995# #
996# # Refer to implementations in ProblemSet and Problem.
997#
998# return "";
999#}
1000
1001=head1 AUTHOR 1246=head1 AUTHOR
1002 1247
1003Written by John Jones, jj (at) asu.edu. 1248Written by John Jones, jj (at) asu.edu.
1004 1249
1005=cut 1250=cut
1006 1251
1007
1008
10091; 12521;

Legend:
Removed from v.3397  
changed lines
  Added in v.3431

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9