--- loncom/interface/londocs.pm	2004/06/10 22:23:35	1.129
+++ loncom/interface/londocs.pm	2004/08/22 18:15:54	1.138
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Documents
 #
-# $Id: londocs.pm,v 1.129 2004/06/10 22:23:35 albertel Exp $
+# $Id: londocs.pm,v 1.138 2004/08/22 18:15:54 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -36,6 +36,7 @@ use Apache::lonratedt;
 use Apache::lonratsrv;
 use Apache::lonxml;
 use Apache::loncreatecourse;
+use Apache::lonnavmaps;
 use HTML::Entities;
 use GDBM_File;
 use Apache::lonlocal;
@@ -121,7 +122,8 @@ sub dumpbutton {
     if ($home) {
 	return '</td><td bgcolor="#DDDDCC">'.
 	    '<input type="submit" name="dumpcourse" value="'.
-	    &mt('Dump Course DOCS to Construction Space').'" />';
+	    &mt('Dump Course DOCS to Construction Space').'" />'.
+	    &Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs');
     } else {
 	return'</td><td bgcolor="#DDDDCC">'.
      &mt('Dump Course DOCS to Construction Space: available on other servers');
@@ -156,7 +158,7 @@ sub dumpcourse {
 	$crs=~s/\_/\//g;
 	foreach (keys %replacehash) {
 	    my $newfilename=$title.'/'.$replacehash{$_};
-	    $newfilename=~s/[^\w\/\.]+/\_/g;
+	    $newfilename=~s/[^\w\/\.\/]+/\_/g;
 	    my @dirs=split(/\//,$newfilename);
 	    my $path='/home/'.$ca.'/public_html';
 	    my $makepath=$path;
@@ -200,7 +202,8 @@ sub dumpcourse {
 		    $r->print(
 		  '<input type="hidden" name="authorspace" value="'.$1.'" />');
 		} else {
-		    $r->print('<option value="'.$1.'">'.$_.'</option>');
+		    $r->print('<option value="'.$1.'">'.$1.' - '.
+			      &Apache::loncommon::plainname(split(/\@/,$1)).'</option>');
 		}
 	    }
 	}
@@ -223,7 +226,7 @@ sub dumpcourse {
 		$title=$_;
 	    }
 	    $title=~s/\.(\w+)$//;
-	    $title=~s/\W+/\_/gs;
+	    $title=~s/[^\w\/]+/\_/gs;
 	    $title.='.'.$ext;
 	    $r->print("\n<td><input type='text' size='60' name='namefor_".$_."' value='".$title."' /></td></tr>\n");
 	}
@@ -234,6 +237,202 @@ sub dumpcourse {
     }
 }
 
+# ------------------------------------------------------ Generate "export" button
+
+sub exportbutton {
+    return '</td><td bgcolor="#DDDDCC">'.
+            '<input type="submit" name="exportcourse" value="'.
+            &mt('Export Course to IMS').'" />'.
+            &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs');
+}
+
+sub exportcourse {
+    my $r=shift;
+    my %discussiontime = &Apache::lonnet::dump('discussiontimes',
+                                               $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+    my $numdisc = keys %discussiontime;
+    my $navmap = Apache::lonnavmaps::navmap->new();
+    my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef);
+    my $curRes;
+
+    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+                                            ['finishexport']);
+    if ($ENV{'form.finishexport'}) {
+        &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+                                            ['archive','discussion']);
+
+        my @exportitems = ();
+        if (defined($ENV{'form.archive'})) {
+            if (ref($ENV{'form.archive'}) eq 'ARRAY') {
+                @exportitems = @{$ENV{'form.archive'}};
+            } else {
+                $exportitems[0] = $ENV{'form.archive'};
+            }
+        }
+        my @discussions = ();
+        if (defined($ENV{'form.discussion'})) {
+            if (ref($ENV{'form.discussion'}) eq 'ARRAY') {
+                @discussions = $ENV{'form.discussion'};
+            } else {
+                $discussions[0] = $ENV{'form.discussion'};
+            }
+        }
+        my $curRes;
+        my $count;
+        my %symbs;
+        my $display;
+        while ($curRes = $it->next()) {
+            if (ref($curRes)) {
+                $count ++;
+                $symbs{$count} = $curRes->symb();
+                if (grep/^$count$/,@exportitems) {
+                    $display.= 'Export content item '.$curRes->title()."<br />\n";
+                }
+                if (grep/^$count$/,@discussions) {
+                    $display.= 'Export discussion posts '.$curRes->title()."<br />\n";
+                }  
+            }
+        }
+
+        $r->print('<html><head><title>Export Course</title></head>'.
+            &Apache::loncommon::bodytag('Export course to IMS or SCORM content package'
+));
+
+        my $exportfile;
+        $r->print($display);
+        $r->print('</body></html>');
+    } else {
+        my $display;
+        $display = '<form name="exportdoc" method="post">'."\n";
+        $display .= 'Choose which items you wish to export from your course.<br /><br />';
+        $display .= '<table border="0" cellspacing="0" cellpadding="3">'.
+                    '<tr><td><fieldset><legend>&nbsp;<b>Content items</b></legend>'.
+                    '<input type="button" value="check all" '.
+                    'onclick="javascript:checkAll(document.exportdoc.archive)" />'.
+                    '&nbsp;&nbsp;<input type="button" value="uncheck all"'.
+                    ' onclick="javascript:uncheckAll(document.exportdoc.archive)" /></fieldset></td>'.
+                    '<td>&nbsp;</td><td>&nbsp;</td>'.
+                    '<td align="right"><fieldset><legend>&nbsp;<b>Discussion posts'.
+                    '</b></legend><input type="button" value="check all"'.
+                    ' onclick="javascript:checkAll(document.exportdoc.discussion)" />'.
+                    '&nbsp;&nbsp;<input type="button" value="uncheck all"'.
+                    ' onclick="javascript:uncheckAll(document.exportdoc.discussion)" /></fieldset></td>'.
+                    '</tr></table>';
+        my $curRes;
+        my $depth = 0;
+        my $count = 0;
+        my $boards = 0;
+        my $startcount = 5;
+        my %parent = ();
+        my %children = ();
+        my $lastcontainer = $startcount;
+        my @bgcolors = ('#F6F6F6','#FFFFFF');
+        $display .= '<table cellspacing="0"><tr>'.
+            '<td><b>Export content item?<br /></b></td><td>&nbsp;</td><td align="right">'."\n";
+        if ($numdisc > 0) {
+            $display.='<b>Export&nbsp;discussion posts?</b>'."\n";
+        }
+        $display.='&nbsp;</td></tr>';
+        while ($curRes = $it->next()) {
+            if (ref($curRes)) {
+                $count ++;
+            }
+            if ($curRes == $it->BEGIN_MAP()) {
+                $depth++;
+                $parent{$depth} = $lastcontainer;
+            }
+            if ($curRes == $it->END_MAP()) {
+                $depth--;
+                $lastcontainer = $parent{$depth};
+            }
+            if (ref($curRes)) {
+                my $symb = $curRes->symb();
+                my $color = $count%2;
+                $display .='<tr bgcolor='.$bgcolors[$color].'><td>'."\n".
+                    '<input type="checkbox" name="archive" value="'.$count.'" ';
+                if (($curRes->is_sequence()) || ($curRes->is_page())) {
+                    my $checkitem = $count + $boards + $startcount;
+                    $display .= 'onClick="javascript:propagateCheck('."'$checkitem'".')"';
+                }
+                $display .= ' />'."\n";
+                for (my $i=0; $i<$depth; $i++) {
+                    $display .= '<img src="/adm/lonIcons/whitespace1.gif" width="25" height="1" alt="" border="0" /><img src="/adm/lonIcons/whitespace1.gif" width="25" height="1" alt="" border="0" />'."\n";
+                }
+                if ($curRes->is_sequence()) {
+                    $display .= '<img src="/adm/lonIcons/navmap.folder.open.gif">&nbsp;'."\n";
+                    $lastcontainer = $count + $startcount + $boards;
+                } elsif ($curRes->is_page()) {
+                    $display .= '<img src="/adm/lonIcons/navmap.page.open.gif">&nbsp;'."\n";
+                    $lastcontainer = $count + $startcount + $boards;
+                }
+                my $currelem = $count+$boards+$startcount;
+                $children{$parent{$depth}} .= $currelem.':';
+                $display .= '&nbsp;'.$curRes->title().'</td>';
+                if ($discussiontime{$symb} > 0) {
+                    $boards ++;
+                    $currelem = $count+$boards+$startcount;
+                    $display .= '<td>&nbsp;</td><td align="right"><input type="checkbox" name="discussion" value="'.$count.'" />&nbsp;</td>'."\n";
+                } else {
+                    $display .= '<td colspan="2">&nbsp;</td>'."\n";
+                }
+            }
+        }
+        my $scripttag = qq|
+<script>
+
+function checkAll(field) {
+    for (i = 0; i < field.length; i++)
+        field[i].checked = true ;
+}
+
+function uncheckAll(field) {
+    for (i = 0; i < field.length; i++)
+        field[i].checked = false ;
+}
+
+function propagateCheck(item) {
+    if (document.exportdoc.elements[item].checked == true) {
+        containerCheck(item)
+    }
+} 
+
+function containerCheck(item) {
+    document.exportdoc.elements[item].checked = true
+    var numitems = $count + $boards + $startcount
+    var parents = new Array(numitems)
+    for (var i=$startcount; i<numitems; i++) {
+        parents[i] = new Array
+    }
+        |;
+
+        foreach my $container (sort { $a <=> $b } keys %children) {
+            my @contents = split/:/,$children{$container};
+            for (my $i=0; $i<@contents; $i ++) {
+                $scripttag .= '    parents['.$container.']['.$i.'] = '.$contents[$i]."\n";
+            }
+        }
+
+        $scripttag .= qq|
+    if (parents[item].length > 0) {
+        for (var j=0; j<parents[item].length; j++) {
+            containerCheck(parents[item][j])
+        }
+     }   
+}
+
+</script>
+        |;
+        $r->print('<html><head><title>Export Course</title>'.$scripttag.'</head>'.
+            &Apache::loncommon::bodytag('Export course to IMS or SCORM content package'
+));
+
+        $r->print($display.'</table>'.
+                  '<p><input type="hidden" name="finishexport" value="1">'.
+                  '<input type="submit" name="exportcourse" value="'.
+                  &mt('Export Course DOCS').'" /></p></form></body></html>');
+    }
+}
+
 
 # Imports the given (name, url) resources into the course
 # coursenum, coursedom, and folder must precede the list
