Diff for /rat/lonratedt.pm between versions 1.12 and 1.51

version 1.12, 2002/05/13 15:36:05 version 1.51, 2004/01/02 21:00:56
Line 32 Line 32
   
 package Apache::lonratedt;  package Apache::lonratedt;
   
   =pod
   
   =head1 NAME
   
   Apache::lonratedt: advanced resource assembly tool
   
   =head1 SYNOPSIS
   
   lonratedt provides the routines and the handler for the Advanced
       Resource Assembly Tool (RAT), and ties the various pieces together
       with Javascript.
   
   =head1 OVERVIEW
   
   =head2 Map Representation
   
   =begin latex
   
   %
   \begin{figure}
   \begin{center}\includegraphics[%
     width=0.55\paperwidth,bb = 0 0 200 100, draft, type=eps]{Map_Example}\end{center}
   
   
   \caption{\label{Map_In_Advanced_Editor}Example of a Map in the Advanced Editor}
   \end{figure}
   %
   \begin{figure}
   \begin{lyxcode}
   <map>
   
   ~~<resource~id=\char`\"{}1\char`\"{}
   
   ~~~~src=\char`\"{}/res/msu/korte/phy231welcome.html\char`\"{}
   
   ~~~~type=\char`\"{}start\char`\"{}
   
   ~~~~title=\char`\"{}Start\char`\"{}>
   
   ~~~~</resource>
   
   ~~<resource~id=\char`\"{}2\char`\"{}
   
   ~~~~src=\char`\"{}\char`\"{}~type=\char`\"{}finish\char`\"{}
   
   ~~~~title=\char`\"{}Finish\char`\"{}>
   
   ~~~~</resource>
   
   ~~<resource~id=\char`\"{}6\char`\"{}
   
   ~~~~src=\char`\"{}/res/msu/korte/tests/units.problem\char`\"{}
   
   ~~~~type=\char`\"{}mandatory\char`\"{}
   
   ~~~~title=\char`\"{}Physical~Units~Test\char`\"{}>
   
   ~~~~</resource>
   
   ~~<resource~id=\char`\"{}9\char`\"{}
   
   ~~~~src=\char`\"{}/res/msu/korte/chapters/onedim.sequence\char`\"{}
   
   ~~~~title=\char`\"{}Motion~in~One~Dimension\char`\"{}>
   
   ~~~~</resource>
   
   ~~<resource~id=\char`\"{}11\char`\"{}
   
   ~~~~src=\char`\"{}/res/msu/bauer/bridges/units.sequence\char`\"{}
   
   ~~~~title=\char`\"{}Physical~Units~Refresher\char`\"{}>
   
   ~~~~</resource>
   
   ~~<condition~id=\char`\"{}19\char`\"{}
   
   ~~~~type=\char`\"{}stop\char`\"{}
   
   ~~~~value=\char`\"{}user.assessments{[}this./res/msu/korte/tests/units.problem{]}.status=solved\char`\"{}>
   
   ~~~~</condition>
   
   ~~<link~from=\char`\"{}1\char`\"{}~to=\char`\"{}6\char`\"{}></link>
   
   ~~<link~from=\char`\"{}6\char`\"{}~to=\char`\"{}9\char`\"{}~condition=\char`\"{}19\char`\"{}></link>
   
   ~~<link~from=\char`\"{}6\char`\"{}~to=\char`\"{}11\char`\"{}></link>
   
   ~~<link~from=\char`\"{}11\char`\"{}~to=\char`\"{}6\char`\"{}></link>
   
   ~~</map>
   \end{lyxcode}
   
   \caption{\label{XML}XML for Map in Figure \ref{Map_In_Advanced_Editor}}
   \end{figure}
   
   =end latex
   
   Fig. "XML for Map in Figure" shows the XML representation of the
   resource map shown in Fig. "Example of a Map in the Advanced Editor",
   which is the format in which maps are stored. In the figure, however,
   additional graphical map layout information generated by the Advanced
   Resource Assembly Tool is not displayed. This graphical information is
   optional to re-generate the same graphical layout when the map is
   brought up again in the Resource Assembly Tool, and is not needed for
   any other system functionality.
   
   Maps can be generated by tools other than the Resource Assembly
   Tool. In particular, an author might have some other representation of
   a course sequence, which can be converted into a map using scripts. If
   this map then were to be brought up in the Resource Assembly Tool, the
   Tool would automatically generate a graphical layout for it. Each
   entry of the map (resources, conditions and links) is stored in a
   separate tag.
   
   Resources and conditionsX<conditions> have to have unique ID
   numbers. These numbers are automatically generated by the Resource
   Assembly Tool when the entry is first created, or added to the entries
   when a map generated outside the Resource Assembly Tool is first
   retrieved. They can also be assigned by custom scripts or added in by
   hand.
   
   In the XML example, entry 1 is the start resource of the map. When
   this map is accessed, the source (src) URL of this tag will be the
   first resource rendered. Entry 2 is the finish resource of this
   map. This resource will be the last resource in the sequence of
   resources. Entry 6 is a problem resource with the given URL and title,
   as well as the priority "mandatory". Entry 19 is a condition, which is
   used by the link between entries 6, the problem, and 9, a
   sequence. I<The final syntax for conditions has not yet been
   determined.>
   
   =cut
   
 use strict;  use strict;
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::lonratsrv;  use Apache::lonratsrv;
   use Apache::lonsequence;
   use Apache::loncommon;
   use Apache::lonlocal;
   use File::Copy;
   
 my @order=();  use vars qw(@order @resources);
 my @resources=();  
   
   
 # Mapread read maps into global arrays @links and @resources, determines status  # Mapread read maps into global arrays @links and @resources, determines status
