--- loncom/interface/londocs.pm 2013/03/17 14:27:34 1.537 +++ loncom/interface/londocs.pm 2013/03/31 22:36:01 1.538 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.537 2013/03/17 14:27:34 raeburn Exp $ +# $Id: londocs.pm,v 1.538 2013/03/31 22:36:01 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -323,10 +323,9 @@ sub group_import { } my $ext = 'false'; if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; } - $url = &LONCAPA::map::qtunescape($url); $name = &LONCAPA::map::qtunescape($name); if ($name eq '') { - $name = &mt('Web Page'); + $name = &LONCAPA::map::qtunescape(&mt('Web Page')); } if ($url =~ m{^/uploaded/$coursedom/$coursenum/((?:docs|supplemental)/(?:default|\d+))/new\.html$}) { my $filepath = $1; @@ -367,6 +366,7 @@ END return (&mt('Failed to save new web page.'),1); } } + $url = &LONCAPA::map::qtunescape($url); $LONCAPA::map::resources[$residx] = join(':', ($name, $url, $ext, 'normal', 'res')); } @@ -490,7 +490,7 @@ sub docs_change_log { } my $folderpath=$env{'form.folderpath'}; if ($folderpath eq '') { - $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Documents').':::::'); + $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Content').':::::'); } $pathitem = ''; @@ -655,57 +655,115 @@ sub docs_change_log { sub update_paste_buffer { my ($coursenum,$coursedom,$folder) = @_; + my (@possibles,%removals,%cuts); + if ($env{'form.multiremove'}) { + $env{'form.multiremove'} =~ s/,$//; + map { $removals{$_} = 1; } split(/,/,$env{'form.multiremove'}); + } + if (($env{'form.multicopy'}) || ($env{'form.multicut'})) { + if ($env{'form.multicut'}) { + $env{'form.multicut'} =~ s/,$//; + foreach my $item (split(/,/,$env{'form.multicut'})) { + unless ($removals{$item}) { + $cuts{$item} = 1; + push(@possibles,$item.':cut'); + } + } + } + if ($env{'form.multicopy'}) { + $env{'form.multicopy'} =~ s/,$//; + foreach my $item (split(/,/,$env{'form.multicopy'})) { + unless ($removals{$item} || $cuts{$item}) { + push(@possibles,$item.':copy'); + } + } + } + } elsif ($env{'form.markcopy'}) { + @possibles = split(/,/,$env{'form.markcopy'}); + } - return if (!defined($env{'form.markcopy'})); + return if (@possibles == 0); return if (!defined($env{'form.copyfolder'})); - return if ($env{'form.markcopy'} < 0); my ($errtext,$fatal) = &mapread($coursenum,$coursedom, $env{'form.copyfolder'}); - return if ($fatal); -# Mark for copying - my ($title,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$env{'form.markcopy'}]]); - if (&is_supplemental_title($title)) { - &Apache::lonnet::appenv({'docs.markedcopy_supplemental' => $title}); - ($title) = &Apache::loncommon::parse_supplemental_title($title); - } elsif ($env{'docs.markedcopy_supplemental'}) { - &Apache::lonnet::delenv('docs.markedcopy_supplemental'); - } - $url=~s{http(:|:)//https(:|:)//}{https$2//}; - - (my $cmd,undef)=split('_',$env{'form.cmd'}); - - my %addtoenv = ( - 'docs.markedcopy_title' => $title, - 'docs.markedcopy_url' => $url, - 'docs.markedcopy_cmd' => $cmd, - ); - &Apache::lonnet::delenv('docs.markedcopy_nested'); - &Apache::lonnet::delenv('docs.markedcopy_nestednames'); - if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(default|supplemental)_?(\d*)\.(page|sequence)$}) { - my $prefix = $1; - my $subdir =$2; - if ($subdir eq '') { - $subdir = $prefix; - } - my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps); - &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps, - \%hierarchy,\%titles,\%allmaps); - if (ref($hierarchy{$url}) eq 'HASH') { - my ($nested,$nestednames); - &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames); - $nested =~ s/\&$//; - $nestednames =~ s/\Q___&&&___\E$//; - if ($nested ne '') { - $addtoenv{'docs.markedcopy_nested'} = $nested; + my %curr_groups = &Apache::longroup::coursegroups(); + +# Retrieve current paste buffer suffixes. + my @currpaste = split(/,/,$env{'docs.markedcopies'}); + my (%pasteurls,@newpaste); + +# Construct identifiers for current contents of user's paste buffer + if (@currpaste) { + foreach my $suffix (@currpaste) { + my $cid = $env{'docs.markedcopy_crs_'.$suffix}; + my $url = $env{'docs.markedcopy_url_'.$suffix}; + if (($cid =~ /^$match_domain(?:_)$match_courseid$/) && + ($url ne '')) { + $pasteurls{$cid.'_'.$url}; + } + } + } + +# Mark items for copying (skip any items already in user's paste buffer) + my %addtoenv; + + foreach my $item (@possibles) { + my ($orderidx,$cmd) = split(/:/,$item); + next if ($orderidx =~ /\D/); + next unless (($cmd eq 'cut') || ($cmd eq 'copy') || ($cmd eq 'remove')); + my ($title,$url)=split(':',$LONCAPA::map::resources[$orderidx]); + my %denied = &action_restrictions($coursenum,$coursedom, + &LONCAPA::map::qtescape($url), + $env{'form.folderpath'},\%curr_groups); + next if ($denied{'copy'}); + $url=~s{http(:|:)//https(:|:)//}{https$2//}; + next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$url})); + my ($suffix,$errortxt,$locknotfreed) = + &new_timebased_suffix($env{'user.domain'},$env{'user.name'},'paste'); + push(@newpaste,$suffix); + if ($locknotfreed) { + return $locknotfreed; + last; + } + if (&is_supplemental_title($title)) { + &Apache::lonnet::appenv({'docs.markedcopy_supplemental_'.$suffix => $title}); + ($title) = &Apache::loncommon::parse_supplemental_title($title); + } + + $addtoenv{'docs.markedcopy_title_'.$suffix} = $title, + $addtoenv{'docs.markedcopy_url_'.$suffix} = $url, + $addtoenv{'docs.markedcopy_cmd_'.$suffix} = $cmd, + $addtoenv{'docs.markedcopy_crs_'.$suffix} = $env{'request.course.id'}; + + if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(default|supplemental)_?(\d*)\.(page|sequence)$}) { + my $prefix = $1; + my $subdir =$2; + if ($subdir eq '') { + $subdir = $prefix; } - if ($nestednames ne '') { - $addtoenv{'docs.markedcopy_nestednames'} = $nestednames; + my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps); + &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps, + \%hierarchy,\%titles,\%allmaps); + if (ref($hierarchy{$url}) eq 'HASH') { + my ($nested,$nestednames); + &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames); + $nested =~ s/\&$//; + $nestednames =~ s/\Q___&&&___\E$//; + if ($nested ne '') { + $addtoenv{'docs.markedcopy_nested_'.$suffix} = $nested; + } + if ($nestednames ne '') { + $addtoenv{'docs.markedcopy_nestednames_'.$suffix} = $nestednames; + } } } } + if (@newpaste) { + $addtoenv{'docs.markedcopies'} = join(',',(@currpaste,@newpaste)); + } &Apache::lonnet::appenv(\%addtoenv); delete($env{'form.markcopy'}); } @@ -737,155 +795,200 @@ sub recurse_uploaded_maps { sub print_paste_buffer { my ($r,$container,$folder,$coursedom,$coursenum) = @_; - return if (!defined($env{'docs.markedcopy_url'})); + return if (!defined($env{'docs.markedcopies'})); - my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent); - my $extension = (split(/\./,$env{'docs.markedcopy_url'}))[-1]; - if ($env{'docs.markedcopy_url'} =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) { - $is_external = 1; + unless (($env{'form.pastemarked'}) || ($env{'form.clearmarked'})) { + return if ($env{'docs.markedcopies'} eq ''); } - my ($canpaste,$nopaste,$othercrs,$areachange); - if ($folder =~ /^supplemental/) { - $canpaste = &supp_pasteable($env{'docs.markedcopy_url'}); - unless ($canpaste) { - $nopaste = &mt('Paste into Supplemental Content unavailable for this type of content.'); - } - } else { - $canpaste = 1; - } + my @currpaste = split(/,/,$env{'docs.markedcopies'}); + my ($pasteitems,@pasteable); - if ($canpaste) { - if ($env{'docs.markedcopy_url'} =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) { - my $srcdom = $1; - my $srcnum = $2; - my $rem = $3; - if (($srcdom ne $coursedom) || ($srcnum ne $coursenum)) { - $othercourse = 1; - if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) { - if ($canpaste) { - $othercrs = '
'.&mt('(from another course).'); - } - } else { - $canpaste = 0; - $nopaste = &mt('Paste from another course unavailable.') - } +# Construct identifiers for current contents of user's paste buffer + foreach my $suffix (@currpaste) { + next if ($suffix =~ /\D/); + my $cid = $env{'docs.markedcopy_crs_'.$suffix}; + my $url = $env{'docs.markedcopy_url_'.$suffix}; + if (($cid =~ /^$match_domain\_$match_courseid$/) && + ($url ne '')) { + my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent, + $canpaste,$nopaste,$othercrs,$areachange); + my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1]; + if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) { + $is_external = 1; } - if ($rem =~ m{^(default|supplemental)_?(\d*)\.(?:page|sequence)$}) { - my $prefix = $1; - $parent = $2; - if ($folder !~ /^\Q$prefix\E/) { - $areachange = 1; + if ($folder =~ /^supplemental/) { + $canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix}); + unless ($canpaste) { + $nopaste = &mt('Paste into Supplemental Content unavailable.'); } - $is_uploaded_map = 1; + } else { + $canpaste = 1; } - } - } - - $r->print('
' - .''.&mt('Clipboard').''); - my ($type,$buffer); - if ($is_external) { - $type = &mt('External Resource'); - $buffer = $type.': '. - &LONCAPA::map::qtescape($env{'docs.markedcopy_title'}).' ('. - &LONCAPA::map::qtescape($env{'docs.markedcopy_url'}).')'; - } else { - my $icon = &Apache::loncommon::icon($extension); - if ($extension eq 'sequence' && - $env{'docs.markedcopy_url'} =~ m{/default_\d+\.sequence$ }x) { - $icon = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL')); - $icon .= '/navmap.folder.closed.gif'; - } - $icon = ''; - $buffer = $icon.$type.': '. &Apache::loncommon::parse_supplemental_title(&LONCAPA::map::qtescape($env{'docs.markedcopy_title'})); - } - if ($canpaste) { - $r->print('
'.$buffer); - if ((!$areachange) && (!$othercourse) && - ($env{'docs.markedcopy_cmd'} eq 'cut')) { - if (($is_uploaded_map) || - ($env{'docs.markedcopy_url'} =~ /(bulletinboard|smppg)$/) || - ($env{'docs.markedcopy_url'} =~ m{^/uploaded/$coursedom/$coursenum/(?:docs|supplemental)/(.+)$})) { - my ($copytext,$movetext); - if ($is_uploaded_map) { - $copytext = &mt('Copy to new folder'); - $movetext = &mt('Move old folder'); - } elsif ($env{'docs.markedcopy_url'} =~ /bulletinboard$/) { - $copytext = &mt('Copy to new bulletin board (not posts)'); - $movetext = &mt('Move old bulletin board (not posts)'); - } elsif ($env{'docs.markedcopy_url'} =~ /smppg$/) { - $copytext = &mt('Copy to new simple page'); - $movetext = &mt('Move old simple page'); - } else { - $copytext = &mt('Copy to new uploaded document'); - $movetext = &mt('Move old uploaded document'); - } - $r->print((' 'x 4).''. - ''. - &mt('Show Paste Options').'
'. - '
'.(' 'x 4). - ''.(' ' x2). - '
'); - if (($is_uploaded_map) && ($env{'docs.markedcopy_nested'})) { - $r->print('
'.&mt('Folder to paste contains sub-folders'). - '
'); - my @pastemaps = split(/\&/,$env{'docs.markedcopy_nested'}); - my @titles = split(/\Q___&&&___\E/,$env{'docs.markedcopy_nestednames'}); - my $lastdir = $parent; - my %depths = ( - $lastdir => 0, - ); - my (%display,%deps); - for (my $i=0; $i<@pastemaps; $i++) { - ($lastdir,my $subfolderstr) = split(/\:/,$pastemaps[$i]); - my ($namedir,$esctitlestr) = split(/\:/,$titles[$i]); - my @subfolders = split(/,/,$subfolderstr); - $deps{$lastdir} = \@subfolders; - my @subfoldertitles = map { &unescape($_); } split(/,/,$esctitlestr); - my $depth = $depths{$lastdir} + 1; - my $offset = int($depth * 4); - my $indent = (' ' x $offset); - for (my $j=0; $j<@subfolders; $j++) { - $depths{$subfolders[$j]} = $depth; - $display{$subfolders[$j]} = - ''. - ''; + if ($canpaste) { + if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) { + my $srcdom = $1; + my $srcnum = $2; + my $rem = $3; + if (($srcdom ne $coursedom) || ($srcnum ne $coursenum)) { + $othercourse = 1; + if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) { + if ($canpaste) { + $othercrs = '
'.&mt('(from another course).'); + } + } else { + $canpaste = 0; + $nopaste = &mt('Paste from another course unavailable.'); } } - &recurse_print($r,$parent,\%deps,\%display); - $r->print('
'.$indent.$subfoldertitles[$j].' '.(' ' x2). - ''. - '
'); + if ($rem =~ m{^(default|supplemental)_?(\d*)\.(?:page|sequence)$}) { + my $prefix = $1; + $parent = $2; + if ($folder !~ /^\Q$prefix\E/) { + $areachange = 1; + } + $is_uploaded_map = 1; + } + } + } + if ($canpaste) { + push(@pasteable,$suffix); + } + my $buffer; + if ($is_external) { + $buffer = &mt('External Resource').': '. + &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}).' ('. + &LONCAPA::map::qtescape($url).')'; + } else { + my $icon = &Apache::loncommon::icon($extension); + if ($extension eq 'sequence' && + $url =~ m{/default_\d+\.sequence$}x) { + $icon = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL')); + $icon .= '/navmap.folder.closed.gif'; + } + $buffer = ''. + ': '. + &Apache::loncommon::parse_supplemental_title( + &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix})); + } + $pasteitems .= '
'; + my ($options,$onclick); + if (($canpaste) && (!$areachange) && (!$othercourse) && + ($env{'docs.markedcopy_cmd_'.$suffix} eq 'cut')) { + if (($is_uploaded_map) || + ($url =~ /(bulletinboard|smppg)$/) || + ($url =~ m{^/uploaded/$coursedom/$coursenum/(?:docs|supplemental)/(.+)$})) { + $options = &paste_options($suffix,$is_uploaded_map,$parent); + $onclick= 'onclick="showOptions(this,'."'$suffix'".');" '; + } + } + $pasteitems .= ''; + if ($nopaste) { + $pasteitems .= $nopaste; + } else { + if ($othercrs) { + $pasteitems .= $othercrs; + } + if ($options) { + $pasteitems .= $options; } - $r->print('
'); } + $pasteitems .= '
'; } - $r->print('
'.$othercrs); - $r->print(' - -'); - $r->print('
'); + } + if ($pasteitems eq '') { + &Apache::lonnet::delenv('docs.markedcopies'); + } + my ($pasteform,$form_start,$buttons,$form_end); + if ($pasteitems) { + $pasteitems .= '
'; + $form_start = '
'; + if (@pasteable) { + $buttons = ''.(' 'x2); + } + $buttons .= ''. + ''; + $form_end = '
'; } else { - $r->print(&mt('Paste buffer contains:').' '.$buffer. - '