@@ -279,7 +478,8 @@ sub breadcrumbs {
 		       
 						 
     }
-    return &Apache::lonhtmlcommon::breadcrumbs(undef,undef,undef,undef,undef,0);
+    return &Apache::lonhtmlcommon::breadcrumbs(undef,undef,undef,undef,undef,
+					       0,'nohelp');
 }
 
 sub editor {
@@ -493,6 +693,9 @@ sub editor {
            $r->print(&entryline($idx,$name,$url,$folder,$allowed,$_,$coursenum));
            $idx++;
         }
+	unless ($idx) {
+	    $r->print('<tr><td>'.&mt('Currently no documents.').'</td></tr>');
+	}
         $r->print('</table>');
     }
 }
@@ -570,13 +773,15 @@ END
     my $isfolder=0;
     my $folderarg;
     if ($uploaded) {
-       if ($extension eq 'sequence') {
-	  $icon=$iconpath.'/folder_closed.gif';
-          $url=~/$coursenum\/([\/\w]+)\.sequence$/;
-          $url='/adm/coursedocs?';
-	  $folderarg=$1;
-          $isfolder=1;
-       }
+	if ($extension eq 'sequence') {
+	    $icon=$iconpath.'/folder_closed.gif';
+	    $url=~/$coursenum\/([\/\w]+)\.sequence$/;
+	    $url='/adm/coursedocs?';
+	    $folderarg=$1;
+	    $isfolder=1;
+	} else {
+	    &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
+	}
     }
     $url=~s/^http\&colon\;\/\//\/adm\/wrapper\/ext\//;
     if ((!$isfolder) && ($residx) && ($folder!~/supplemental/)) {
@@ -643,12 +848,20 @@ ENDPARMS
 # ---------------------------------------------------------------- tie the hash
 
 sub tiehash {
+    my ($mode)=@_;
     $hashtied=0;
     if ($ENV{'request.course.fn'}) {
-        if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db",
-            &GDBM_READER(),0640)) {
+	if ($mode eq 'write') {
+	    if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db",
+		    &GDBM_WRCREAT(),0640)) {
+                $hashtied=2;
+	    }
+	} else {
+	    if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db",
+		    &GDBM_READER(),0640)) {
                 $hashtied=1;
-        }
+	    }
+	}
     }    
 }
 