Line 52  sub mapread { Line 190  sub mapread {
     undef @links;      undef @links;
     undef @resources;      undef @resources;
     undef @order;      undef @order;
       @resources=('');
       @order=();
   
     my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,'');      my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,'');
     if ($errtext) { return ($errtext,2); }      if ($errtext) { return ($errtext,2); }
Line 65  sub mapread { Line 205  sub mapread {
         if ($command eq 'objlinks') {          if ($command eq 'objlinks') {
             $links[$number]=$content;              $links[$number]=$content;
         }          }
           if ($command eq 'objparms') {
       return(&mt('Map has resource parameters. Use advanced editor.'),1);
           }
     }      }
 # ------------------------------------------------------- Is this a linear map?  # ------------------------------------------------------- Is this a linear map?
     my @starters=();      my @starters=();
Line 77  sub mapread { Line 220  sub mapread {
     my ($start,$end,$cond)=split(/\:/,$_);      my ($start,$end,$cond)=split(/\:/,$_);
             if ((defined($starters[$start])) || (defined($endings[$end]))) {               if ((defined($starters[$start])) || (defined($endings[$end]))) { 
  return   return
                  ('Map has branchings. Use advanced editor.',1);                   (&mt('Map has branchings. Use advanced editor.'),1);
             }              }
     $starters[$start]=1;      $starters[$start]=1;
     $endings[$end]=1;      $endings[$end]=1;
     if ($cond) {      if ($cond) {
  return   return
                  ('Map has conditions. Use advanced editor.',1);                   (&mt('Map has conditions. Use advanced editor.'),1);
             }              }
  }   }
   
     }      }
     for (my $i=0; $i<=$#resources; $i++) {      for (my $i=1; $i<=$#resources; $i++) {
         if (defined($resources[$i])) {          if (defined($resources[$i])) {
     unless (($starters[$i]) || ($endings[$i])) {      unless (($starters[$i]) || ($endings[$i])) {
                 return                  return
  ('Map has unconnected resources. Use advanced editor.',1);   (&mt('Map has unconnected resources. Use advanced editor.'),1);
             }              }
         }          }
     }      }
   # ---------------------------------------------- Did we just read an empty map?
       if ($#resources<1) {
           undef $resources[0];
    $resources[1]=':::start';
           $resources[2]=':::finish';
       }
 # -------------------------------------------------- This is a linear map, sort  # -------------------------------------------------- This is a linear map, sort
   
     my $startidx=0;      my $startidx=0;
