--- loncom/interface/londocs.pm	2023/03/23 16:45:50	1.696
+++ loncom/interface/londocs.pm	2023/07/11 12:44:18	1.700
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Documents
 #
-# $Id: londocs.pm,v 1.696 2023/03/23 16:45:50 raeburn Exp $
+# $Id: londocs.pm,v 1.700 2023/07/11 12:44:18 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -45,7 +45,6 @@ use Apache::lontemplate();
 use Apache::lonsimplepage();
 use Apache::lonhomework();
 use Apache::lonpublisher();
-use Apache::lonparmset();
 use Apache::loncourserespicker();
 use HTML::Entities;
 use HTML::TokeParser;
@@ -719,7 +718,7 @@ sub group_import {
                 $url = $1;
                 my $marker = $2;
                 my $info = $3;
-                my ($toolid,%toolhash,%toolsettings);
+                my ($toolid,$toolprefix,$tooltype,%toolhash,%toolsettings);
                 my @extras = ('linktext','explanation','crslabel','crstitle','crsappend');
                 my @toolinfo = split(/:/,$info);
                 if ($residx) {
@@ -728,6 +727,12 @@ sub group_import {
                 } else {
                     $toolid = shift(@toolinfo);
                 }
+                if ($toolid =~ /^c/) {
+                    $tooltype = 'crs';
+                    $toolprefix = 'c';
+                } else {
+                    $tooltype = 'dom';
+                }
                 $toolid =~ s/\D//g;
                 ($toolhash{'target'},$toolhash{'width'},$toolhash{'height'},
                  $toolhash{'linktext'},$toolhash{'explanation'},$toolhash{'crslabel'},
@@ -741,127 +746,130 @@ sub group_import {
                     $toolhash{'gradable'} =~ s/\D+//g;
                 }
                 if (ref($ltitoolsref) eq 'HASH') {
-                    if (ref($ltitoolsref->{$toolid}) eq 'HASH') {
-                        my @deleted;
-                        $toolhash{'id'} = $toolid;
-                        if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'tab') ||
-                            ($toolhash{'target'} eq 'window')) {
-                            if ($toolhash{'target'} eq 'window') {
-                                foreach my $item ('width','height') {
-                                    $toolhash{$item} =~ s/^\s+//;
-                                    $toolhash{$item} =~ s/\s+$//;
-                                    if ($toolhash{$item} =~ /\D/) {
-                                        delete($toolhash{$item});
-                                        if ($residx) {
-                                            if ($toolsettings{$item}) {
-                                                push(@deleted,$item);
+                    if (ref($ltitoolsref->{$tooltype}) eq 'HASH') {
+                        if (ref($ltitoolsref->{$tooltype}->{$toolid}) eq 'HASH') {
+                            my %tools = %{$ltitoolsref->{$tooltype}->{$toolid}};
+                            my @deleted;
+                            $toolhash{'id'} = $toolprefix.$toolid;
+                            if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'tab') ||
+                                ($toolhash{'target'} eq 'window')) {
+                                if ($toolhash{'target'} eq 'window') {
+                                    foreach my $item ('width','height') {
+                                        $toolhash{$item} =~ s/^\s+//;
+                                        $toolhash{$item} =~ s/\s+$//;
+                                        if ($toolhash{$item} =~ /\D/) {
+                                            delete($toolhash{$item});
+                                            if ($residx) {
+                                                if ($toolsettings{$item}) {
+                                                    push(@deleted,$item);
+                                                }
                                             }
                                         }
                                     }
                                 }
-                            }
-                        } elsif ($residx) {
-                            $toolhash{'target'} = $toolsettings{'target'};
-                            if ($toolhash{'target'} eq 'window') {
-                                foreach my $item ('width','height') {
-                                    $toolhash{$item} = $toolsettings{$item};
+                            } elsif ($residx) {
+                                $toolhash{'target'} = $toolsettings{'target'};
+                                if ($toolhash{'target'} eq 'window') {
+                                    foreach my $item ('width','height') {
+                                        $toolhash{$item} = $toolsettings{$item};
+                                    }
+                                }
+                            } elsif (ref($tools{'display'}) eq 'HASH') {
+                                $toolhash{'target'} = $tools{'display'}{'target'};
+                                if ($toolhash{'target'} eq 'window') {
+                                    $toolhash{'width'} = $tools{'display'}{'width'};
+                                    $toolhash{'height'} = $tools{'display'}{'height'};
                                 }
                             }
-                        } elsif (ref($ltitoolsref->{$toolid}->{'display'}) eq 'HASH') {
-                            $toolhash{'target'} = $ltitoolsref->{$toolid}->{'display'}->{'target'};
-                            if ($toolhash{'target'} eq 'window') {
-                                $toolhash{'width'} = $ltitoolsref->{$toolid}->{'display'}->{'width'};
-                                $toolhash{'height'} = $ltitoolsref->{$toolid}->{'display'}->{'height'};
-                            }
-                        }
-                        if ($toolhash{'target'} eq 'iframe') {
-                            foreach my $item ('width','height','linktext','explanation') {
-                                delete($toolhash{$item});
-                                if ($residx) {
-                                    if ($toolsettings{$item}) {
-                                        push(@deleted,$item);
+                            if ($toolhash{'target'} eq 'iframe') {
+                                foreach my $item ('width','height','linktext','explanation') {
+                                    delete($toolhash{$item});
+                                    if ($residx) {
+                                        if ($toolsettings{$item}) {
+                                            push(@deleted,$item);
+                                        }
                                     }
                                 }
-                            }
-                        } elsif ($toolhash{'target'} eq 'tab') {
-                            foreach my $item ('width','height') {
-                                delete($toolhash{$item});
-                                if ($residx) {
-                                    if ($toolsettings{$item}) {
-                                        push(@deleted,$item);
+                            } elsif ($toolhash{'target'} eq 'tab') {
+                                foreach my $item ('width','height') {
+                                    delete($toolhash{$item});
+                                    if ($residx) {
+                                        if ($toolsettings{$item}) {
+                                            push(@deleted,$item);
+                                        }
                                     }
                                 }
                             }
-                        }
-                        if (ref($ltitoolsref->{$toolid}->{'crsconf'}) eq 'HASH') {
-                            foreach my $item ('label','title','linktext','explanation') {
-                                my $crsitem;
-                                if (($item eq 'label') || ($item eq 'title')) {
-                                    $crsitem = 'crs'.$item;
-                                } else {
-                                    $crsitem = $item;
-                                }
-                                if ($ltitoolsref->{$toolid}->{'crsconf'}->{$item}) {
-                                    $toolhash{$crsitem} =~ s/^\s+//;
-                                    $toolhash{$crsitem} =~ s/\s+$//;
-                                    if ($toolhash{$crsitem} eq '') {
+                            if (ref($tools{'crsconf'}) eq 'HASH') {
+                                foreach my $item ('label','title','linktext','explanation') {
+                                    my $crsitem;
+                                    if (($item eq 'label') || ($item eq 'title')) {
+                                        $crsitem = 'crs'.$item;
+                                    } else {
+                                        $crsitem = $item;
+                                    }
+                                    if ($tools{'crsconf'}{$item}) {
+                                        $toolhash{$crsitem} =~ s/^\s+//;
+                                        $toolhash{$crsitem} =~ s/\s+$//;
+                                        if ($toolhash{$crsitem} eq '') {
+                                            delete($toolhash{$crsitem});
+                                        }
+                                    } else {
                                         delete($toolhash{$crsitem});
                                     }
-                                } else {
-                                    delete($toolhash{$crsitem});
-                                }
-                                if (($residx) && (exists($toolsettings{$crsitem}))) {
-                                    unless (exists($toolhash{$crsitem})) {
-                                        push(@deleted,$crsitem);
+                                    if (($residx) && (exists($toolsettings{$crsitem}))) {
+                                        unless (exists($toolhash{$crsitem})) {
+                                            push(@deleted,$crsitem);
+                                        }
                                     }
                                 }
                             }
-                        }
-                        if ($toolhash{'passback'}) {
-                            my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
-                            $toolhash{'gradesecret'} = $gradesecret;
-                            $toolhash{'gradesecretdate'} = time;
-                        }
-                        if ($toolhash{'roster'}) {
-                            my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
-                            $toolhash{'rostersecret'} = $rostersecret;
-                            $toolhash{'rostersecretdate'} = time;
-                        }
-                        my $changegradable;
-                        if (($residx) && ($folder =~ /^default/)) {
-                            if ($toolsettings{'gradable'}) {
-                                unless (($toolhash{'gradable'}) || (defined($LONCAPA::map::zombies[$residx]))) {
-                                    push(@deleted,'gradable');
-                                    $changegradable = 1;
-                                }
-                            } elsif ($toolhash{'gradable'}) {
-                                $changegradable = 1;
+                            if ($toolhash{'passback'}) {
+                                my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
+                                $toolhash{'gradesecret'} = $gradesecret;
+                                $toolhash{'gradesecretdate'} = time;
+                            }
+                            if ($toolhash{'roster'}) {
+                                my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
+                                $toolhash{'rostersecret'} = $rostersecret;
+                                $toolhash{'rostersecretdate'} = time;
                             }
-                            if (($caller eq 'londocs') && (defined($LONCAPA::map::zombies[$residx]))) {
-                                $changegradable = 1;
+                            my $changegradable;
+                            if (($residx) && ($folder =~ /^default/)) {
                                 if ($toolsettings{'gradable'}) {
-                                    $toolhash{'gradable'} = 1;
+                                    unless (($toolhash{'gradable'}) || (defined($LONCAPA::map::zombies[$residx]))) {
+                                        push(@deleted,'gradable');
+                                        $changegradable = 1;
+                                    }
+                                } elsif ($toolhash{'gradable'}) {
+                                    $changegradable = 1;
+                                }
+                                if (($caller eq 'londocs') && (defined($LONCAPA::map::zombies[$residx]))) {
+                                    $changegradable = 1;
+                                    if ($toolsettings{'gradable'}) {
+                                        $toolhash{'gradable'} = 1;
+                                    }
                                 }
                             }
-                        }
-                        my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum);
-                        if ($putres eq 'ok') {
-                            if (@deleted) {
-                                &Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum);
-                            }
-                            if (($changegradable) && ($folder =~ /^default/)) {
-                                my $val;
-                                if ($toolhash{'gradable'}) {
-                                    $val = 'yes';
-                                } else {
-                                    $val = 'no';
+                            my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum);
+                            if ($putres eq 'ok') {
+                                if (@deleted) {
+                                    &Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum);
                                 }
-                                &LONCAPA::map::storeparameter($residx,'parameter_0_gradable',$val,
-                                                              'string_yesno');
-                                &remember_parms($residx,'gradable','set',$val);
+                                if (($changegradable) && ($folder =~ /^default/)) {
+                                    my $val;
+                                    if ($toolhash{'gradable'}) {
+                                        $val = 'yes';
+                                    } else {
+                                        $val = 'no';
+                                    }
+                                    &LONCAPA::map::storeparameter($residx,'parameter_0_gradable',$val,
+                                                                  'string_yesno');
+                                    &remember_parms($residx,'gradable','set',$val);
+                                }
+                            } else {
+                                return (&mt('Failed to save update to external tool.'),1);
                             }
-                        } else {
-                            return (&mt('Failed to save update to external tool.'),1);
                         }
                     }
                 }
@@ -2648,7 +2656,7 @@ sub url_paste_fixups {
                     if ($is_exttool) {
                         $exttoolchg = 1;
                     }
-                } elsif (($rem =~ m{\d+/ext\.tool$}) &&
+                } elsif (($is_exttool) &&
                          ($env{'form.docs.markedcopy_options'} ne 'move')) {
                     $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;
                     $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom;
@@ -3745,7 +3753,7 @@ sub multiple_check_form {
     return unless (ref($listsref) eq 'HASH');
     my $disabled;
     unless ($canedit) {
-        $disabled = 'disabled="disabled"'; 
+        $disabled = ' disabled="disabled"';
     }
     my $output =
     '<form action="/adm/coursedocs" method="post" name="togglemult'.$caller.'">'.
@@ -3783,7 +3791,7 @@ sub multiple_check_form {
             '</label></span></td>'."\n".
             '<td class="LC_docs_entry_parameter">'.
             '<span class="LC_nobreak LC_docs_copy">'.
-            '<label><input type="checkbox" name="copyall" id="copyall" onclick="propagateState(this.form,'."'copy'".')"'. $disabled.' />'.&mt('Copy').
+            '<label><input type="checkbox" name="copyall" id="copyall" onclick="propagateState(this.form,'."'copy'".')"'.$disabled.' />'.&mt('Copy').
             '</label></span></td>'.
             '</tr></table>'."\n";
     }
@@ -5725,6 +5733,7 @@ sub handler {
     my $containertag;
     my $pathitem;
     my %ltitools;
+    my $posslti;
     my $hiddentop;
     my $navmap;
     my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) };
@@ -5958,8 +5967,19 @@ sub handler {
                 }
             }
             my $tabidstr = join("','",@tabids);
-            %ltitools = &Apache::lonnet::get_domain_lti($coursedom,'consumer');
-            my $posslti = keys(%ltitools);
+            my (%domtools,%crstools);
+            my %tooltypes = &Apache::loncommon::usable_exttools();
+            if ($tooltypes{'dom'}) {
+                %domtools = &Apache::lonnet::get_domain_lti($coursedom,'consumer');
+            }
+            if ($tooltypes{'crs'}) {
+                %crstools = &Apache::lonnet::get_course_lti($coursenum,$coursedom,'consumer');
+            }
+            %ltitools = (
+                          dom => \%domtools,
+                          crs => \%crstools,
+                        );
+            $posslti = scalar(keys(%domtools)) + scalar(keys(%crstools));
             my $hostname = $r->hostname();
 	    $script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti,
                                    $londocroot,$canedit,$hostname,\$navmap).
@@ -6163,6 +6183,7 @@ sub handler {
                 'dire' => 'Directory:',
                 'cate' => 'Category:',
                 'tmpl' => 'Template:',
+                'empd' => 'No resources found',
                 'comment' => 'Comment',
                 'parse' => 'Upload embedded images/multimedia files if HTML file',
                 'bb5'      => 'Blackboard 5',
@@ -6311,13 +6332,20 @@ SEDFFORM
         <form action="/adm/coursedocs" method="post" name="crsresimportform" onsubmit="return validImportCrsRes();">
         <fieldset id="importcrsresform" style="display: none;">
         <legend>$lt{'imcr'}</legend>
+        <div id="importcrsrescontent" style="display: none;">
         <input type="hidden" name="active" value="bb" />
         $pickfile
         <p>
-        $lt{'title'}: <input type="textbox" name="crsrestitle" value="" $disabled />
+        $lt{'title'}: <input type="text" name="crsrestitle" value="" $disabled />
         </p>
         <input type="hidden" name="importdetail" value="" />
         <input type="submit" name="crsres" value="$lt{'impo'}" $disabled /><br />
+        </div>
+        <div id="importcrsresempty" style="display: none;">
+        <p>
+        $lt{'empd'}
+        </p>
+        </div>
         </fieldset>
         </form>
 CRSFORM
@@ -6652,6 +6680,7 @@ NWEBFORM
         <label><input type="radio" name="newsubdir" value="1" onclick="toggleNewsubdir(this.form);" $disabled />Yes</label>
         </span><span id="newsubdir"></span>
         <input type="hidden" name="newsubdirname" id="newsubdirname" value="" autocomplete="off" />
+        </div>
         </p>
         $lt{'fnam'}
         <input type="text" size="20" name="newresourcename" autocomplete="off" $disabled />
@@ -6762,7 +6791,7 @@ NGFFORM
         my @external = (
         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="toggleExternal(\'ext\');" />'=>$extresourcesform}
         );
-        if (keys(%ltitools)) {
+        if ($posslti) {
             push(@external,
                  {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/exttool.png" alt="'.$lt{extt}.'" onclick="toggleExternal(\'tool\');" />'=>$exttoolform},
             );
@@ -6866,6 +6895,7 @@ unless ($container eq 'page') {
 	$pathitem
 	<input type="hidden" name="cmd" value="upload_supplemental" />
         <input type='submit' value="$lt{'upld'}" />
+        </fieldset>
         </form>
 SUPDOCFORM
 
@@ -6945,7 +6975,7 @@ my @specialdocs = (
         my @supexternal = (
             {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="javascript:toggleExternal(\'suppext\')" />'
              =>$supextform});
-        if (keys(%ltitools)) {
+        if ($posslti) {
             push(@supexternal,
                  {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/exttool.png" alt="'.$lt{extt}.'" onclick="javascript:toggleExternal(\'supptool\')" />'
             =>$supexttoolform});
@@ -7963,7 +7993,22 @@ function toggleImportCrsres(caller) {
             var curr = document.getElementById('importcrsresform').style.display;
             if (curr == 'none') {
                 disp='block';
-                populateCrsSelects(document.crsresimportform,'coursepath','coursefile',1,'',1,0,1,1);
+                populateCrsSelects(document.crsresimportform,'coursepath','coursefile',1,'',1,0,1,1,0);
+                if ((document.getElementById('importcrsrescontent')) &&
+                    (document.getElementById('importcrsresempty'))) {
+                    var selelem = document.crsresimportform.elements['coursepath'];
+                    var numdirs = 0;
+                    if (selelem.options.length) {
+                        numdirs = selelem.options.length - 1;
+                    }
+                    if (numdirs) {
+                        document.getElementById('importcrsrescontent').style.display='block';
+                        document.getElementById('importcrsresempty').style.display='none';
+                    } else {
+                        document.getElementById('importcrsrescontent').style.display='none';
+                        document.getElementById('importcrsresempty').style.display='block';
+                    }
+                }
             }
         }
         document.getElementById('importcrsresform').style.display=disp;
@@ -8027,7 +8072,7 @@ function populateDirSelects(form,locsel,
             }
             var http = new XMLHttpRequest();
             var url = "/adm/courseauthor";
-            var params = "role="+role+"&rec="+recurse+"&nonempty="+nonemptydir;
+            var params = "role="+role+"&rec="+recurse+"&nonempty="+nonemptydir+"&addtop=1";
             http.open("POST", url, true);
             http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
             http.onreadystatechange = function() {
@@ -8046,6 +8091,9 @@ function populateDirSelects(form,locsel,
                                 selelem.options[selelem.options.length] = new Option(data.dirs[j],data.dirs[j]);
                             }
                             selelem.selectedIndex = 0;
+                            if (len == 1) {
+                                toggleCrsResTitle();
+                            }
                         }
                     }
                 }