@@ -814,8 +1027,9 @@ sub checkversions {
 	} else {
 	    $r->print('<h1><font color="red">'.&mt('An Error Occured while Attempting to Store your Version Settings').'</font></h1>');
 	}
-	&changewarning($r,'');
+	&mark_hash_old();
     }
+    &changewarning($r,'');
     if ($ENV{'form.timerange'} eq 'all') {
 # show all documents
 	$header=&mt('All Documents in Course');
@@ -935,7 +1149,9 @@ ENDHEADERS
 # Set version
 	    $r->print(&Apache::loncommon::select_form($setversions{$linkurl},
 						      'set_version_'.$linkurl,
-						      ('' => '',
+						      ('select_form_order' =>
+						       ['',1..$currentversion,'mostrecent'],
+						       '' => '',
 						       'mostrecent' => 'most recent',
 						       map {$_,$_} (1..$currentversion))));
 	    $r->print('</nobr></td></tr><tr><td></td>');
@@ -996,8 +1212,32 @@ ENDHEADERS
     &untiehash();
 }
 
+sub mark_hash_old {
+    my $retie_hash=0;
+    if ($hashtied) {
+	$retie_hash=1;
+	&untiehash();
+    }
+    &tiehash('write');
+    $hash{'old'}=1;
+    &untiehash();
+    if ($retie_hash) { &tiehash(); }
+}
+
+sub is_hash_old {
+    my $untie_hash=0;
+    if (!$hashtied) {
+	$untie_hash=1;
+	&tiehash();
+    }
+    my $return=$hash{'old'};
+    if ($untie_hash) { &untiehash(); }
+    return $return;
+}
+
 sub changewarning {
     my ($r,$postexec)=@_;
+    if (!&is_hash_old()) { return; }
     $r->print(
 '<script>function reinit(tf) { tf.submit();'.$postexec.' }</script>'. 
 '<form method="post" action="/adm/roles" target="loncapaclient">'.
@@ -1023,7 +1263,8 @@ sub handler {
            'Adding_External_Resource','Navigate_Content',
            'Adding_Folders','Docs_Overview', 'Load_Map',
            'Supplemental', 'Score_Upload_Form',
-           'Importing_LON-CAPA_Resource','Uploading_From_Harddrive') {
+           'Importing_LON-CAPA_Resource','Uploading_From_Harddrive',
+	   'Check_Resource_Versions','Verify_Content') {
       $help{$_}=&Apache::loncommon::help_open_topic('Docs_'.$_);
   }
     # Composite help files
@@ -1045,6 +1286,8 @@ sub handler {
       &checkversions($r);
   } elsif ($ENV{'form.dumpcourse'}) {
       &dumpcourse($r);
+  } elsif ($ENV{'form.exportcourse'}) {
+      &exportcourse($r);
   } else {
 # is this a standard course?
 
@@ -1218,8 +1461,7 @@ ENDNEWSCRIPT
   $r->print('</head>'.
             &Apache::loncommon::bodytag('Course Documents','',$events,
 					'','',$showdoc).
-	    &Apache::loncommon::help_open_faq(273).
-	    &Apache::loncommon::help_open_bug('RAT'));
+	    &Apache::loncommon::help_open_menu('','','','',273,'RAT'));
   unless ($showdoc) {
 # -----------------------------------------------------------------------------
        my %lt=&Apache::lonlocal::texthash(
@@ -1250,6 +1492,7 @@ ENDNEWSCRIPT
 # -----------------------------------------------------------------------------
     if ($allowed) {
        my $dumpbut=&dumpbutton();
+       my $exportbut=&exportbutton();
        my %lt=&Apache::lonlocal::texthash(
 					 'vc' => 'Verify Content',
 					 'cv' => 'Check/Set Resource Versions',
@@ -1276,10 +1519,11 @@ ENDNEWSCRIPT
 <form action="/adm/coursedocs" method="post" name="courseverify">
 <table bgcolor="#AAAAAA" width="100%" cellspacing="4" cellpadding="4">
 <tr><td bgcolor="#DDDDCC">
-<input type="submit" name="verify" value="$lt{'vc'}" />
+<input type="submit" name="verify" value="$lt{'vc'}" />$help{'Verify_Content'}
 </td><td bgcolor="#DDDDCC">
-<input type="submit" name="versions" value="$lt{'cv'}" />
+    <input type="submit" name="versions" value="$lt{'cv'}" />$help{'Check_Resource_Versions'}
 $dumpbut
+$exportbut
 </td></tr></table>
 </form>
 ENDCOURSEVERIFY
@@ -1306,8 +1550,9 @@ ENDCOURSEVERIFY
        $hadchanges=0;
        &editor($r,$coursenum,$coursedom,$folder,$allowed);
        if ($hadchanges) {
-	   &changewarning($r,$postexec);
+	   &mark_hash_old()
        }
+       &changewarning($r,$postexec);
        my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
                      '.sequence';
        $r->print(<<ENDFORM);