Line 126  sub mapread { Line 274  sub mapread {
     return $errtext;      return $errtext;
 }  }
   
   # ---------------------------------------------- Read a map as well as possible
   # Also used by the sequence handler
   # Call lonsequence::attemptread to read from resource space
   #
   sub attemptread {
       my $fn=shift;
   
       my @links;
       undef @links;
       my @theseres;
       undef @theseres;
   
       my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,'');
       if ($errtext) { return @theseres }
   
   # -------------------------------------------------------------------- Read map
       foreach (split(/\<\&\>/,$outtext)) {
    my ($command,$number,$content)=split(/\<\:\>/,$_);
           if ($command eq 'objcont') {
       $theseres[$number]=$content;
           }
           if ($command eq 'objlinks') {
               $links[$number]=$content;
           }
       }
   
   # --------------------------------------------------------------- Sort, sort of
   
       my @objsort=();
       undef @objsort;
   
       my @data1=();
       my @data2=();
       undef @data1;
       undef @data2;
   
       my $k;
       my $kj;
       my $j;
       my $ij;
   
      for ($k=1;$k<=$#theseres;$k++) {
         if (defined($theseres[$k])) {
            $objsort[$#objsort+1]=$k;
         }
      }
   
      for ($k=1;$k<=$#links;$k++) {
        if (defined($links[$k])) {
         @data1=split(/\:/,$links[$k]);
         $kj=-1;
         for (my $j=0;$j<=$#objsort;$j++) {
            if ((split(/\:/,$objsort[$j]))[0]==$data1[0]) {
               $kj=$j;
            }
         }
         if ($kj!=-1) { $objsort[$kj].=':'.$data1[1]; }
        }
      }
       for ($k=0;$k<=$#objsort;$k++) {
         for ($j=0;$j<=$#objsort;$j++) {
           if ($k!=$j) {
             @data1=split(/\:/,$objsort[$k]);
             @data2=split(/\:/,$objsort[$j]);
             my $dol=$#data1+1;
             my $dtl=$#data2+1;
             if ($dol+$dtl<1000) {
              for ($kj=1;$kj<$dol;$kj++) {
                if ($data1[$kj]==$data2[0]) {
                   for ($ij=1;$ij<$dtl;$ij++) {
                      $data1[$#data1+1]=$data2[$ij];
                   }
                }
              }
              for ($kj=1;$kj<$dtl;$kj++) {
                if ($data2[$kj]==$data1[0]) {
                    for ($ij=1;$ij<$dol;$ij++) {
                       $data2[$#data2+1]=$data1[$ij];
                    }
                }
              }
              $objsort[$k]=join(':',@data1);
              $objsort[$j]=join(':',@data2);
             }
            }
         } 
     }
   # ---------------------------------------------------------------- Now sort out
   
       @objsort=sort {
         my @data1=split(/\:/,$a);
         my @data2=split(/\:/,$b);
         my $rvalue=0;
         my $k;
         for ($k=1;$k<=$#data1;$k++) {
            if ($data1[$k]==$data2[0]) { $rvalue--; }
         }
         for ($k=1;$k<=$#data2;$k++) {
            if ($data2[$k]==$data1[0]) { $rvalue++; }
         }
         if ($rvalue==0) { $rvalue=$#data2-$#data1; }
         $rvalue;
       } @objsort;
   
       my @outres=();
       undef @outres;
   
       for ($k=0;$k<=$#objsort;$k++) {
    $outres[$k]=$theseres[(split(/\:/,$objsort[$k]))[0]];
       }
       return @outres;
   }
   
 # --------------------------------------------------------- Build up RAT screen  # --------------------------------------------------------- Build up RAT screen
 sub ratedt {  sub ratedt {
   my ($r,$url)=@_;    my ($r,$url)=@_;
Line 153  sub buttons { Line 414  sub buttons {
     my $adv=shift;      my $adv=shift;
     my $output='<form method=post>';           my $output='<form method=post>';     
     if ($adv==1) {      if ($adv==1) {
  $output.='<input type=submit name=forceadv value="Edit">';   $output.='<input type=submit name=forceadv value="'.&mt('Edit').'">';
     } else {      } else {
         unless ($adv==2) {          unless ($adv==2) {
            $output.='<input type=submit name=forcesmp value="Simple Edit">';             $output.='<input type=submit name=forcesmp value="'.&mt('Simple Edit').'">';
         }          }
  $output.='<input type=submit name=forceadv value="Advanced Edit">';   $output.='<input type=submit name=forceadv value="'.&mt('Advanced Edit').'">';
     }      }
     return $output.'</form><hr>';      return $output.'</form><hr>';
 }  }
   
 sub smpedt {  # ----------------------------------------------------------- Paste into target
    my ($r,$errtext)=@_;  # modifies @order, @resources
    my $buttons=&buttons(2);  
   
 # ---------------------------------------------------------- Process form input  sub pastetarget {
       my ($after,@which)=@_;
       my @insertorder=();
       foreach (@which) {
           if (defined($_)) {
       my ($name,$url)=split(/\=/,$_);
               $name=&Apache::lonnet::unescape($name);
               $url=&Apache::lonnet::unescape($url);
               if ($url) {
          my $idx=$#resources+1;
                  $insertorder[$#insertorder+1]=$idx;
                  my $ext='false';
                  if ($url=~/^http\:\/\//) { $ext='true'; }
                  $url=~s/\:/\&colon;/g;
                  $name=~s/\:/\&colon;/g;
                  $resources[$idx]=$name.':'.$url.':'.$ext.':normal:res';
      }
           }
       }
       my @oldorder=splice(@order,$after);
       @order=(@order,@insertorder,@oldorder);
   }
   
    my @importselect=();  # ------------------------------------------------ Get start and finish correct
    my @targetselect=();  # modifies @resources
    undef @importselect;  
    undef @targetselect;  sub startfinish {
    if (defined($ENV{'form.import'})) {  # Remove all start and finish
        if (ref($ENV{'form.import'})) {      foreach (@order) {
    @importselect=$ENV->{'form.import'};   my ($name,$url,$ext)=split(/\:/,$resources[$_]);
        } else {          if ($url=~/http\&colon\:\/\//) { $ext='true'; }
            @importselect=($ENV{'form.import'});          $resources[$_]=$name.':'.$url.':'.$ext.':normal:res';
        }      }
    }  # Garbage collection
    if (defined($ENV{'form.target'})) {      my $stillchange=1;
        if (ref($ENV{'form.target'})) {       while (($#order>1) && ($stillchange)) {
    @targetselect=$ENV->{'form.target'};         $stillchange=0;
        } else {         for (my $i=0;$i<=$#order;$i++) {
            @targetselect=($ENV{'form.target'});     my ($name,$url,$ext)=split(/\:/,$resources[$order[$i]]);
             unless ($url) {
   # Take out empty resource
                 for (my $j=$i+1;$j<=$#order;$j++) {
                     $order[$j-1]=$order[$j];
         }
                 $#order--;
         $stillchange=1;
                 last;
             }
        }         }
       }
   # Put in a start resource
      my ($name,$url,$ext)=split(/\:/,$resources[$order[0]]);
      $resources[$order[0]]=$name.':'.$url.':'.$ext.':start:res';
   # Make sure this has at least start and finish
      if ($#order==0) {
          $resources[$#resources+1]='::false';
          $order[1]=$#resources;
    }     }
 # ---------------------------------------------------------   # Make the last one a finish resource
      ($name,$url,$ext)=split(/\:/,$resources[$order[$#order]]);
    my $targetdetail=();     $resources[$order[$#order]]=$name.':'.$url.':'.$ext.':finish:res';
   }
   
    my @imporder=();  # ------------------------------------------------------------------- Store map
    my @impresources=();  
    my $importdetail='';  
 # ------------------------------------------------------------ Assemble windows  
   
    my $importwindow=join("\n",map {   sub storemap {
        my ($name)=split(/\:/,$impresources[$_]);      my $realfn=shift;
        unless ($name) { $name='UNKNOWN'; }      my $fn=$realfn;
        '<option value="'.$_.'">'.$name.'</option>';  # unless this is forced to work from the original file, use a temporary file
    } @imporder);  # instead
       unless (shift) {
    my $targetwindow=join("\n",map {          $fn=$realfn.'.tmp';
        my ($name)=split(/\:/,$resources[$_]);         unless (-e $fn) {
        unless ($name) { $name='UNKNOWN'; }    copy($realfn,$fn);
        '<option value="'.$_.'">'.$name.'</option>';         }
    } @order);      }
   # store data either into tmp or real file
       &startfinish();
       my $output='graphdef<:>no';
       my $k=1;
       for (my $i=0; $i<=$#order; $i++) {
           if (defined($resources[$order[$i]])) {
       $output.='<&>objcont<:>'.$order[$i].'<:>'.$resources[$order[$i]];
           }
           if (defined($order[$i+1])) {
       if (defined($resources[$order[$i+1]])) {
                  $output.='<&>objlinks<:>'.$k.'<:>'.
      $order[$i].':'.$order[$i+1].':0';
          $k++;
               }
           }
       }
       $output=~s/http\&colon\;\/\///g;
       $ENV{'form.output'}=$output;
       return 
        &Apache::lonratsrv::loadmap($fn,&Apache::lonratsrv::savemap($fn,''));
   }
   
 # ----------------------------------------------------- Start simple RAT screen  sub editscript {
    $r->print(<<ENDSMPHEAD);      my $mode=shift;
 <html>      my $resurl=&Apache::loncommon::lastresurl();
 <head>      return(<<ENDSCRIPT);
 <script>  
 var srch;  var srch;
 var srchflag=-1; // 1 means currently open  var srchflag=-1; // 1 means currently open
                  // 0 means closed (but has been open)                   // 0 means closed (but has been open)
Line 256  function idxopen(mode) { Line 572  function idxopen(mode) {
    var options="scrollbars=1,resizable=1,menubar=0";     var options="scrollbars=1,resizable=1,menubar=0";
    idxmode=mode;     idxmode=mode;
    idxflag=1;     idxflag=1;
    idx=open("/res/?launch=1&mode=simple&catalogmode="+mode,"idxout",options);     idx=open("$resurl/?launch=1&mode=$mode&catalogmode="+mode,"idxout",options);
    idx.focus();     idx.focus();
 }  }
   
Line 265  function srchopen(mode) { Line 581  function srchopen(mode) {
    var options="scrollbars=1,resizable=1,menubar=0";     var options="scrollbars=1,resizable=1,menubar=0";
    srchmode=mode;     srchmode=mode;
    srchflag=1;     srchflag=1;
    srch=open("/adm/searchcat?launch=1&mode=simple&catalogmode="+mode,"srchout",options);     srch=open("/adm/searchcat?launch=1&mode=$mode&catalogmode="+mode,"srchout",options);
    srch.focus();     srch.focus();
 }  }
 // ----------------------------------------------------- launch indexer browser  // ----------------------------------------------------- launch indexer browser
Line 291  function idxcheck(mode) { Line 607  function idxcheck(mode) {
    }     }
    idx.focus();     idx.focus();
 }  }
   
   
       var editbrowser;
       function openbrowser(formname,elementname,only,omit) {
           var url = '$resurl/?';
           if (editbrowser == null) {
               url += 'launch=1&';
           }
           url += 'catalogmode=interactive&';
           url += 'mode=edit&';
           url += 'form=' + formname + '&';
           if (only != null) {
               url += 'only=' + only + '&';
           } 
           if (omit != null) {
               url += 'omit=' + omit + '&';
           }
           url += 'element=' + elementname + '';
           var title = 'Browser';
           var options = 'scrollbars=1,resizable=1,menubar=0';
           options += ',width=700,height=600';
           editbrowser = open(url,title,options,'1');
           editbrowser.focus();
       }
   ENDSCRIPT
   }
   # ------------------------------------------------------- Simple edit processor
   
   sub smpedt {
      my ($r,$url,$errtext)=@_;
      my $buttons=&buttons(2);
      my $tmpfn=&Apache::lonnet::filelocation('',$url).'.tmp';
      my $targetmsg='';
      if ($ENV{'form.save'}) {
          $targetmsg='<b>Saving ...</b><br>';
          copy($tmpfn,&Apache::lonnet::filelocation('',$url));
          unlink($tmpfn);
          my ($errtext,$fatal)=
                              &mapread(&Apache::lonnet::filelocation('',$url),'');
      }
      if ($ENV{'form.revert'}) {
          $targetmsg='<b>Reverting ...</b><br>';
          unlink($tmpfn);
          my ($errtext,$fatal)=
                              &mapread(&Apache::lonnet::filelocation('',$url),'');
      }
      if (-e $tmpfn) {
         $targetmsg=
           '<b><font color="red">'.&mt('You are working with an unsaved version of your map.').'</font></b><br>';
         my ($errtext,$fatal)=&mapread($tmpfn,'');
      }
   # ---------------------------------------------------------- Process form input
   
      my @importselect=();
      my @targetselect=();
      undef @importselect;
      undef @targetselect;
      if (defined($ENV{'form.importsel'})) {
          if (ref($ENV{'form.importsel'})) {
      @importselect=sort(@{$ENV{'form.importsel'}});
          } else {
              @importselect=($ENV{'form.importsel'});
          }
      }
      if (defined($ENV{'form.target'})) {
          if (ref($ENV{'form.target'})) {
      @targetselect=sort(@{$ENV{'form.target'}});
          } else {
              @targetselect=($ENV{'form.target'});
          }
      }
   # ============================================================ Process commands
   
      my $targetdetail=$ENV{'form.targetdetail'};
      my $importdetail=$ENV{'form.curimpdetail'};
   
   # ---------------------------------------------------- Importing from groupsort
      if (($ENV{'form.importdetail'}) && (!$ENV{'form.impfortarget'})) {
   
          $importdetail='';
          my @curimport=split(/\&/,$ENV{'form.curimpdetail'});
   
          my $lastsel;
   
          if (defined($importselect[-1])) {
      $lastsel=$importselect[-1];
          } else {
              $lastsel=$#curimport;
          }
   
          for (my $i=0;$i<=$lastsel;$i++) {
              my ($name,$url)=split(/\=/,$curimport[$i]);
              if ($url) {
                 $importdetail.='&'.$name.'='.$url;
      }
          }
   
         $importdetail.='&'.$ENV{'form.importdetail'};
   
          for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
              my ($name,$url)=split(/\=/,$curimport[$i]);
              if ($url) {
                 $importdetail.='&'.$name.'='.$url;
     }
          }
          $importdetail=~s/\&+/\&/g;
          $importdetail=~s/^\&//;
   
   # ------------------------------------------------------------------- Clear all
      } elsif ($ENV{'form.clear'}) {
          $importdetail='';
   # ------------------------------------------------------------ Discard selected
      } elsif ($ENV{'form.discard'}) {
          $importdetail='';
          my @curimport=split(/\&/,$ENV{'form.curimpdetail'});
          foreach (@importselect) {
      $curimport[$_]='';
          }
          for (my $i=0;$i<=$#curimport;$i++) {
              my ($name,$url)=split(/\=/,$curimport[$i]);
              if ($url) {
                 $importdetail.='&'.$name.'='.$url;
      }
          }
   # --------------------------------------------------------- Loading another map
      } elsif ($ENV{'form.loadmap'}) {
          $importdetail='';
          my @curimport=split(/\&/,$ENV{'form.curimpdetail'});
   
          my $lastsel;
   
          if (defined($importselect[-1])) {
      $lastsel=$importselect[-1];
          } else {
              $lastsel=$#curimport;
          }
   
          for (my $i=0;$i<=$lastsel;$i++) {
              my ($name,$url)=split(/\=/,$curimport[$i]);
              if ($url) {
                 $importdetail.='&'.$name.'='.$url;
      }
          }
   
          foreach (
       &Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$ENV{'form.importmap'}))) {
      my ($name,$url)=split(/\:/,$_);
              if ($url) {
                 $importdetail.='&'.&Apache::lonnet::escape($name).'='.
            &Apache::lonnet::escape($url);
     }
          }
   
          for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
              my ($name,$url)=split(/\=/,$curimport[$i]);
              if ($url) {
                 $importdetail.='&'.$name.'='.$url;
     }
          }
          $importdetail=~s/\&+/\&/g;
          $importdetail=~s/^\&//;
   
   # ------------------------------------------------ Groupimport/search to target
      } elsif ($ENV{'form.importdetail'}) {
          my $lastsel;
          if (defined($targetselect[-1])) {
      $lastsel=$targetselect[-1];
          } else {
              $lastsel=$#order+1;
          }
          &pastetarget($lastsel,split(/\&/,$ENV{'form.importdetail'}));
          &storemap(&Apache::lonnet::filelocation('',$url));
   # ------------------------------------------------------------------------- Cut
      } elsif (($ENV{'form.cut'}) || ($ENV{'form.copy'})) {
          $importdetail='';
          my @curimport=split(/\&/,$ENV{'form.curimpdetail'});
   
          my $lastsel;
   
          if (defined($importselect[-1])) {
      $lastsel=$importselect[-1];
          } else {
              $lastsel=$#curimport;
          }
   
          for (my $i=0;$i<=$lastsel;$i++) {
              my ($name,$url)=split(/\=/,$curimport[$i]);
              if ($url) {
                 $importdetail.='&'.$name.'='.$url;
      }
          }
   
          foreach (@targetselect) {
      my ($name,$url)=split(/\:/,$resources[$order[$_-1]]);
              if ($url) {
                 $importdetail.='&'.&Apache::lonnet::escape($name).'='.
            &Apache::lonnet::escape($url);
     }
          }
   
          for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
              my ($name,$url)=split(/\=/,$curimport[$i]);
              if ($url) {
                 $importdetail.='&'.$name.'='.$url;
     }
          }
          $importdetail=~s/\&+/\&/g;
          $importdetail=~s/^\&//;
   
          if ($ENV{'form.cut'}) {
              my @neworder=();
              for (my $i=0;$i<=$#order;$i++) {
                  my $include=1;
                  foreach (@targetselect) {
      if ($_-1==$i) { $include=0; }
                  }
                  if ($include) { $neworder[$#neworder+1]=$order[$i]; }
              }
              @order=@neworder;
              &storemap(&Apache::lonnet::filelocation('',$url));      
          }
   
   # ----------------------------------------------------------------------- Paste
      } elsif ($ENV{'form.paste'}) {
          my $lastsel;
          if (defined($targetselect[-1])) {
      $lastsel=$targetselect[-1];
          } else {
              $lastsel=$#order+1;
          }
          my @newsequence;
          my @curimport=split(/\&/,$ENV{'form.curimpdetail'});
          foreach (@importselect) {
             $newsequence[$#newsequence+1]=$curimport[$_];
          }
          &pastetarget($lastsel,@newsequence);
          &storemap(&Apache::lonnet::filelocation('',$url));
   # -------------------------------------------------------------------- Move up 
      } elsif ($ENV{'form.moveup'}) {
          foreach (sort @targetselect) {
              if ($_-1>0) {
                 my $movethis=$order[$_-1];
                 $order[$_-1]=$order[$_-2];
                 $order[$_-2]=$movethis;
     }
          }
          &storemap(&Apache::lonnet::filelocation('',$url));
   # ------------------------------------------------------------------ Move down
      } elsif ($ENV{'form.movedown'}) {
          foreach (reverse sort @targetselect) {
              if ($_-1<$#order) {
                 my $movethis=$order[$_-1];
                 $order[$_-1]=$order[$_];
                 $order[$_]=$movethis;
      }
          }
          &storemap(&Apache::lonnet::filelocation('',$url));
   # --------------------------------------------------------------------- Rename
      } elsif ($ENV{'form.renameres'}) {
          my $residx=$Apache::lonratedt::order[$ENV{'form.renameidx'}-1];
          my ($name,@resrest)=split(/\:/,$Apache::lonratedt::resources[$residx]);
          $name=$ENV{'form.renametitle'};
          $name=~s/\:/\&colon\;/g;
          $Apache::lonratedt::resources[$residx]=$name.':'.join(':',@resrest);
          &storemap(&Apache::lonnet::filelocation('',$url));
      }
   # ------------------------------------------------------------ Assemble windows
      
      my $idx=-1;
      $importdetail='&'.$importdetail;
      $importdetail=~s/^\&+/\&/;
      my $importwindow=
          '<option value="-1"> ---- '.&mt('Import and Paste Area').' ---- </option>'.
        join("\n",map {
          $idx++;
          if ($_) { 
             my ($name,$url)=split(/\=/,$_);
             unless ($name) { $name=(split(/\//,$url))[-1]; }
             unless ($name) { $name='EMPTY'; }
             '<option value="'.$idx.'">'.&Apache::lonnet::unescape($name).
                                       '</option>';
         }
      } split(/\&/,$importdetail));
   
      $idx=0;
      $targetdetail='';
      my $targetwindow=       
          '<option value="0"> ------- '.&mt('Target Edit Map').' ------- </option>'.
        join("\n",map { 
          my ($name,$url)=split(/\:/,$resources[$_]);
          unless ($name) {  $name=(split(/\//,$url))[-1]; }
          unless ($name) { $name='EMPTY'; }
          $targetdetail.='&'.&Apache::lonnet::escape($name).'='.
                     &Apache::lonnet::escape($url);
          $idx++;
          $name=~s/\&colon;/\:/g;
          '<option value="'.$idx.'">'.$name.'</option>';
      } @order);
   
   # ----------------------------------------------------- Start simple RAT screen
      my $editscript=&editscript('simple');
      my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
      my %lt=&Apache::lonlocal::texthash(
         'sa' => 'Save',
         'nt' => 'New Title',
         'se' => 'Search',
         'im' => 'Import',
         'vi' => 'View',
         'lm' => 'Load Map',
         'ds' => 'Discard Selected',
         'ca' => 'Clear All',
         'ta' => 'Temporary Assembly Workspace',
         'rv' => 'Revert to Last Saved',
                                         'sa' => 'Save',
                                         'mu' => 'Move Up',
                                         'md' => 'Move Down',
                                         're' => 'Rename',
                                         'as' => 'after selected',
                                         'cs' => 'Cut selected',
                                         'ps' => 'Copy selected',
                                         'pas' => 'Paste after selected',
         );
      $r->print(<<ENDSMPHEAD);
   <html>
   <head>
   <script>
   
      $editscript
   
      function openview(entry) {
          var url=unescape((entry.split('='))[1]);
          var parts=new Array;
          parts=url.split('&colon;');
          url=parts.join(':');
          if (url) { open(url,'cat'); }
      }
   
      function viewtarget() {
          openview((document.forms.simpleedit.targetdetail.value.split('&'))
                   [document.forms.simpleedit.target.selectedIndex]);
      }
   
      function viewimport() {
          openview((document.forms.simpleedit.curimpdetail.value.split('&'))
                   [document.forms.simpleedit.importsel.selectedIndex]);
      }
   
      function renametarget() {
          var selidx=document.forms.simpleedit.target.selectedIndex;
          var entry=(document.forms.simpleedit.targetdetail.value.split('&'))
                   [selidx];
          var oldname=unescape((entry.split('='))[0]);
          var nameparts=oldname.split('&colon;');
          oldname=unescape(nameparts.join(':'));
          nameparts=oldname.split('&#34;');
          oldname=unescape(nameparts.join('"'));
          nameparts=oldname.split('&#39;');
          oldname=unescape(nameparts.join("'"));
          newtitle=prompt('$lt{'nt'}',oldname);
          if (newtitle) {
              document.forms.simpleedit.renameres.value=1;
              document.forms.simpleedit.renameidx.value=selidx;
              document.forms.simpleedit.renametitle.value=newtitle;
      document.forms.simpleedit.submit();
          }
      }
   
 </script>  </script>
 </head>                   </head>                 
 <body bgcolor='#FFFFFF'>  $bodytag
 $buttons  $buttons
 <font color=red>$errtext</font>  <font color=red>$errtext</font>
 <form method=post>  <form name=simpleedit method=post>
 <input type=hidden name=forcesmp value=1>  <input type=hidden name=forcesmp value=1>
   <input type=hidden name=renameres value=0>
   <input type=hidden name=renametitle value=''>
   <input type=hidden name=renameidx value=0>
 <table>  <table>
     <tr><th width="40%">Import</th>      <tr><th width="40%">$lt{'ta'}</th>
 <th>&nbsp;</th>  <th>&nbsp;</th>
 <th width="40%">Target</th></tr>  <th width="40%">File: $url</th></tr>
 <tr><td bgcolor="#FFFFCC">  <tr><td bgcolor="#FFFFCC">
 <input type=button onClick="javascript:groupsearch()" value="Group Search">  <input type=button onClick="javascript:groupsearch()" value="$lt{'se'}">
 <input type=button onClick="javascript:groupimport()" value="Group Import">  <input type=button onClick="javascript:groupimport();" value="$lt{'im'}">
 <input type=button onClick="javascript:viewimport()" value="View">  $lt{'as'}
   <hr>
   <input type=text size=20 name=importmap>
   <input type=button 
   onClick="javascript:openbrowser('simpleedit','importmap','sequence,page','')"
   value="Select Map"><input type=submit name=loadmap value="$lt{'lm'}"><hr>
   <input type=submit name="discard" value="$lt{'ds'}">
   <input type=submit name="clear" value="$lt{'ca'}">
   <input type=button onClick="javascript:viewimport()" value="$lt{'vi'}">
   
     </td><td>&nbsp;</td><td bgcolor="#FFFFCC">      </td><td>&nbsp;</td><td bgcolor="#FFFFCC">
 <input type=button onClick="javascript:viewtarget()" value="View">  
   <input type=button onClick=
   "javascript:impfortarget.value=1;groupsearch()" value="$lt{'se'}">
   <input type=button onClick=
   "javascript:impfortarget.value=1;groupimport();" value="$lt{'im'}">
   $lt{'as'}
   <hr>
   <input type=submit name="moveup" value="$lt{'mu'}">
   <input type=submit name="movedown" value="$lt{'md'}">
   <input type=button onClick="javascript:renametarget()" value="$lt{'re'}">
   <hr>$targetmsg
   <input type=submit name="revert" value="$lt{'rv'}">
   <input type=submit name="save" value="$lt{'sa'}">
   <input type=button onClick="javascript:viewtarget()" value="$lt{'vi'}">
 </td></tr>  </td></tr>
 <tr><td bgcolor="#FFFFCC"><select name="import" multiple>  
   <tr><td bgcolor="#FFFFCC"><select name="importsel" size=10 multiple>
 $importwindow  $importwindow
 </select>  </select>
 </td>  </td>
 <td bgcolor="#FFFFAA" align="center">  <td bgcolor="#FFFFAA" align="center">
 Cut selected<br>  $lt{'cs'}<br>
 <input type=submit name=cut value='<<<'><p>  <input type=submit name=cut value='<<<'><p>
 <hr>  <hr>
 Paste after selected<br>  $lt{'ps'}<br>
 <input type=submit name=paste value='>>>'>  <input type=submit name=copy value='<--'><p>
   <hr>
   $lt{'pas'}<br>
   <input type=submit name=paste value='-->'>
 </td>  </td>
 <td bgcolor="#FFFFCC"><select name="target" multiple>  <td bgcolor="#FFFFCC"><select name="target" size=10 multiple>
 $targetwindow  $targetwindow
 </select>  </select>
 </table>  </table>
 <input type=hidden name=importdetail value="$importdetail">  <input type=hidden name=importdetail value="">
   <input type=hidden name=curimpdetail value="$importdetail">
 <input type=hidden name=targetdetail value="$targetdetail">  <input type=hidden name=targetdetail value="$targetdetail">
   <input type=hidden name=impfortarget value="0">
 </form>  </form>
 </body></html>  </body></html>
 ENDSMPHEAD  ENDSMPHEAD
Line 347  ENDNODIR Line 1061  ENDNODIR
 # ---------------------------------------------------------------- View Handler  # ---------------------------------------------------------------- View Handler
   
 sub viewmap {  sub viewmap {
     my ($r,$adv,$errtext)=@_;      my ($r,$url,$adv,$errtext)=@_;
     $r->print('<html><body bgcolor="#FFFFFF">'.&buttons($adv));      $r->print('<html>'.
        &Apache::loncommon::bodytag('Edit Content of a Map').
        &buttons($adv));
     if ($errtext) {      if ($errtext) {
  $r->print($errtext.'<hr>');   $r->print($errtext.'<hr>');
     }      }
     foreach (@resources) {      my $idx=0;
       $r->print('<h1>'.$url.'</h1>');
       if ($adv) {
    $r->print('<p><b><font color="red">'.&mt('Map contents are not shown in order.').'</font></b></p><br />');
       }
       foreach (&attemptread(&Apache::lonnet::filelocation('',$url))) {
  if (defined($_)) {   if (defined($_)) {
               $idx++;
     my ($title,$url)=split(/\:/,$_);      my ($title,$url)=split(/\:/,$_);
             $title=~s/\&colon\;/\:/g;              $title=~s/\&colon\;/\:/g;
             $url=~s/\&colon\;/\:/g;              $url=~s/\&colon\;/\:/g;
             unless ($title) { $title='<i>Unknown</i>'; }              unless ($title) { $title=(split(/\//,$url))[-1] };
               unless ($title) { $title='<i>Empty</i>'; }
             if ($url) {              if ($url) {
  $r->print('<a href="'.&Apache::lonratsrv::qtescape($url).'">');   $r->print('<a href="'.&Apache::lonratsrv::qtescape($url).'">');
             }              }
             $r->print(&Apache::lonratsrv::qtescape($title));              $r->print(&Apache::lonratsrv::qtescape($title));
             if ($url) { $r->print('</a>'); }              if ($url) { $r->print('</a>'); }
             $r->print('<br>');      $r->print('<br>');
         }          }
     }      }
     $r->print('</body></html>');      $r->print('</body></html>');
Line 373  sub viewmap { Line 1096  sub viewmap {
   
 sub handler {  sub handler {
   my $r=shift;    my $r=shift;
   $r->content_type('text/html');    &Apache::loncommon::content_type($r,'text/html');
   $r->send_http_header;    $r->send_http_header;
   
   return OK if $r->header_only;    return OK if $r->header_only;
     my $target = $ENV{'form.grade_target'};
     if ($target eq 'meta') {
         &Apache::loncommon::content_type($r,'text/html');
         $r->send_http_header;
         return OK;
     }
     
   my $url=$r->uri;    my $url=$r->uri;
   my $fn=&Apache::lonnet::filelocation('',$url);    my $fn=&Apache::lonnet::filelocation('',$url);
   
Line 412  sub handler { Line 1141  sub handler {
   if ($ENV{'form.forceadv'}) {    if ($ENV{'form.forceadv'}) {
       &ratedt($r,$url);        &ratedt($r,$url);
   } elsif ($ENV{'form.forcesmp'}) {    } elsif ($ENV{'form.forcesmp'}) {
       &smpedt($r,$errtext);        &smpedt($r,$url,$errtext);
   } else {    } else {
       &viewmap($r,$adv,$errtext);        &viewmap($r,$url,$adv,$errtext);
   }    }
   return OK;    return OK;
 }  }

Removed from v.1.12  
changed lines
  Added in v.1.51


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>