'.$nopaste.'

'); + $pasteitems = &mt('Clipboard is empty'); } - $r->print('
'); + $r->print($form_start + .'
' + .''.&mt('Clipboard').(' ' x2).$buttons.'' + .$pasteitems + .'
' + .$form_end); +} + +sub paste_options { + my ($suffix,$is_uploaded_map,$parent) = @_; + my ($copytext,$movetext); + if ($is_uploaded_map) { + $copytext = &mt('Copy to new folder'); + $movetext = &mt('Move old'); + } elsif ($env{'docs.markedcopy_url_'.$suffix} =~ /bulletinboard$/) { + $copytext = &mt('Copy to new board'); + $movetext = &mt('Move (not posts)'); + } elsif ($env{'docs.markedcopy_url_'.$suffix} =~ /smppg$/) { + $copytext = &mt('Copy to new page'); + $movetext = &mt('Move'); + } else { + $copytext = &mt('Copy to new file'); + $movetext = &mt('Move'); + } + my $output = '
'. + ''. + ''; + return $output; } sub recurse_print { - my ($r,$dir,$deps,$display) = @_; - $r->print($display->{$dir}."\n"); + my ($outputref,$dir,$deps,$display) = @_; + $$outputref .= $display->{$dir}."\n"; if (ref($deps->{$dir}) eq 'ARRAY') { foreach my $subdir (@{$deps->{$dir}}) { - &recurse_print($r,$subdir,$deps,$display); + &recurse_print($outputref,$subdir,$deps,$display); } } } @@ -904,22 +1007,34 @@ sub supp_pasteable { sub paste_popup_js { my %lt = &Apache::lonlocal::texthash( - show => 'Show Paste Options', - hide => 'Hide Paste Options', + show => 'Show Options', + hide => 'Hide Options', ); return <<"END"; -function showPasteOptions() { - document.getElementById('pasteoptions').style.display='block'; - document.getElementById('pasteoptions').style.textAlign='left'; - document.getElementById('pasteoptions').style.textFace='normal'; - document.getElementById('pasteoptionstext').innerHTML ='$lt{'hide'}
'; +function showPasteOptions(suffix) { + document.getElementById('pasteoptions_'+suffix).style.display='block'; + document.getElementById('pasteoptionstext_'+suffix).innerHTML = '    $lt{'hide'}'; return; } -function hidePasteOptions() { - document.getElementById('pasteoptions').style.display='none'; - document.getElementById('pasteoptionstext').innerHTML ='$lt{'show'}'; +function hidePasteOptions(suffix) { + document.getElementById('pasteoptions_'+suffix).style.display='none'; + document.getElementById('pasteoptionstext_'+suffix).innerHTML ='    $lt{'show'}'; + return; +} + +function showOptions(caller,suffix) { + if (document.getElementById('pasteoptionstext_'+suffix)) { + if (caller.checked) { + document.getElementById('pasteoptionstext_'+suffix).innerHTML ='    $lt{'show'}'; + } else { + document.getElementById('pasteoptionstext_'+suffix).innerHTML =''; + } + if (document.getElementById('pasteoptions_'+suffix)) { + document.getElementById('pasteoptions_'+suffix).style.display='none'; + } + } return; } @@ -931,276 +1046,423 @@ END sub do_paste_from_buffer { my ($coursenum,$coursedom,$folder,$container,$errors) = @_; +# Array of items in paste buffer + my (@currpaste,%pastebuffer,%allerrors); + @currpaste = split(/,/,$env{'docs.markedcopies'}); + # Early out if paste buffer is empty - if (!$env{'form.pastemarked'}) { + if (@currpaste == 0) { return (); + } + map { $pastebuffer{$_} = 1; } @currpaste; + +# Array of items selected items to paste + my @reqpaste = &Apache::loncommon::get_env_multiple('form.pasting'); + +# Early out if nothing selected to paste + if (@reqpaste == 0) { + return(); + } + my @topaste; + foreach my $suffix (@reqpaste) { + next if ($suffix =~ /\D/); + next unless (exists($pastebuffer{$suffix})); + push(@topaste,$suffix); } -# Supplemental content may only include certain types of content -# Early out if pasted content is not supported in Supplemental area - if ($folder =~ /^supplemental/) { - unless (&supp_pasteable($env{'docs.markedcopy_url'})) { - return (&mt('Paste failed: content type is not supported within Supplemental Content')); - } +# Early out if nothing available to paste + if (@topaste == 0) { + return(); } -# Prepare to paste resource at end of list - my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url'}); - my $title=&LONCAPA::map::qtescape($env{'docs.markedcopy_title'}); + my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%duplicate, + %prefixchg,%srcdom,%srcnum,%marktomove,$save_err,$lockerrors,$allresult, + %msgs); - my ($is_map,$srcdom,$srcnum,$prefixchg,%before,%after,%mapchanges,%tomove); - if ($url=~/\.(page|sequence)$/) { - $is_map = 1; - } - if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/([^/]+)}) { - $srcdom = $1; - $srcnum = $2; - my $oldprefix = $3; + foreach my $suffix (@topaste) { + my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix}); +# Supplemental content may only include certain types of content +# Early out if pasted content is not supported in Supplemental area + if ($folder =~ /^supplemental/) { + unless (&supp_pasteable($url)) { + $notinsupp{$suffix} = 1; + next; + } + } + if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/}) { + my $srcd = $1; + my $srcn = $2; # When paste buffer was populated using an active role in a different course -# check for mdc privilege in the course from which the resource was pasted - if (($srcdom ne $coursedom) || ($srcnum ne $coursenum)) { - unless ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) { - return (&mt('Paste failed: Item is from a different course which you do not have rights to edit.')); +# check for mdc privilege in the course from which the resource was pasted + if (($srcd ne $coursedom) || ($srcn ne $coursenum)) { + unless ($env{"user.priv.cm./$srcd/$srcn"} =~ /\Q:mdc&F\E/) { + $notincrs{$suffix} = 1; + next; + } } + $srcdom{$suffix} = $srcd; + $srcnum{$suffix} = $srcn; } + + push(@dopaste,$suffix); + if ($url=~/\.(page|sequence)$/) { + $is_map{$suffix} = 1; + } + + if ($url =~ m{^/uploaded/$match_domain/$match_courseid/([^/]+)}) { + my $oldprefix = $1; # When pasting content from Main Content to Supplemental Content and vice versa # URLs will contain different paths (which depend on whether pasted item is # a folder/page or a document. - if (($folder =~ /^supplemental/) && (($oldprefix =~ /^default/) || ($oldprefix eq 'docs'))) { - $prefixchg = 1; - %before = ( map => 'default', - doc => 'docs'); - %after = ( map => 'supplemental', - doc => 'supplemental' ); - } elsif (($folder =~ /^default/) && ($oldprefix =~ /^supplemental/)) { - $prefixchg = 1; - %before = ( map => 'supplemental', - doc => 'supplemental'); - %after = ( map => 'default', - doc => 'docs'); - } + if (($folder =~ /^supplemental/) && (($oldprefix =~ /^default/) || ($oldprefix eq 'docs'))) { + $prefixchg{$suffix} = 'docstosupp'; + } elsif (($folder =~ /^default/) && ($oldprefix =~ /^supplemental/)) { + $prefixchg{$suffix} = 'supptodocs'; + } # If pasting an uploaded map, get list of contained uploaded maps. - my @nested; - if ($env{'docs.markedcopy_nested'}) { - my ($type) = ($oldprefix =~ /^(default|supplemental)/); - my @items = split(/\&/,$env{'docs.markedcopy_nested'}); - my @deps = map { /\d+:([\d,]+$)/ } @items; - foreach my $dep (@deps) { - if ($dep =~ /,/) { - push(@nested,split(/,/,$dep)); - } else { - push(@nested,$dep); + if ($env{'docs.markedcopy_nested_'.$suffix}) { + my @nested; + my ($type) = ($oldprefix =~ /^(default|supplemental)/); + my @items = split(/\&/,$env{'docs.markedcopy_nested_'.$suffix}); + my @deps = map { /\d+:([\d,]+$)/ } @items; + foreach my $dep (@deps) { + if ($dep =~ /,/) { + push(@nested,split(/,/,$dep)); + } else { + push(@nested,$dep); + } } - } - foreach my $item (@nested) { - if ($env{'form.docs.markedcopy_'.$item} eq 'move') { - $tomove{$type.'_'.$item} = 1; + foreach my $item (@nested) { + if ($env{'form.docs.markedcopy_'.$suffix.'_'.$item} eq 'move') { + push(@{$marktomove{$suffix}},$type.'_'.$item); + } } } } } +# Early out if nothing available to paste + if (@dopaste == 0) { + return (); + } + +# Populate message hash and hashes used for main content <=> supplemental content +# changes + + %msgs = &Apache::lonlocal::texthash ( + notinsupp => 'Paste failed: content type is not supported within Supplemental Content', + notincrs => 'Paste failed: Item is from a different course which you do not have rights to edit.', + duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.', + ); + + %before = ( + docstosupp => { + map => 'default', + doc => 'docs', + }, + supptodocs => { + map => 'supplemental', + doc => 'supplemental', + }, + ); + + %after = ( + docstosupp => { + map => 'supplemental', + doc => 'supplemental' + }, + supptodocs => { + map => 'default', + doc => 'docs', + }, + ); + +# Retrieve information about all course maps in main content area + + my $allmaps = {}; + if ($folder =~ /^default/) { + $allmaps = + &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, + $env{"course.$env{'request.course.id'}.home"}, + $env{'request.course.id'}); + } + + my (@toclear,%mapurls,%lockerrs,%msgerrs,%results); + +# Loop over the items to paste + foreach my $suffix (@dopaste) { # Maps need to be copied first - my ($oldurl,%removefrommap,%removeparam,%addedmaps,%rewrites,%retitles,%copies, - %dbcopies,%zombies,%params,%docmoves,%mapmoves,%newsubdir,%newurls); - $oldurl = $url; - if ($is_map) { + my (%removefrommap,%removeparam,%addedmaps,%rewrites,%retitles,%copies, + %dbcopies,%zombies,%params,%docmoves,%mapmoves,%mapchanges,%newsubdir, + %newurls,%tomove); + if (ref($marktomove{$suffix}) eq 'ARRAY') { + map { $tomove{$_} = 1; } @{$marktomove{$suffix}}; + } + my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix}); + my $title=&LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}); + my $oldurl = $url; + if ($is_map{$suffix}) { # If pasting a map, check if map contains other maps - my ($allmaps,%hierarchy,%titles); - $allmaps = {}; - if ($folder =~ /^default/) { - $allmaps = - &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, - $env{"course.$env{'request.course.id'}.home"}, - $env{'request.course.id'}); - } - &contained_map_check($url,$folder,\%removefrommap,\%removeparam, - \%addedmaps,\%hierarchy,\%titles,$allmaps); - if ($url=~ m{^/uploaded/}) { - my $newurl; - unless ($env{'form.docs.markedcopy_options'} eq 'move') { - ($newurl,my $error) = - &get_newmap_url($url,$folder,$prefixchg,$coursedom,$coursenum, - $srcdom,$srcnum,\$title,$allmaps,\%newurls); - if ($error) { - return ($error); - } - if ($newurl ne '') { - if ($newurl ne $url) { - if ($newurl =~ /(?:default|supplemental)_(\d+).(?:sequence|page)$/) { - $newsubdir{$url} = $1; + my (%hierarchy,%titles); + &contained_map_check($url,$folder,\%removefrommap,\%removeparam, + \%addedmaps,\%hierarchy,\%titles,$allmaps); + if ($url=~ m{^/uploaded/}) { + my $newurl; + unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') { + ($newurl,my $error) = + &get_newmap_url($url,$folder,$prefixchg{$suffix},$coursedom, + $coursenum,$srcdom{$suffix},$srcnum{$suffix}, + \$title,$allmaps,\%newurls); + if ($error) { + $allerrors{$suffix} = $error; + next; + } + if ($newurl ne '') { + if ($newurl ne $url) { + if ($newurl =~ /(?:default|supplemental)_(\d+).(?:sequence|page)$/) { + $newsubdir{$url} = $1; + } + $mapchanges{$url} = 1; } - $mapchanges{$url} = 1; } } - } - if (($srcdom ne $coursedom) || ($srcnum ne $coursenum) || ($prefixchg) || - (($newurl ne '') && ($newurl ne $url))) { - unless (&url_paste_fixups($url,$folder,$prefixchg,$coursedom, - $coursenum,$srcdom,$srcnum,$allmaps, - \%rewrites,\%retitles,\%copies,\%dbcopies, - \%zombies,\%params,\%mapmoves,\%mapchanges,\%tomove, - \%newsubdir,\%newurls)) { - $mapmoves{$url} = 1; - } - $url = $newurl; - } elsif ($env{'docs.markedcopy_nested'}) { - &url_paste_fixups($url,$folder,$prefixchg,$coursedom,$coursenum, - $srcdom,$srcnum,$allmaps,\%rewrites, - \%retitles,\%copies,\%dbcopies,\%zombies,\%params,\%mapmoves, - \%mapchanges,\%tomove,\%newsubdir,\%newurls); - } - } elsif ($url=~m {^/res/}) { -# published maps can only exists once, so remove it from paste buffer when done - &Apache::lonnet::delenv('docs.markedcopy'); -# if pasting published map (main content are only) check map is not already in course - if ($folder =~ /^default/) { - if ((ref($allmaps) eq 'HASH') && ($allmaps->{$url})) { - return (&mt('Paste failed: only one instance of a particular published sequence or page is allowed within each course.')); + if (($srcdom{$suffix} ne $coursedom) || + ($srcnum{$suffix} ne $coursenum) || + ($prefixchg{$suffix}) || (($newurl ne '') && ($newurl ne $url))) { + unless (&url_paste_fixups($url,$folder,$prefixchg{$suffix}, + $coursedom,$coursenum,$srcdom{$suffix}, + $srcnum{$suffix},$allmaps,\%rewrites, + \%retitles,\%copies,\%dbcopies, + \%zombies,\%params,\%mapmoves, + \%mapchanges,\%tomove,\%newsubdir, + \%newurls)) { + $mapmoves{$url} = 1; + } + $url = $newurl; + } elsif ($env{'docs.markedcopy_nested_'.$suffix}) { + &url_paste_fixups($url,$folder,$prefixchg{$suffix},$coursedom, + $coursenum,$srcdom{$suffix},$srcnum{$suffix}, + $allmaps,\%rewrites,\%retitles,\%copies,\%dbcopies, + \%zombies,\%params,\%mapmoves,\%mapchanges, + \%tomove,\%newsubdir,\%newurls); + } + } elsif ($url=~m {^/res/}) { +# published map can only exists once, so remove from paste buffer when done + push(@toclear,$suffix); +# if pasting published map (main content area only) check map not already in course + if ($folder =~ /^default/) { + if ((ref($allmaps) eq 'HASH') && ($allmaps->{$url})) { + $duplicate{$suffix} = 1; + next; + } } } } - } - my $lockerrors; - if ($url=~ m{/(bulletinboard|smppg)$}) { - my $prefix = $1; - #need to copy the db contents to a new one, unless this is a move. - my %info = ( - src => $url, - cdom => $coursedom, - cnum => $coursenum, - ); - my (%lockerr,$msg); - unless ($env{'form.docs.markedcopy_options'} eq 'move') { - my ($newurl,$result,$errtext) = - &dbcopy(\%info,$coursedom,$coursenum,\%lockerr); - if ($result eq 'ok') { - $url = $newurl; - $title=&mt('Copy of').' '.$title; - } else { - if ($prefix eq 'smppg') { - $msg = &mt('Paste failed: An error occurred when copying the simple page.').' '.$errtext; - } elsif ($prefix eq 'bulletinboard') { - $msg = &mt('Paste failed: An error occurred when copying the bulletin board.').' '.$errtext; + if ($url=~ m{/(bulletinboard|smppg)$}) { + my $prefix = $1; + #need to copy the db contents to a new one, unless this is a move. + my %info = ( + src => $url, + cdom => $coursedom, + cnum => $coursenum, + ); + unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') { + my (%lockerr,$msg); + my ($newurl,$result,$errtext) = + &dbcopy(\%info,$coursedom,$coursenum,\%lockerr); + if ($result eq 'ok') { + $url = $newurl; + $title=&mt('Copy of').' '.$title; + } else { + if ($prefix eq 'smppg') { + $msg = &mt('Paste failed: An error occurred when copying the simple page.').' '.$errtext; + } elsif ($prefix eq 'bulletinboard') { + $msg = &mt('Paste failed: An error occurred when copying the bulletin board.').' '.$errtext; + } + $results{$suffix} = $result; + $msgerrs{$suffix} = $msg; + $lockerrs{$suffix} = $lockerr{$prefix}; + next; + } + if ($lockerr{$prefix}) { + $lockerrs{$suffix} = $lockerr{$prefix}; } - return ($result,undef,[$msg],$lockerr{$prefix}); - } - if ($lockerr{$prefix}) { - $lockerrors = $lockerr{$prefix}; } } - } - $title = &LONCAPA::map::qtunescape($title); - my $ext='false'; - if ($url=~m{^http(|s)://}) { $ext='true'; } - $url = &LONCAPA::map::qtunescape($url); + $title = &LONCAPA::map::qtunescape($title); + my $ext='false'; + if ($url=~m{^http(|s)://}) { $ext='true'; } + if ($env{'docs.markedcopy_supplemental_'.$suffix}) { + if ($folder !~ /^supplemental/) { + (undef,undef,$title) = + &Apache::loncommon::parse_supplemental_title($env{'docs.markedcopy_supplemental_'.$suffix}); + } + } else { + if ($folder=~/^supplemental/) { + $title=time.'___&&&___'.$env{'user.name'}.'___&&&___'. + $env{'user.domain'}.'___&&&___'.$title; + } + } # For uploaded files (excluding pages/sequences) path in copied file is changed # if paste is from Main to Supplemental (or vice versa), or if pasting between # courses. - my $newidx; - unless ($is_map) { + unless ($is_map{$suffix}) { + my $newidx; # Now insert the URL at the bottom - $newidx = &LONCAPA::map::getresidx($url); - if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(?:docs|supplemental)/(.+)$}) { - my $relpath = $1; - if ($relpath ne '') { - my ($prefix,$subdir,$rem) = ($relpath =~ m{^(default|\d+)/(\d+)/(.+)$}); - my ($newloc,$newdocsdir) = ($folder =~ /^(default|supplemental)_?(\d*)/); - my $newprefix = $newloc; - if ($newloc eq 'default') { - $newprefix = 'docs'; - } - if ($newdocsdir eq '') { - $newdocsdir = 'default'; - } - if (($prefixchg) || - ($srcdom ne $coursedom) || ($srcnum ne $coursenum) || - ($env{'form.docs.markedcopy_options'} ne 'move')) { - my $newpath = "$newprefix/$newdocsdir/$newidx/$rem"; - $url = - &Apache::lonclonecourse::writefile($env{'request.course.id'},$newpath, - &Apache::lonnet::getfile($oldurl)); - if ($url eq '/adm/notfound.html') { - return (&mt('Paste failed: an error occurred saving the file.')); - } else { - my ($newsubpath) = ($newpath =~ m{^(.*/)[^/]*$}); - $newsubpath =~ s{/+$}{/}; - $docmoves{$oldurl} = $newsubpath; + $newidx = &LONCAPA::map::getresidx(&LONCAPA::map::qtunescape($url)); + if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(?:docs|supplemental)/(.+)$}) { + my $relpath = $1; + if ($relpath ne '') { + my ($prefix,$subdir,$rem) = ($relpath =~ m{^(default|\d+)/(\d+)/(.+)$}); + my ($newloc,$newdocsdir) = ($folder =~ /^(default|supplemental)_?(\d*)/); + my $newprefix = $newloc; + if ($newloc eq 'default') { + $newprefix = 'docs'; + } + if ($newdocsdir eq '') { + $newdocsdir = 'default'; + } + if (($prefixchg{$suffix}) || + ($srcdom{$suffix} ne $coursedom) || + ($srcnum{$suffix} ne $coursenum) || + ($env{'form.docs.markedcopy_options_'.$suffix} ne 'move')) { + my $newpath = "$newprefix/$newdocsdir/$newidx/$rem"; + $url = + &Apache::lonclonecourse::writefile($env{'request.course.id'},$newpath, + &Apache::lonnet::getfile($oldurl)); + if ($url eq '/adm/notfound.html') { + $msgs{$suffix} = &mt('Paste failed: an error occurred saving the file.'); + next; + } else { + my ($newsubpath) = ($newpath =~ m{^(.*/)[^/]*$}); + $newsubpath =~ s{/+$}{/}; + $docmoves{$oldurl} = $newsubpath; + } } } } - } - } -# Apply any changes to maps, or copy dependencies for uploaded HTML pages - my ($result,$save_err); - my %updated = ( - rewrites => \%rewrites, - zombies => \%zombies, - removefrommap => \%removefrommap, - removeparam => \%removeparam, - dbcopies => \%dbcopies, - retitles => \%retitles, - ); - my %info = ( - newsubdir => \%newsubdir, - params => \%params, - before => \%before, - after => \%after, - ); - my %moves = ( - copies => \%copies, - docmoves => \%docmoves, - mapmoves => \%mapmoves, - ); - ($result,my $msgsarray,my $lockerror) = - &apply_fixups($folder,$is_map,$coursedom,$coursenum,$errors, - \%updated,\%info,\%moves,$prefixchg,$oldurl,$url,'paste'); - $lockerrors .= $lockerror; - if ($result eq 'ok') { - if ($is_map) { - my ($errtext,$fatal) = &mapread($coursenum,$coursedom, - $folder.'.'.$container); - return ($errtext,$save_err,$msgsarray,$lockerrors) if ($fatal); - - if ($#LONCAPA::map::order<1) { - my $idx=&LONCAPA::map::getresidx(); - if ($idx<=0) { $idx=1; } - $LONCAPA::map::order[0]=$idx; - $LONCAPA::map::resources[$idx]=''; - } - $newidx = &LONCAPA::map::getresidx($url); - } - if ($env{'docs.markedcopy_supplemental'}) { - if ($folder !~ /^supplemental/) { - (undef,undef,$title) = - &Apache::loncommon::parse_supplemental_title($env{'docs.markedcopy_supplemental'}); - } - } else { - if ($folder=~/^supplemental/) { - $title=time.'___&&&___'.$env{'user.name'}.'___&&&___'. - $env{'user.domain'}.'___&&&___'.$title; + $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url). + ':'.$ext.':normal:res'; + push(@LONCAPA::map::order,$newidx); +# Store the result + my ($errtext,$fatal) = + &storemap($coursenum,$coursedom,$folder.'.'.$container,1); + if ($fatal) { + $save_err .= $errtext; + $allresult = 'fail'; } } - $LONCAPA::map::resources[$newidx]= $title.':'.$url.':'.$ext.':normal:res'; - push(@LONCAPA::map::order, $newidx); + +# Apply any changes to maps, or copy dependencies for uploaded HTML pages + unless ($allresult eq 'fail') { + my %updated = ( + rewrites => \%rewrites, + zombies => \%zombies, + removefrommap => \%removefrommap, + removeparam => \%removeparam, + dbcopies => \%dbcopies, + retitles => \%retitles, + ); + my %info = ( + newsubdir => \%newsubdir, + params => \%params, + ); + if ($prefixchg{$suffix}) { + $info{'before'} = $before{$prefixchg{$suffix}}; + $info{'after'} = $after{$prefixchg{$suffix}}; + } + my %moves = ( + copies => \%copies, + docmoves => \%docmoves, + mapmoves => \%mapmoves, + ); + (my $result,$msgs{$suffix},my $lockerror) = + &apply_fixups($folder,$is_map{$suffix},$coursedom,$coursenum,$errors, + \%updated,\%info,\%moves,$prefixchg{$suffix},$oldurl, + $url,'paste'); + $lockerrors .= $lockerror; + if ($result eq 'ok') { + if ($is_map{$suffix}) { + my ($errtext,$fatal) = &mapread($coursenum,$coursedom, + $folder.'.'.$container); + if ($fatal) { + $allresult = 'failread'; + } else { + if ($#LONCAPA::map::order<1) { + my $idx=&LONCAPA::map::getresidx(); + if ($idx<=0) { $idx=1; } + $LONCAPA::map::order[0]=$idx; + $LONCAPA::map::resources[$idx]=''; + } + my $newidx = &LONCAPA::map::getresidx(&LONCAPA::map::qtunescape($url)); + $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url). + ':'.$ext.':normal:res'; + push(@LONCAPA::map::order,$newidx); # Store the result - my ($errtext,$fatal) = - &storemap($coursenum,$coursedom,$folder.'.'.$container,1); - if ($fatal) { - $save_err = $errtext; + my ($errtext,$fatal) = + &storemap($coursenum,$coursedom,$folder.'.'.$container,1); + if ($fatal) { + $save_err .= $errtext; + $allresult = 'failstore'; + } + } + } + if ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') { + push(@toclear,$suffix); + } + } } } + &clear_from_buffer(\@toclear,\@currpaste); + my $msgsarray; + foreach my $suffix (keys(%msgs)) { + if (ref($msgs{$suffix}) eq 'ARRAY') { + $msgsarray .= join(',',@{$msgs{$suffix}}); + } + } + return ($allresult,$save_err,$msgsarray,$lockerrors); +} - if ($env{'form.docs.markedcopy_options'} eq 'move') { - &Apache::lonnet::delenv('docs.markedcopy'); - &Apache::lonnet::delenv('docs.markedcopy_nested'); - &Apache::lonnet::delenv('docs.markedcopy_nestednames'); +sub do_buffer_empty { + my @currpaste = split(/,/,$env{'docs.markedcopies'}); + if (@currpaste == 0) { + return &mt('Clipboard is already empty'); + } + my @toclear = &Apache::loncommon::get_env_multiple('form.pasting'); + if (@toclear == 0) { + return &mt('Nothing selected to clear from clipboard'); + } + my $numdel = &clear_from_buffer(\@toclear,\@currpaste); + if ($numdel) { + return &mt('[quant,_1,item] cleared from clipboard',$numdel); + } else { + return &mt('Clipboard unchanged'); } - return ($result,$save_err,$msgsarray,$lockerrors); + return; +} + +sub clear_from_buffer { + my ($toclear,$currpaste) = @_; + return unless ((ref($toclear) eq 'ARRAY') && (ref($currpaste) eq 'ARRAY')); + my %pastebuffer; + map { $pastebuffer{$_} = 1; } @{$currpaste}; + my $numdel = 0; + foreach my $suffix (@{$toclear}) { + next if ($suffix =~ /\D/); + next unless (exists($pastebuffer{$suffix})); + my $regexp = 'docs.markedcopy_[a-z]+_'.$suffix; + if (&Apache::lonnet::delenv($regexp,1) eq 'ok') { + delete($pastebuffer{$suffix}); + $numdel ++; + } + } + my $newbuffer = join(',',sort(keys(%pastebuffer))); + &Apache::lonnet::appenv({'docs.markedcopies' => $newbuffer}); + return $numdel; } sub get_newmap_url { @@ -1744,7 +2006,8 @@ sub apply_fixups { if (defined($LONCAPA::map::resources[$idx])) { my $changed; my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::resources[$idx]); - if ((exists($toremove{$idx})) && ($toremove{$idx} eq $src)) { + if ((exists($toremove{$idx})) && + ($toremove{$idx} eq &LONCAPA::map::qtescape($src))) { splice(@LONCAPA::map::order,$i,1); if (ref($currparam{$idx}) eq 'ARRAY') { foreach my $name (@{$currparam{$idx}}) { @@ -1783,7 +2046,7 @@ sub apply_fixups { $changed = 1; } if ($changed) { - $LONCAPA::map::resources[$idx] = join(':',($title,$src,$ext,$type)); + $LONCAPA::map::resources[$idx] = join(':',($title,&LONCAPA::map::qtunescape($src),$ext,$type)); } } } @@ -1981,12 +2244,13 @@ sub update_parameter { sub handle_edit_cmd { my ($coursenum,$coursedom) =@_; + return if ($env{'form.cmd'} eq ''); my ($cmd,$idx)=split('_',$env{'form.cmd'}); my $ratstr = $LONCAPA::map::resources[$LONCAPA::map::order[$idx]]; my ($title, $url, @rrest) = split(':', $ratstr); - if ($cmd eq 'del') { + if ($cmd eq 'remove') { if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) && ($url!~/$LONCAPA::assess_page_seq_re/)) { &Apache::lonnet::removeuploadedurl($url); @@ -2008,7 +2272,6 @@ sub handle_edit_cmd { @LONCAPA::map::order[$idx+1,$idx] = @LONCAPA::map::order[$idx,$idx+1]; } elsif ($cmd eq 'rename') { - my $comment = &LONCAPA::map::qtunescape($env{'form.title'}); if ($comment=~/\S/) { $LONCAPA::map::resources[$LONCAPA::map::order[$idx]]= @@ -2017,6 +2280,7 @@ sub handle_edit_cmd { # Devalidate title cache my $renamed_url=&LONCAPA::map::qtescape($url); &Apache::lonnet::devalidate_title_cache($renamed_url); + } else { return 0; } @@ -2102,10 +2366,10 @@ sub editor { return $save_error; } if ($paste_res ne 'ok') { - $r->print('

'.$paste_res.'

'); + $r->print('

'.$paste_res.'

'); } if (keys(%paste_errors) > 0) { - $r->print('

'."\n". + $r->print('

'."\n". &mt('The following files are either dependencies of a web page or references within a folder and/or composite page which could not be copied during the paste operation:')."\n". '

'."\n"); } - } + } elsif ($env{'form.clearmarked'}) { + my $output = &do_buffer_empty(); + if ($output) { + $r->print('

'.$output.'

'); + } + } $r->print($upload_output); +# Rename, cut, copy or remove a single resource if (&handle_edit_cmd()) { my $contentchg; - if ($env{'form.cmd'} =~ /^(del|cut)_/) { + if ($env{'form.cmd'} =~ m{^(del|cut)_}) { $contentchg = 1; } ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container,$contentchg); return $errtext if ($fatal); } + +# Cut, copy and/or remove multiple resources + if ($env{'form.multichange'}) { + my %allchecked = ( + cut => {}, + remove => {}, + ); + my $needsupdate; + foreach my $which (keys(%allchecked)) { + $env{'form.multi'.$which} =~ s/,$//; + if ($env{'form.multi'.$which}) { + map { $allchecked{$which}{$_} = 1; } split(/,/,$env{'form.multi'.$which}); + if (ref($allchecked{$which}) eq 'HASH') { + $needsupdate += scalar(keys(%{$allchecked{$which}})); + } + } + } + if ($needsupdate) { + my $haschanges = 0; + my %curr_groups = &Apache::longroup::coursegroups(); + my $total = scalar(@LONCAPA::map::order) - 1; + for (my $i=$total; $i>=0; $i--) { + my $res = $LONCAPA::map::order[$i]; + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]); + $name=&LONCAPA::map::qtescape($name); + $url=&LONCAPA::map::qtescape($url); + next unless ($name && $url); + my %denied = + &action_restrictions($coursenum,$coursedom,$url, + $env{'form.folderpath'},\%curr_groups); + foreach my $which (keys(%allchecked)) { + next if ($denied{$which}); + next unless ($allchecked{$which}{$res}); + if ($which eq 'remove') { + if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) && + ($url!~/$LONCAPA::assess_page_seq_re/)) { + &Apache::lonnet::removeuploadedurl($url); + } else { + &LONCAPA::map::makezombie($res); + } + splice(@LONCAPA::map::order,$i,1); + $haschanges ++; + } elsif ($which eq 'cut') { + &LONCAPA::map::makezombie($res); + splice(@LONCAPA::map::order,$i,1); + $haschanges ++; + } + } + } + if ($haschanges) { + ($errtext,$fatal) = + &storemap($coursenum,$coursedom,$folder.'.'.$container,1); + return $errtext if ($fatal); + } + } + } + # Group import/search if ($env{'form.importdetail'}) { my @imports; @@ -2237,8 +2564,13 @@ sub editor { $r->print(''); } - my ($to_show,$output,@allidx,@allmapidx); - + my ($to_show,$output,@allidx,@allmapidx,%filters,%lists,%curr_groups); + %filters = ( + canremove => [], + cancut => [], + cancopy => [], + ); + %curr_groups = &Apache::longroup::coursegroups(); &Apache::loncommon::start_data_table_count(); #setup a row counter foreach my $res (@LONCAPA::map::order) { my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]); @@ -2252,12 +2584,14 @@ sub editor { } $output .= &entryline($idx,$name,$url,$folder,$allowed,$res, $coursenum,$coursedom,$crstype, - $pathitem,$supplementalflag,$container); + $pathitem,$supplementalflag,$container, + \%filters,\%curr_groups); $idx++; $shown++; } &Apache::loncommon::end_data_table_count(); + my $need_save; if (($allowed) || ($supplementalflag && $folder eq 'supplemental')) { my $toolslink = '' - .'' - .''; + .'' + .''; if ($folder !~ /^supplemental/) { $to_show .= ''; } $to_show .= &Apache::loncommon::end_data_table_header_row(); if ($folder !~ /^supplemental/) { - my $idxlist = join(',',@allidx); - my $mapidxlist = join(',',@allmapidx); + $lists{'canhide'} = join(',',@allidx); + $lists{'canrandomlyorder'} = join(',',@allmapidx); + foreach my $item ('canremove','cancut','cancopy') { + if (ref($filters{$item}) eq 'ARRAY') { + $lists{$item} = join(',',@{$filters{$item}}); + } + } if (@allidx > 0) { my $path; if ($env{'form.folderpath'}) { $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); } - $to_show .= - &Apache::loncommon::continue_data_table_row(). - ''. - ''. - &Apache::loncommon::end_data_table_row(); + if (@allidx > 1) { + $to_show .= + &Apache::loncommon::continue_data_table_row(). + ''. + ''. + ''. + ''. + ''. + &Apache::loncommon::end_data_table_row(); + $need_save = 1; + } } } $to_show .= $output.' ' @@ -2360,8 +2685,8 @@ sub editor { } if ($allowed) { my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container"; - $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath,$jumpto, - $readfile)); + $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath, + $jumpto,$readfile,$need_save,"$folder.$container")); &print_paste_buffer($r,$container,$folder,$coursedom,$coursenum); } else { $r->print($to_show); @@ -2369,6 +2694,67 @@ sub editor { return; } +sub multiple_check_form { + my ($caller,$listsref) = @_; + return unless (ref($listsref) eq 'HASH'); + my $output = + ''. + ''. + ''.(' 'x2).''. + '
' .&Apache::loncommon::help_open_menu('Navigation Screen', @@ -2275,50 +2609,41 @@ sub editor { .&Apache::loncommon::start_data_table(undef,'contentlist') .&Apache::loncommon::start_data_table_header_row() .''.&mt('Move').''.&mt('Actions').''.&mt('Document').''.&mt('Actions').''.&mt('Document').''.&mt('Settings').' '. - '
'. - ''.&mt('Select:').' '. - ''.(' 'x2).'
'. - ''. - - '
 '. + &multiple_check_form('actions',\%lists). + '  '. + &multiple_check_form('settings',\%lists). + '
'. + ''. + ''. + ''."\n". + ''. + '
'. + ''. + ''. + '
'. + ''. + '
'."\n"; + } else { + $output .= + ''. + ''. + ''."\n". + ''. + '
'. + ''. + ''. + ''. + ''. + ''. + '
'."\n"; + } + $output .= + ''. + ''; + if ($caller eq 'settings') { + $output .= + ''; + } elsif ($caller eq 'actions') { + $output .= + ''. + ''. + ''; + } + $output .= + ''. + ''; + return $output; +} + sub process_file_upload { my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd) = @_; # upload a file, if present @@ -2528,7 +2914,7 @@ sub is_supplemental_title { sub entryline { my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom, - $crstype,$pathitem,$supplementalflag,$container)=@_; + $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups)=@_; my ($foldertitle,$renametitle); if (&is_supplemental_title($title)) { ($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title); @@ -2544,7 +2930,7 @@ sub entryline { $renametitle=~s/\"\;/\\\"/g; $renametitle=~s/ /%20/g; my $line=&Apache::loncommon::start_data_table_row(); - my ($form_start,$form_end,$form_common); + my ($form_start,$form_end,$form_common,$form_param); # Edit commands my ($esc_path, $path, $symb); if ($env{'form.folderpath'}) { @@ -2568,8 +2954,25 @@ sub entryline { &Apache::lonnet::declutter($currurl)); } } - my ($renamelink,%lt); + my ($renamelink,%lt,$ishash); + if (ref($filtersref) eq 'HASH') { + $ishash = 1; + } + if ($allowed) { + $form_start = ' +
+'; + $form_common=(< + +END + $form_param=(< + +END + $form_end = ''; + my $incindex=$index+1; my $selectbox=''; if (($#LONCAPA::map::order>0) && @@ -2605,66 +3008,9 @@ sub entryline { 'ul' => 'URL', 'ti' => 'Title', ); - my $nocopy=0; - my $nocut=0; - my $noremove=0; - if ($url=~ m{^/res/.+\.(page|sequence)$}) { - # no copy for published maps - $nocopy=1; - } - if ($url=~/^\/res\/lib\/templates\//) { - $nocopy=1; - $nocut=1; - } - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - if ($url eq "/uploaded/$cdom/$cnum/group_allfolders.sequence") { - if ($env{'form.folderpath'} =~ /^default&[^\&]+$/) { - my %curr_groups = &Apache::longroup::coursegroups(); - if (keys(%curr_groups) > 0) { - $noremove=1; - } - $nocut=1; - $nocopy=1; - } - } elsif ($url =~ m{^\Q/uploaded/$cdom/$cnum/group_folder_\E(\w+)\.sequence$}) { - my $group = $1; - if ($env{'form.folderpath'} =~ /^default&[^\&]+\&group_allfolders\&[^\&]+$/) { - my %curr_group = &Apache::longroup::coursegroups($cdom,$cnum,$group); - if (keys(%curr_group) > 0) { - $noremove=1; - } - } - $nocut=1; - $nocopy=1; - } elsif ($url =~ m{^\Q/adm/$cdom/$cnum/\E(\w+)/smppg$}) { - my $group = $1; - if ($env{'form.folderpath'} =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&\Qgroup_folder_$group\E\&[^\&]+$/) { - my %curr_group = &Apache::longroup::coursegroups($cdom,$cnum,$group); - my %groupsettings = &Apache::longroup::get_group_settings($curr_group{$group}); - if (keys(%groupsettings) > 0) { - $noremove=1; - } - $nocut=1; - $nocopy=1; - } - } elsif ($env{'form.folderpath'} =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&group_folder_(\w+)\&/) { - my $group = $1; - my %curr_group = &Apache::longroup::coursegroups($cdom,$cnum,$group); - if ($url =~ /group_boards_\Q$group\E/) { - my %curr_group = &Apache::longroup::coursegroups($cdom,$cnum,$group); - my %groupsettings = &Apache::longroup::get_group_settings($curr_group{$group}); - if (keys(%groupsettings) > 0) { - if (ref($groupsettings{'functions'}) eq 'HASH') { - if ($groupsettings{'functions'}{'discussion'} eq 'on') { - $noremove=1; - } - } - } - $nocut=1; - $nocopy=1; - } - } + my %denied = &action_restrictions($coursenum,$coursedom,$url, + $env{'form.folderpath'}, + $currgroups); my ($copylink,$cutlink,$removelink); my $skip_confirm = 0; if ( $folder =~ /^supplemental/ @@ -2678,48 +3024,62 @@ sub entryline { $skip_confirm = 1; } - if ($nocopy) { + if ($denied{'copy'}) { $copylink=(<$lt{'cp'} ENDCOPY } else { + my $formname = 'edit_copy_'.$orderidx; + my $js = "javascript:checkForSubmit(document.forms.renameform,'copy','actions','$orderidx','$esc_path','$index','$renametitle',$skip_confirm,'$container','$folder');"; $copylink=(<$lt{'cp'} +
+$form_common +$lt{'cp'} +$form_end ENDCOPY + if (($ishash) && (ref($filtersref->{'cancopy'}) eq 'ARRAY')) { + push(@{$filtersref->{'cancopy'}},$orderidx); + } } - if ($nocut) { + if ($denied{'cut'}) { $cutlink=(<$lt{'ct'} ENDCUT } else { + my $formname = 'edit_cut_'.$orderidx; + my $js = "javascript:checkForSubmit(document.forms.renameform,'cut','actions','$orderidx','$esc_path','$index','$renametitle',$skip_confirm,'$container','$folder');"; $cutlink=(<$lt{'ct'} + +$form_common +$lt{'ct'} +$form_end ENDCUT + if (($ishash) && (ref($filtersref->{'cancut'}) eq 'ARRAY')) { + push(@{$filtersref->{'cancut'}},$orderidx); + } } - if ($noremove) { + if ($denied{'remove'}) { $removelink=(<$lt{'rm'} ENDREM } else { + my $formname = 'edit_remove_'.$orderidx; + my $js = "javascript:checkForSubmit(document.forms.renameform,'remove','actions','$orderidx','$esc_path','$index','$renametitle',$skip_confirm);"; $removelink=(<$lt{'rm'} + +$form_common +$lt{'rm'} +$form_end ENDREM + if (($ishash) && (ref($filtersref->{'canremove'}) eq 'ARRAY')) { + push(@{$filtersref->{'canremove'}},$orderidx); + } } unless ($isexternal) { $renamelink=(<$lt{'rn'} ENDREN } - $form_start = ' - -'; - $form_common=(< - - - -END - $form_end = ''; $line.=(<
@@ -2735,6 +3095,7 @@ END $form_start + $form_param $form_common $selectbox $form_end @@ -2746,7 +3107,6 @@ $copylink END - } # Figure out what kind of a resource this is my ($extension)=($url=~/\.(\w+)$/); @@ -2835,6 +3195,7 @@ END my $formname = 'edit_randompick_'.$orderidx; $rand_pick_text = '
'."\n". +$form_param."\n". $form_common."\n". ''; if ($rpicknum ne '') { @@ -2847,8 +3208,9 @@ $form_common."\n". my $formname = 'edit_rorder_'.$orderidx; $rand_order_text = ''."\n". +$form_param."\n". $form_common."\n". -''. +''. $form_end; } } elsif ($supplementalflag && !$allowed) { @@ -2928,13 +3290,15 @@ $form_end; $line.=(< + $form_param $form_common - + $form_end
+ $form_param $form_common - + $form_end $rand_pick_text
@@ -2945,10 +3309,75 @@ ENDPARMS return $line; } +sub action_restrictions { + my ($cnum,$cdom,$url,$folderpath,$currgroups) = @_; + my %denied = ( + cut => 0, + copy => 0, + remove => 0, + ); + if ($url=~ m{^/res/.+\.(page|sequence)$}) { + # no copy for published maps + $denied{'copy'} = 1; + } elsif ($url=~m{^/res/lib/templates/}) { + $denied{'copy'} = 1; + $denied{'cut'} = 1; + } elsif ($url eq "/uploaded/$cdom/$cnum/group_allfolders.sequence") { + if ($folderpath =~ /^default&[^\&]+$/) { + if ((ref($currgroups) eq 'HASH') && (keys(%{$currgroups}) > 0)) { + $denied{'remove'} = 1; + } + $denied{'cut'} = 1; + $denied{'copy'} = 1; + } + } elsif ($url =~ m{^\Q/uploaded/$cdom/$cnum/group_folder_\E(\w+)\.sequence$}) { + my $group = $1; + if ($folderpath =~ /^default&[^\&]+\&group_allfolders\&[^\&]+$/) { + if ((ref($currgroups) eq 'HASH') && (exists($currgroups->{$group}))) { + $denied{'remove'} = 1; + } + } + $denied{'cut'} = 1; + $denied{'copy'} = 1; + } elsif ($url =~ m{^\Q/adm/$cdom/$cnum/\E(\w+)/smppg$}) { + my $group = $1; + if ($folderpath =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&\Qgroup_folder_$group\E\&[^\&]+$/) { + if ((ref($currgroups) eq 'HASH') && (exists($currgroups->{$group}))) { + my %groupsettings = &Apache::longroup::get_group_settings($currgroups->{$group}); + if (keys(%groupsettings) > 0) { + $denied{'remove'} = 1; + } + $denied{'cut'} = 1; + $denied{'copy'} = 1; + } + } + } elsif ($folderpath =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&group_folder_(\w+)\&/) { + my $group = $1; + if ($url =~ /group_boards_\Q$group\E/) { + if ((ref($currgroups) eq 'HASH') && (exists($currgroups->{$group}))) { + my %groupsettings = &Apache::longroup::get_group_settings($currgroups->{$group}); + if (keys(%groupsettings) > 0) { + if (ref($groupsettings{'functions'}) eq 'HASH') { + if ($groupsettings{'functions'}{'discussion'} eq 'on') { + $denied{'remove'} = 1; + } + } + } + $denied{'cut'} = 1; + $denied{'copy'} = 1; + } + } + } + return %denied; +} + sub new_timebased_suffix { - my ($coursedom,$coursenum,$type,$area,$container) = @_; + my ($dom,$num,$type,$area,$container) = @_; my ($prefix,$namespace,$idtype,$errtext,$locknotfreed); - if ($type eq 'map') { + if ($type eq 'paste') { + $prefix = $type; + $namespace = 'courseeditor'; + } elsif ($type eq 'map') { $prefix = 'docs'; if ($area eq 'supplemental') { $prefix = 'supp'; @@ -2961,10 +3390,11 @@ sub new_timebased_suffix { } $idtype = 'concat'; my ($suffix,$freedlock,$error) = - &Apache::lonnet::get_timebased_id($prefix,'num',$namespace, - $coursedom,$coursenum); + &Apache::lonnet::get_timebased_id($prefix,'num',$namespace,$dom,$num); if (!$suffix) { - if ($type eq 'map') { + if ($type eq 'paste') { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix when adding to the paste buffer.'); + } elsif ($type eq 'map') { $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.'); } elsif ($type eq 'smppg') { $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new simple page.'); @@ -2979,7 +3409,9 @@ sub new_timebased_suffix { $locknotfreed = '
'. &mt('There was a problem removing a lockfile.').' '; - if ($type eq 'map') { + if ($type eq 'paste') { + &mt('This will prevent use of the paste buffer until th next log-in.'); + } elsif ($type eq 'map') { &mt('This will prevent creation of additional folders or composite pages in this course.'); } elsif ($type eq 'smppg') { $locknotfreed .= @@ -2988,9 +3420,11 @@ sub new_timebased_suffix { $locknotfreed .= &mt('This will prevent creation of additional bulletin boards in this course.'); } - $locknotfreed .= - ' '.&mt('Please contact the domain coordinator for your LON-CAPA domain.'). - '
'; + unless ($type eq 'paste') { + $locknotfreed .= + ' '.&mt('Please contact the domain coordinator for your LON-CAPA domain.'); + } + $locknotfreed .= '
'; } return ($suffix,$errtext,$locknotfreed); } @@ -3654,7 +4088,7 @@ sub handler { # supplementalflag=0: show standard documents # toolsflag=1: show utilities - + $env{'form.folderpath'} = &unescape($env{'form.folderpath'}); my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); if (($env{'form.folderpath'}=~/^default/) || ($env{'form.folderpath'} eq "")) { $supplementalflag=0; @@ -3688,12 +4122,11 @@ sub handler { } } elsif ($env{'form.command'} eq 'editdocs') { $env{'form.folderpath'} = 'default&'. - &Apache::lonhtmlcommon::entity_encode('Main Course Content'). - ':::::'; + &escape(&mt('Main '.$crstype.' Content').':::::'); &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => $env{'form.command'}}); } elsif ($env{'form.command'} eq 'editsupp') { $env{'form.folderpath'} = 'supplemental&'. - &Apache::lonhtmlcommon::entity_encode('Supplemental Content'); + &escape('Supplemental Content'); &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/supplemental'}); } elsif ($env{'form.command'} eq 'contents') { &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/navmaps'}); @@ -3734,8 +4167,8 @@ sub handler { if ($supplementalflag) { $env{'form.folderpath'}=&supplemental_base(); } else { - $env{'form.folderpath'}='default'.&escape(&mt('Main '.$crstype.' Documents')). - ':::::'; + $env{'form.folderpath'}='default'.&escape(&mt('Main '.$crstype.' Content'). + ':::::'); } } @@ -3760,8 +4193,7 @@ sub handler { if ($env{'form.folder'} eq '' || $env{'form.folder'} eq 'supplemental') { $folderpath='default&'. - &escape(&mt('Main '.$crstype.' Documents')). - ':::::'; + &escape(&mt('Main '.$crstype.' Content').':::::'); } } $containertag = ''; @@ -3818,9 +4250,7 @@ sub handler { onload => "javascript:resize_scrollbox('contentscroll','1','1');", }; } - if ($env{'docs.markedcopy_url'}) { - $script .= &paste_popup_js(); - } + $script .= &paste_popup_js(); my $confirm_switch = &mt("Editing requires switching to the resource's home server.").'\n'. &mt('Switch server?'); @@ -3846,7 +4276,6 @@ sub handler { } else { &Apache::lonhtmlcommon::add_breadcrumb({ href=>"/adm/coursedocs",text=>"$crstype Contents"}); - $r->print(&Apache::loncommon::start_page("$crstype Contents", $script, {'add_entries' => $addentries} ) @@ -4047,7 +4476,10 @@ SEDFFORM if ($folder eq '') { $folder='default'; } - &update_paste_buffer($coursenum,$coursedom,$folder); + my $output = &update_paste_buffer($coursenum,$coursedom,$folder); + if ($output) { + $r->print($output); + } $r->print(< @@ -4660,7 +5092,7 @@ sub generate_admin_menu { foreach my $aurole (keys(%outhash)) { unless(grep(/^\Q$outhash{$aurole}\E/,@hosts)) { push(@hosts,$outhash{$aurole}); - } + } } if (@hosts == 1) { my $switchto = '/adm/switchserver?otherserver='.$hosts[0]. @@ -4724,7 +5156,8 @@ sub generate_admin_menu { } sub generate_edit_table { - my ($tid,$orderhash_ref,$to_show,$iconpath,$jumpto,$readfile) = @_; + my ($tid,$orderhash_ref,$to_show,$iconpath,$jumpto,$readfile, + $need_save,$copyfolder) = @_; return unless(ref($orderhash_ref) eq 'HASH'); my %orderhash = %{$orderhash_ref}; my $form; @@ -4773,7 +5206,35 @@ sub generate_edit_table { $form .= '
'."\n"; if ($to_show ne '') { - $form .= '
'.$to_show.'
'."\n"; + my $saveform; + if ($need_save) { + my $button = &mt('Make changes'); + my $path; + if ($env{'form.folderpath'}) { + $path = + &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + } + $saveform = <<"END"; + +END + } + $form .= '
'.$to_show.'
'.$saveform."\n"; } foreach my $field (keys(%orderhash)){ if($field ne '00'){ @@ -4823,6 +5284,8 @@ sub editing_js { imscms => 'You must select which Course Management System was the source of the IMS package', invurl => 'Invalid URL', titbl => 'Title is blank', + more => '(More ...)', + less => '(Less ...)', ); my $crstype = &Apache::loncommon::course_type(); @@ -4831,7 +5294,8 @@ sub editing_js { if (&HTML::Entities::decode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.folderpath'}) =~ /\:1$/) { $main_container_page = 1; } - my $toplevelmain = 'default&Main%20'.$crstype.'%20Documents%3A%3A%3A%3A%3A'; + my $toplevelmain = + &escape(&mt('Main '.$crstype.' Content').':::::'); my $toplevelsupp = &supplemental_base(); my $backtourl; @@ -5006,7 +5470,7 @@ function makeims(imsform) { function changename(folderpath,index,oldtitle) { var title=prompt('$lt{"p_chn"}',oldtitle); if (title) { -this.document.forms.renameform.markcopy.value=-1; +this.document.forms.renameform.markcopy.value=''; this.document.forms.renameform.title.value=title; this.document.forms.renameform.cmd.value='rename_'+index; this.document.forms.renameform.folderpath.value=folderpath; @@ -5014,32 +5478,6 @@ this.document.forms.renameform.submit(); } } -function removeres(folderpath,index,oldtitle,skip_confirm) { -if (skip_confirm || confirm('$lt{"p_rmr1"}\\n\\n$lt{"p_rmr2a"} "'+oldtitle+'" $lt{"p_rmr2b"}')) { -this.document.forms.renameform.markcopy.value=-1; -this.document.forms.renameform.cmd.value='del_'+index; -this.document.forms.renameform.folderpath.value=folderpath; -this.document.forms.renameform.submit(); -} -} - -function cutres(folderpath,index,oldtitle,container,folder,skip_confirm) { -if (skip_confirm || confirm('$lt{"p_ctr1a"}\\n$lt{"p_ctr1b"}\\n\\n$lt{"p_ctr2a"} "'+oldtitle+'" $lt{"p_ctr2b"}')) { -this.document.forms.renameform.cmd.value='cut_'+index; -this.document.forms.renameform.markcopy.value=index; -this.document.forms.renameform.copyfolder.value=folder+'.'+container; -this.document.forms.renameform.folderpath.value=folderpath; -this.document.forms.renameform.submit(); -} -} - -function markcopy(folderpath,index,oldtitle,container,folder) { -this.document.forms.renameform.markcopy.value=index; -this.document.forms.renameform.copyfolder.value=folder+'.'+container; -this.document.forms.renameform.folderpath.value=folderpath; -this.document.forms.renameform.submit(); -} - function updatePick(targetform,index,caller) { var pickitem; var picknumitem; @@ -5064,7 +5502,7 @@ function updatePick(targetform,index,cal propagateState(targetform,'rpicknum'); } } else { - checkForSubmit(targetform,'randompick'); + checkForSubmit(targetform,'randompick','settings'); } } } else { @@ -5073,13 +5511,13 @@ function updatePick(targetform,index,cal if (regexdigit.test(picknum)) { picknumitem.value = picknum; if (index == 'all') { - picknumtext.innerHTML = ' '+picknum+''; + picknumtext.innerHTML = ' '+picknum+''; if (caller == 'link') { propagateState(targetform,'rpicknum'); } } else { picknumtext.innerHTML = ' '+picknum+''; - checkForSubmit(targetform,'randompick'); + checkForSubmit(targetform,'randompick','settings'); } } else { if (caller == 'check') { @@ -5090,7 +5528,7 @@ function updatePick(targetform,index,cal } } else { pickitem.checked=false; - checkForSubmit(targetform,'randompick'); + checkForSubmit(targetform,'randompick','settings'); } } return; @@ -5104,7 +5542,7 @@ function updatePick(targetform,index,cal propagateState(targetform,'rpicknum'); } } else { - checkForSubmit(targetform,'randompick'); + checkForSubmit(targetform,'randompick','settings'); } } } @@ -5126,64 +5564,160 @@ function propagateState(form,param) { setcheck = 1; } } + var allidxlist; + if ((param == 'remove') || (param == 'cut') || (param == 'copy')) { + if (document.getElementById('all'+param+'idx')) { + allidxlist = document.getElementById('all'+param+'idx').value; + } + var actions = new Array ('remove','cut','copy'); + for (var i=0; i 1) { - for (var i=0; i 1) { + for (var i=0; i 0) { + document.getElementById('randompicknum_'+allidxs[i]).innerHTML = ': '+rpick+''; + } else { + document.getElementById('randompicknum_'+allidxs[i]).innerHTML = ''; + } + } + } + } else { if (setcheck == 1) { document.getElementById(param+'_'+allidxs[i]).checked = true; } else { document.getElementById(param+'_'+allidxs[i]).checked = false; + if (param == 'randompick') { + document.getElementById('randompicknum_'+allidxs[i]).innerHTML = ''; + } } } } } - } - } else { - var allmapidxlist = form.allmapidx.value; - if (allmapidxlist != '') { - var allmapidxs = allmapidxlist.split(','); - if (allmapidxs.length > 1) { - for (var i=0; i 0) { - document.getElementById('randompicknum_'+allmapidxs[i]).innerHTML = ': '+rpick+''; - } else { - document.getElementById('randompicknum_'+allmapidxs[i]).innerHTML = ''; + if (setcheck == 1) { + if ((param == 'remove') || (param == 'cut') || (param == 'copy')) { + var actions = new Array('copy','cut','remove'); + for (var i=0; i 1) { + for (var j=0; j 1) { - for (var i=0; i$lt{'more'}'; + } else { + document.getElementById('more'+caller).innerHTML = ''; + } + if (caller == 'actions') { + setClass(value); + setBoxes(value); + } + } + var showButton = multiSettings(); + if (showButton != 1) { + showButton = multiActions(); + } + if (document.getElementById('multisave')) { + if (showButton == 1) { + document.getElementById('multisave').style.display='block'; + } else { + document.getElementById('multisave').style.display='none'; + } + } + resize_scrollbox('contentscroll','1','1'); + return; +} + +function toggleCheckUncheck(caller,more) { + if (more == 1) { + document.getElementById('more'+caller).innerHTML = '  $lt{'less'}'; + document.getElementById('allfields'+caller).style.display='block'; + } else { + document.getElementById('more'+caller).innerHTML = '  $lt{'more'}'; + document.getElementById('allfields'+caller).style.display='none'; + } + resize_scrollbox('contentscroll','1','1'); +} + +function multiSettings() { + var inuse = 0; + var settingsform = document.togglemultsettings; + if (settingsform.showmultpick.length > 1) { + for (var i=0; i 1) { + for (var i=0; i 0) { + form.multichange.value = numchanges; + } } - var allmapidxlist = form.allmapidx.value; - form.allrandompick.value = ''; - form.allrandomorder.value = ''; - if (allmapidxlist != '') { - var allmapidxs = allmapidxlist.split(','); - for (var i=0; i 1) { + for (var i=0; i 0) || (dosettings == 1)) { + form.submit(); + return true; + } + return false; +} + +function setClass(value) { + var cutclass = 'LC_docs_cut'; + var copyclass = 'LC_docs_copy'; + var removeclass = 'LC_docs_remove'; + var cutreg = new RegExp("\\\\b"+cutclass+"\\\\b"); + var copyreg = new RegExp("\\\\b"+copyclass+"\\\\b"); + var removereg = new RegExp("\\\\"+removeclass+"\\\\b"); + var links = document.getElementsByTagName('a'); + for (var i=0; i