File:  [LON-CAPA] / rat / lonratedt.pm
Revision 1.95: download - view: text, annotated - select for diffs
Wed May 20 13:55:40 2009 UTC (14 years, 11 months ago) by bisitz
Branches: MAIN
CVS tags: HEAD
Changes related to modification of LON-CAPA screen header.
start_page calls:
- Added breadcrumbs (only basic call)
- Added head_subbox and included CSTR standard header
- Moved edit buttons to head_subbox and removed <hr />

"no such dir" error screen:
- Added page header
- Added standard error style to error message
- Added &mt() to error message
- Standard style for path/filename

de.pm:
- Added translation for error message
- Optimized German wording for Simple Edit

    1: # The LearningOnline Network with CAPA
    2: # Edit Handler for RAT Maps
    3: #
    4: # $Id: lonratedt.pm,v 1.95 2009/05/20 13:55:40 bisitz Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: 
   29: 
   30: package Apache::lonratedt;
   31: 
   32: use strict;
   33: use Apache::Constants qw(:common);
   34: use Apache::lonnet;
   35: use Apache::lonsequence();
   36: use Apache::loncommon();
   37: use Apache::lonlocal;
   38: use LONCAPA::map();
   39: use File::Copy;
   40: use LONCAPA;
   41: use HTML::Entities();
   42: 
   43: # --------------------------------------------------------- Build up RAT screen
   44: sub ratedt {
   45:   my ($r,$url)=@_;
   46:   my %layout = ('border' => "0");
   47:     if ($env{'environment.remote'} eq 'off') {
   48:       $layout{'rows'} = "1,250,*";
   49:   } else {
   50:       $layout{'rows'} = "1,70,*";
   51:   }
   52:   my $js ='
   53: <script type="text/javascript">
   54:     var flag=0;
   55: </script>';
   56: 
   57:   my $start_page = 
   58:       &Apache::loncommon::start_page('Edit Sequence',$js,
   59: 				     {'frameset'    => 1,
   60: 				      'add_entries' => \%layout});
   61: 
   62:   my $end_page = 
   63:       &Apache::loncommon::end_page({'frameset' => 1});
   64: 
   65:   $r->print(<<ENDDOCUMENT);
   66: $start_page
   67: <frame name="server" src="$url/loadonly/ratserver" noresize="noresize"
   68:        noscroll="noscroll" />
   69: <frame name="code" src="$url/loadonly/adveditmenu" />
   70: <frame name="mapout" src="/adm/rat/map.html" />
   71: $end_page
   72: ENDDOCUMENT
   73: }
   74: 
   75: # ---------------------------------------------------------------- Make buttons
   76: 
   77: sub buttons {
   78:     my $adv=shift;
   79:     my $output='<form method="post">';     
   80:     if ($adv==1) {
   81: 	$output.='<input type="submit" name="forceadv" value="'.&mt('Edit').'" />'.
   82: 	    &Apache::loncommon::help_open_topic('Sequence_Advanced_Editor_Creation');
   83:     } else {
   84:         unless ($adv==2) {
   85:            $output.='<input type="submit" name="forcesmp" value="'.&mt('Simple Edit').'" />'.
   86: 	    &Apache::loncommon::help_open_topic('Sequence_Simple_Editor_Creation');
   87:         }
   88: 	$output.='<input type="submit" name="forceadv" value="'.&mt('Advanced Edit').'" />'.
   89: 	    &Apache::loncommon::help_open_topic('Sequence_Advanced_Editor_Creation');
   90:     }
   91:     return $output.'</form>';
   92: }
   93: 
   94: # ----------------------------------------------------------------- Edit script
   95: sub editscript {
   96:     my $mode=shift;
   97:     my $resurl=
   98: 	&Apache::loncommon::escape_single(&Apache::loncommon::lastresurl());
   99:     return(<<ENDSCRIPT);
  100: var srch;
  101: var srchflag=-1; // 1 means currently open
  102:                  // 0 means closed (but has been open)
  103:                  // -1 means never yet opened/defined
  104: var srchmode='';
  105: 
  106: var idx;
  107: var idxflag=-1; // 1 means currently open
  108:                  // 0 means closed (but has been open)
  109:                  // -1 means never yet opened/defined
  110: var idxmode='';
  111: 
  112: // ------------------------------------------------------ Clears indexer window
  113: function idxclear() {
  114:   idx.document.clear();
  115: }
  116: 
  117: // ------------------------------------------------------- Clears search window
  118: function srchclear() {
  119:   srch.document.clear();
  120: }
  121: 
  122: // ------------------------------------------------------ Closes indexer window
  123: function idxclose() {
  124:   if (idx && !idx.closed) {
  125:     idxflag=0;
  126:     idx.close();
  127:   }
  128: }
  129: 
  130: // ------------------------------------------------------- Closes search window
  131: function srchclose() {
  132:   if (srch && !srch.closed) {
  133:     srchflag=0;
  134:     srch.close();
  135:   }
  136: }
  137: 
  138: // -------------------------------------------------------- Open indexer window
  139: function idxopen(mode) {
  140:    var options="scrollbars=1,resizable=1,menubar=0,location=1,toolbar=1";
  141:    idxmode=mode;
  142:    idxflag=1;
  143:    idx=open('$resurl/?inhibitmenu=yes&launch=1&mode=$mode&catalogmode='+mode,'idxout',options);
  144:    idx.focus();
  145: }
  146: 
  147: // ------------------------------------------------------ Open groupsort window
  148: function groupopen(url,recover,bookmarks) {
  149:    var options="scrollbars=1,resizable=1,menubar=0";
  150:    idxflag=1;
  151:    idx=open("/adm/groupsort?inhibitmenu=yes&mode=$mode&recover="+recover+"&readfile="+url+"&bookmarks="+bookmarks,"idxout",options);
  152:    idx.focus();
  153: }
  154: 
  155: // --------------------------------------------------------- Open search window
  156: function srchopen(mode) {
  157:    var options="scrollbars=1,resizable=1,menubar=0";
  158:    srchmode=mode;
  159:    srchflag=1;
  160:    srch=open("/adm/searchcat?inhibitmenu=yes&launch=1&mode=$mode&catalogmode="+mode,"srchout",options);
  161:    srch.focus();
  162: }
  163: // ----------------------------------------------------- launch indexer browser
  164: function groupsearch() {
  165:    srchcheck('import');
  166: }
  167: 
  168: function groupimport() {
  169:    idxcheck('import');
  170: }
  171: 
  172: // ------------------------------------------------------- Do srch status check
  173: function srchcheck(mode) {
  174:    if (!srch || srch.closed || srchmode!=mode) {
  175:       srchopen(mode);
  176:    }
  177:    srch.focus();
  178: }
  179: 
  180: // -------------------------------------------------------- Do idx status check
  181: function idxcheck(mode) {
  182:    if (!idx || idx.closed || idxmode!=mode) {
  183:       idxopen(mode);
  184:    }
  185:    idx.focus();
  186: }
  187: 
  188: 
  189:     var editbrowser;
  190:     function openbrowser(formname,elementname,only,omit) {
  191:         var url = '$resurl/?';
  192:         if (editbrowser == null) {
  193:             url += 'launch=1&';
  194:         }
  195:         url += 'inhibitmenu=yes&';
  196:         url += 'catalogmode=interactive&';
  197:         url += 'mode=edit&';
  198:         url += 'form=' + formname + '&';
  199:         if (only != null) {
  200:             url += 'only=' + only + '&';
  201:         } 
  202:         if (omit != null) {
  203:             url += 'omit=' + omit + '&';
  204:         }
  205:         url += 'element=' + elementname + '';
  206:         var title = 'Browser';
  207:         var options = 'scrollbars=1,resizable=1,menubar=0,toolbar=1,location=1';
  208:         options += ',width=700,height=600';
  209:         editbrowser = open(url,title,options,'1');
  210:         editbrowser.focus();
  211:     }
  212: ENDSCRIPT
  213: }
  214: # ------------------------------------------------------- Simple edit processor
  215: 
  216: sub smpedt {
  217:    my ($r,$url,$errtext)=@_;
  218:    my $tmpfn=&Apache::lonnet::filelocation('',$url).'.tmp';
  219:    my $targetmsg='';
  220:    if ($env{'form.save'}) {
  221:        copy($tmpfn,&Apache::lonnet::filelocation('',$url));
  222:        unlink($tmpfn);
  223:        my ($errtext,$fatal)=
  224: 	   &LONCAPA::map::mapread(&Apache::lonnet::filelocation('',$url),'');
  225:        unless ($fatal) {
  226: 	   $targetmsg='<b>'.&mt('Saved.').'</b><br />';
  227:        } else {
  228: 	   $targetmsg='<b>'.&mt('An error occurred while saving.').'</b><br />';
  229:        }
  230:    }
  231:    if ($env{'form.revert'}) {
  232:        $targetmsg='<b>'.&mt('Reverted.').'</b><br />';
  233:        unlink($tmpfn);
  234:        my ($errtext,$fatal)=
  235: 	   &LONCAPA::map::mapread(&Apache::lonnet::filelocation('',$url),'');
  236:    }
  237:    if (-e $tmpfn) {
  238:       $targetmsg=
  239:         '<span class="LC_warning">'.&mt('You are working with an unsaved version of your map.').'</span><br />';
  240:       my ($errtext,$fatal)=&LONCAPA::map::mapread($tmpfn,'');
  241:    }
  242: # ---------------------------------------------------------- Process form input
  243: 
  244:    my @importselect=&Apache::loncommon::get_env_multiple('form.importsel');
  245:    my @targetselect=&Apache::loncommon::get_env_multiple('form.target');
  246: # ============================================================ Process commands
  247: 
  248:    my $targetdetail=$env{'form.targetdetail'};
  249:    my $importdetail=$env{'form.curimpdetail'};
  250: 
  251: # ---------------------------------------------------- Importing from groupsort
  252:    if (($env{'form.importdetail'}) && (!$env{'form.impfortarget'})) {
  253: 
  254:        $importdetail='';
  255:        my @curimport=split(/\&/,$env{'form.curimpdetail'});
  256: 
  257:        my $lastsel;
  258: 
  259:        if (defined($importselect[-1])) {
  260: 	   $lastsel=$importselect[-1];
  261:        } else {
  262:            $lastsel=$#curimport;
  263:        }
  264: 
  265:        for (my $i=0;$i<=$lastsel;$i++) {
  266:            my ($name,$url)=split(/\=/,$curimport[$i]);
  267:            if ($url) {
  268:               $importdetail.='&'.$name.'='.$url;
  269: 	   }
  270:        }
  271: 
  272:       $importdetail.='&'.$env{'form.importdetail'};
  273: 
  274:        for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
  275:            my ($name,$url)=split(/\=/,$curimport[$i]);
  276:            if ($url) {
  277:               $importdetail.='&'.$name.'='.$url;
  278: 	  }
  279:        }
  280:        $importdetail=~s/\&+/\&/g;
  281:        $importdetail=~s/^\&//;
  282: 
  283: # ------------------------------------------------------------------- Clear all
  284:    } elsif ($env{'form.clear'}) {
  285:        $importdetail='';
  286: # ------------------------------------------------------------ Discard selected
  287:    } elsif ($env{'form.discard'}) {
  288:        $importdetail='';
  289:        my @curimport=split(/\&/,$env{'form.curimpdetail'});
  290:        foreach (@importselect) {
  291: 	   $curimport[$_]='';
  292:        }
  293:        for (my $i=0;$i<=$#curimport;$i++) {
  294:            my ($name,$url)=split(/\=/,$curimport[$i]);
  295:            if ($url) {
  296:               $importdetail.='&'.$name.'='.$url;
  297: 	   }
  298:        }
  299: # --------------------------------------------------------- Loading another map
  300:    } elsif ($env{'form.loadmap'}) {
  301:        $importdetail='';
  302:        my @curimport=split(/\&/,$env{'form.curimpdetail'});
  303: 
  304:        my $lastsel;
  305: 
  306:        if (defined($importselect[-1])) {
  307: 	   $lastsel=$importselect[-1];
  308:        } else {
  309:            $lastsel=$#curimport;
  310:        }
  311: 
  312:        for (my $i=0;$i<=$lastsel;$i++) {
  313:            my ($name,$url)=split(/\=/,$curimport[$i]);
  314:            if ($url) {
  315:               $importdetail.='&'.$name.'='.$url;
  316: 	   }
  317:        }
  318: 
  319:        foreach (
  320:     &Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) {
  321: 	   my ($name,$url)=split(/\:/,$_);
  322:            if ($url) {
  323:               $importdetail.='&'.&escape($name).'='.
  324: 		 	         &escape($url);
  325: 	  }
  326:        }
  327: 
  328:        for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
  329:            my ($name,$url)=split(/\=/,$curimport[$i]);
  330:            if ($url) {
  331:               $importdetail.='&'.$name.'='.$url;
  332: 	  }
  333:        }
  334:        $importdetail=~s/\&+/\&/g;
  335:        $importdetail=~s/^\&//;
  336: 
  337: # ------------------------------------------------ Groupimport/search to target
  338:    } elsif ($env{'form.importdetail'}) {
  339:        my $lastsel;
  340:        if (defined($targetselect[-1])) {
  341: 	   $lastsel=$targetselect[-1];
  342:        } else {
  343:            $lastsel=$#LONCAPA::map::order+1;
  344:        }
  345:        &LONCAPA::map::pastetarget($lastsel,split(/\&/,$env{'form.importdetail'}));
  346:        &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
  347: # ------------------------------------------------------------------------- Cut
  348:    } elsif (($env{'form.cut'}) || ($env{'form.copy'})) {
  349:        $importdetail='';
  350:        my @curimport=split(/\&/,$env{'form.curimpdetail'});
  351: 
  352:        my $lastsel;
  353: 
  354:        if (defined($importselect[-1])) {
  355: 	   $lastsel=$importselect[-1];
  356:        } else {
  357:            $lastsel=$#curimport;
  358:        }
  359: 
  360:        for (my $i=0;$i<=$lastsel;$i++) {
  361:            my ($name,$url)=split(/\=/,$curimport[$i]);
  362:            if ($url) {
  363:               $importdetail.='&'.$name.'='.$url;
  364: 	   }
  365:        }
  366: 
  367:        foreach (@targetselect) {
  368: 	   my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$LONCAPA::map::order[$_-1]]);
  369:            if ($url) {
  370:               $importdetail.='&'.&escape($name).'='.
  371: 		 	         &escape($url);
  372: 	  }
  373:        }
  374: 
  375:        for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
  376:            my ($name,$url)=split(/\=/,$curimport[$i]);
  377:            if ($url) {
  378:               $importdetail.='&'.$name.'='.$url;
  379: 	  }
  380:        }
  381:        $importdetail=~s/\&+/\&/g;
  382:        $importdetail=~s/^\&//;
  383: 
  384:        if ($env{'form.cut'}) {
  385:            my @neworder=();
  386:            for (my $i=0;$i<=$#LONCAPA::map::order;$i++) {
  387:                my $include=1;
  388:                foreach (@targetselect) {
  389: 		   if ($_-1==$i) { $include=0; }
  390:                }
  391:                if ($include) { 
  392: 		   $neworder[$#neworder+1]=$LONCAPA::map::order[$i]; 
  393: 	       } else {
  394: 		   &LONCAPA::map::makezombie($LONCAPA::map::order[$i]);
  395: 	       }
  396:            }
  397:            @LONCAPA::map::order=@neworder;
  398:            &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));      
  399:        }
  400: 
  401: # ----------------------------------------------------------------------- Paste
  402:    } elsif ($env{'form.paste'}) {
  403:        my $lastsel;
  404:        if (defined($targetselect[-1])) {
  405: 	   $lastsel=$targetselect[-1];
  406:        } else {
  407:            $lastsel=$#LONCAPA::map::order+1;
  408:        }
  409:        my @newsequence;
  410:        my @curimport=split(/\&/,$env{'form.curimpdetail'});
  411:        foreach (@importselect) {
  412:           $newsequence[$#newsequence+1]=$curimport[$_];
  413:        }
  414:        &LONCAPA::map::pastetarget($lastsel,@newsequence);
  415:        &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
  416: # -------------------------------------------------------------------- Move up 
  417:    } elsif ($env{'form.moveup'}) {
  418:        foreach (sort @targetselect) {
  419:            if ($_-1>0) {
  420:               my $movethis=$LONCAPA::map::order[$_-1];
  421:               $LONCAPA::map::order[$_-1]=$LONCAPA::map::order[$_-2];
  422:               $LONCAPA::map::order[$_-2]=$movethis;
  423: 	  }
  424:        }
  425:        &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
  426: # ------------------------------------------------------------------ Move down
  427:    } elsif ($env{'form.movedown'}) {
  428:        foreach (reverse sort @targetselect) {
  429:            if ($_-1<$#LONCAPA::map::order) {
  430:               my $movethis=$LONCAPA::map::order[$_-1];
  431:               $LONCAPA::map::order[$_-1]=$LONCAPA::map::order[$_];
  432:               $LONCAPA::map::order[$_]=$movethis;
  433: 	   }
  434:        }
  435:        &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
  436: # --------------------------------------------------------------------- Rename
  437:    } elsif ($env{'form.renameres'}) {
  438:        my $residx=$LONCAPA::map::order[$env{'form.renameidx'}-1];
  439:        my ($name,@resrest)=split(/\:/,$LONCAPA::map::resources[$residx]);
  440:        $name=$env{'form.renametitle'};
  441:        $name=~s/\:/\&colon\;/g;
  442:        $LONCAPA::map::resources[$residx]=$name.':'.join(':',@resrest);
  443:        &LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
  444:    }
  445: # ------------------------------------------------------------ Assemble windows
  446:    
  447:    my $idx=-1;
  448:    $importdetail='&'.$importdetail;
  449:    $importdetail=~s/^\&+/\&/;
  450:    my $importwindow=
  451:        '<option value="-1"> ---- '.&mt('Import and Paste Area').' ---- </option>'.
  452:      join("\n",map {
  453:        $idx++;
  454:        if ($_) { 
  455:           my ($name,$url)=split(/\=/,$_);
  456:           unless ($name) { $name=(split(/\//,$url))[-1]; }
  457:           unless ($name) { $name='EMPTY'; }
  458:           '<option value="'.$idx.'">'.&unescape($name).
  459:                                     '</option>';
  460:       }
  461:    } split(/\&/,$importdetail));
  462: 
  463:    $idx=0;
  464:    $targetdetail='';
  465:    my $targetwindow=       
  466:        '<option value="0"> ------- '.&mt('Target Edit Map').' ------- </option>'.
  467:      join("\n",map { 
  468:        my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$_]);
  469:        unless ($name) {  $name=(split(/\//,$url))[-1]; }
  470:        unless ($name) { $name='EMPTY'; }
  471:        $name = &LONCAPA::map::qtescape($name);
  472:        $url  = &LONCAPA::map::qtescape($url);
  473:        $targetdetail.='&'.&escape($name).'='.
  474: 	                  &escape($url);
  475:        $idx++;
  476:        $name = &HTML::Entities::encode($name,'\'"<>&');
  477:        '<option value="'.$idx.'">'.$name.'</option>';
  478:    } @LONCAPA::map::order);
  479: 
  480: # ----------------------------------------------------- Start simple RAT screen
  481:    my $editscript=&editscript('simple');
  482: 
  483:    my %lt=&Apache::lonlocal::texthash(
  484: 				      'sa' => 'Save',
  485: 				      'nt' => 'New Title',
  486: 				      'se' => 'Search',
  487: 				      'im' => 'Import',
  488:                                       'bk' => 'Import Bookmarks',
  489: 				      'vi' => 'View',
  490: 				      'lm' => 'Load Map',
  491: 				      'ds' => 'Discard Selected',
  492: 				      'ca' => 'Clear All',
  493: 				      'ta' => 'Temporary Assembly Workspace',
  494: 				      'rv' => 'Revert to Last Saved',
  495:                                       'sa' => 'Save',
  496:                                       'mu' => 'Move Up',
  497:                                       'md' => 'Move Down',
  498:                                       're' => 'Rename',
  499:                                       'as' => 'after selected',
  500:                                       'cs' => 'Cut selected',
  501:                                       'ps' => 'Copy selected',
  502:                                       'pas' => 'Paste after selected',
  503:                                       'reco' => 'Recover Deleted'
  504: 				      );
  505:    my $js=<<ENDJS;
  506: <script type="text/javascript">
  507: 
  508:    $editscript
  509: 
  510:    function openview(entry) {
  511:        var url=unescape((entry.split('='))[1]);
  512:        var parts=new Array;
  513:        if (url) { open(url,'cat'); }
  514:    }
  515: 
  516:    function viewtarget() {
  517:        openview((document.forms.simpleedit.targetdetail.value.split('&'))
  518:                 [document.forms.simpleedit.target.selectedIndex]);
  519:    }
  520: 
  521:    function viewimport() {
  522:        openview((document.forms.simpleedit.curimpdetail.value.split('&'))
  523:                 [document.forms.simpleedit.importsel.selectedIndex]);
  524:    }
  525: 
  526:    function renametarget() {
  527:        var selidx=document.forms.simpleedit.target.selectedIndex;
  528:        var entry=(document.forms.simpleedit.targetdetail.value.split('&'))
  529:                 [selidx];
  530:        var oldname=unescape((entry.split('='))[0]);
  531:        newtitle=prompt('$lt{'nt'}',oldname);
  532:        if (newtitle) {
  533:            document.forms.simpleedit.renameres.value=1;
  534:            document.forms.simpleedit.renameidx.value=selidx;
  535:            document.forms.simpleedit.renametitle.value=newtitle;
  536: 	   document.forms.simpleedit.submit();
  537:        }
  538:    }
  539: 
  540: </script>
  541: ENDJS
  542: 
  543:     my $start_page = &Apache::loncommon::start_page('Construction Space',$js)
  544:                     .&Apache::lonhtmlcommon::breadcrumbs(# FIXME add breadcrumbs
  545:                          &Apache::loncommon::help_open_menu('Sequence_Simple_Editor_Creation',
  546:                              'Sequence_Simple_Editor_Creation',
  547:                              6,'RAT'))
  548:                     .&Apache::loncommon::head_subbox(
  549:                          &Apache::loncommon::CSTR_pageheader()
  550:                         .&buttons(2));
  551:     my $end_page = &Apache::loncommon::end_page();
  552: 
  553:     $r->print(<<ENDSMPHEAD);
  554: $start_page
  555: <span class="LC_error">$errtext</span>
  556: <form name="simpleedit" method="post">
  557: <input type="hidden" name="forcesmp" value="1" />
  558: <input type="hidden" name="renameres" value="0" />
  559: <input type="hidden" name="renametitle" value="" />
  560: <input type="hidden" name="renameidx" value="0" />
  561: <table>
  562:     <tr><th width="40%">$lt{'ta'}</th>
  563: <th>&nbsp;</th>
  564: <th width="40%">File: $url</th></tr>
  565: <tr><td bgcolor="#FFFFCC">
  566: <input type="button" onClick="javascript:groupsearch()" value="$lt{'se'}" />
  567: <input type="button" onClick="javascript:groupimport();" value="$lt{'im'}" />
  568: $lt{'as'}
  569: <hr />
  570: <input type="text" size="20" name="importmap" />
  571: <input type="button" 
  572: onClick="javascript:openbrowser('simpleedit','importmap','sequence,page','')"
  573: value="Select Map" /><input type="submit" name="loadmap" value="$lt{'lm'}" /><hr />
  574: <input type="submit" name="discard" value="$lt{'ds'}" />
  575: <input type="submit" name="clear" value="$lt{'ca'}" />
  576: <input type="button" onClick="javascript:viewimport()" value="$lt{'vi'}" />
  577: 
  578:     </td><td>&nbsp;</td><td bgcolor="#FFFFCC">
  579: 
  580: <input type="button" onClick=
  581: "javascript:impfortarget.value=1;groupsearch()" value="$lt{'se'}" />
  582: <input type="button" onClick=
  583: "javascript:impfortarget.value=1;groupimport();" value="$lt{'im'}" />
  584: <input type="button" onClick=
  585: "javascript:impfortarget.value=1;groupopen(0,1,1);" value="$lt{'bk'}" />
  586: <input type="button" onClick=
  587: "javascript:impfortarget.value=1;groupopen('$url',1,0);" value="$lt{'reco'}" />
  588: $lt{'as'}
  589: <hr />
  590: <input type="submit" name="moveup" value="$lt{'mu'}" />
  591: <input type="submit" name="movedown" value="$lt{'md'}" />
  592: <input type="button" onClick="javascript:renametarget()" value="$lt{'re'}" />
  593: <hr />$targetmsg
  594: <input type="submit" name="revert" value="$lt{'rv'}" />
  595: <input type="submit" name="save" value="$lt{'sa'}" />
  596: <input type="button" onClick="javascript:viewtarget()" value="$lt{'vi'}" />
  597: </td></tr>
  598: 
  599: <tr><td bgcolor="#FFFFCC"><select name="importsel" size="10" multiple="multiple">
  600: $importwindow
  601: </select>
  602: </td>
  603: <td bgcolor="#FFFFAA" align="center">
  604: $lt{'cs'}<br />
  605: <input type="submit" name="cut" value="<<<" /><p>
  606: <hr />
  607: $lt{'ps'}<br />
  608: <input type="submit" name="copy" value="<--" /><p>
  609: <h /r>
  610: $lt{'pas'}<br />
  611: <input type="submit" name="paste" value="-->" />
  612: </td>
  613: <td bgcolor="#FFFFCC"><select name="target" size="10" multiple="multiple">
  614: $targetwindow
  615: </select>
  616: </table>
  617: <input type="hidden" name="importdetail" value="" />
  618: <input type="hidden" name="curimpdetail" value="$importdetail" />
  619: <input type="hidden" name="targetdetail" value="$targetdetail" />
  620: <input type="hidden" name="impfortarget" value="0" />
  621: </form>
  622: $end_page
  623: ENDSMPHEAD
  624: }
  625: 
  626: # ----------------------------------------------------------------- No such dir
  627: sub nodir {
  628:    my ($r,$dir)=@_;
  629:    $dir=~s{^/home/$LONCAPA::username_re/public_html}{};
  630:    $r->print(&Apache::loncommon::start_page('Construction Space',undef)
  631:             .&Apache::lonhtmlcommon::breadcrumbs() # FIXME add breadcrumbs
  632:             .&Apache::loncommon::head_subbox(
  633:                  &Apache::loncommon::CSTR_pageheader())
  634:             .'<p class="LC_error">'
  635:             .&mt('No such directory: [_1]','<span class="LC_filename">'.$dir.'</span>'
  636:             .'</p>'
  637:             .&Apache::loncommon::end_page())
  638:    );
  639: }
  640: 
  641: # ---------------------------------------------------------------- View Handler
  642: 
  643: sub viewmap {
  644:     my ($r,$url,$adv,$errtext)=@_;
  645:     $r->print(&Apache::loncommon::start_page('Edit Content of a Map')
  646:              .&Apache::lonhtmlcommon::breadcrumbs(# FIXME add breadcrumbs
  647:                   &Apache::loncommon::help_open_menu('','',6,'RAT')) # FIXME help broken?
  648:              .&Apache::loncommon::head_subbox(
  649:                   &Apache::loncommon::CSTR_pageheader()
  650:                  .&buttons($adv))
  651:     );
  652:     if ($errtext) {
  653: 	$r->print('<div class="LC_error">'
  654:                  .$errtext
  655:                  .'</div>'
  656:                  .'<hr />'
  657:         );
  658:     }
  659:     my $idx=0;
  660:     $r->print('<h1>'.$url.'</h1>');
  661:     if ($adv) {
  662: 	$r->print('<p class="LC_warning">'
  663:                  .&mt('Map contents are not shown in order.')
  664:                  .'</p><br />'
  665:         );
  666:     }
  667:     $r->print(&Apache::loncommon::start_data_table()
  668:              .&Apache::loncommon::start_data_table_header_row()
  669:              .'<th>'.&mt('Type').'</th>'
  670:              .'<th>'.&mt('Title in map').'</th>'
  671:              .'<th>'.&mt('Filename of resource').'</th>'
  672:              .'<th>'.&mt('Link to published resource').'</th>'
  673:              .'<th>'.&mt('Link to resource in Construction Space').'</th>'
  674:              .&Apache::loncommon::end_data_table_header_row()
  675:     );
  676:     foreach (&LONCAPA::map::attemptread(&Apache::lonnet::filelocation('',$url))) {
  677: 	if (defined($_)) {
  678:             $idx++;
  679: 	    my ($title,$url,$cond)=split(/\:/,$_);
  680: 	    if ($cond eq 'cond') { next; }
  681:             $title= &LONCAPA::map::qtescape($title);
  682:             $url  = &LONCAPA::map::qtescape($url);
  683:             unless ($title) { $title=(split(/\//,$url))[-1] };
  684:             unless ($title) { $title='<i>'.&mt('Empty').'</i>'; }
  685:             my $resurl = $url;
  686:             my $resfilepath = $Apache::lonnet::perlvar{'lonDocRoot'}.$resurl;
  687:             my $filename; 
  688:             if ($resurl =~ m#/([^/]+)$#) {
  689:                 $filename = $1;
  690:             }
  691:             my $cstrurl = $resurl;
  692:             $cstrurl =~ s#^/res/[^/]+/([^/]+)/#/priv/$1/#;
  693:             $r->print(&Apache::loncommon::start_data_table_row()
  694:                      .'<td>'
  695:                      .'<img src="'.&Apache::loncommon::icon($resfilepath).'" />'
  696:                      .'</td>'
  697:                      .'<td>'
  698:                      .&HTML::Entities::encode(&LONCAPA::map::qtescape($title))
  699:                      .'</td>'
  700:                      .'<td>'.$filename.'</td>'
  701:                      .'<td>'
  702:             );
  703:             if ($url) {
  704: 		$r->print('<a href="'.$resurl.'">'.&mt('Resource space').'</a>');
  705:             } else {
  706:                 $r->print('&nbsp;');
  707:             }
  708:             $r->print('</td><td>');
  709:             if ($url) {
  710:                $r->print('<a href="'.$cstrurl.'">'.
  711:                          &mt('Construction space').'</a>');
  712:             } else {
  713:                 $r->print('&nbsp;');
  714:             }
  715:             $r->print('</td>'
  716:                      .&Apache::loncommon::end_data_table_row()
  717:             );
  718:         }
  719:     }
  720:     $r->print(&Apache::loncommon::end_data_table());
  721:     $r->print(&Apache::loncommon::end_page());
  722: }
  723: 
  724: # ================================================================ Main Handler
  725: 
  726: sub handler {
  727:   my $r=shift;
  728:   &Apache::loncommon::content_type($r,'text/html');
  729:   $r->send_http_header;
  730: 
  731:   return OK if $r->header_only;
  732:   my $target = $env{'form.grade_target'};
  733:   if ($target eq 'meta') {
  734:       &Apache::loncommon::content_type($r,'text/html');
  735:       $r->send_http_header;
  736:       return OK;
  737:   }
  738:   
  739:   my $url=$r->uri;
  740:   my $fn=&Apache::lonnet::filelocation('',$url);
  741: 
  742:   my ($dir)=($fn=~/^(.+)\/[^\/]+$/);
  743:   unless (-e $dir) {
  744:       &nodir($r,$dir);
  745:       return OK;
  746:   }
  747: 
  748: # ------------------------------------------- Determine which tools can be used
  749:   my $adv=0;
  750: 
  751:   unless ($env{'form.forcesmp'}) {
  752:      if ($env{'form.forceadv'}) {
  753:         $adv=1;
  754:      } elsif (my $fh=Apache::File->new($fn)) {
  755: 	 my $allmap=join('',<$fh>);
  756:          $adv=($allmap=~/\<map[^\>]+mode\s*\=\s*(\'|\")rat/is);
  757:      }
  758:   }
  759: 
  760:   my $errtext='';
  761:   my $fatal=0;
  762: 
  763: # -------------------------------------------------------------------- Load map
  764:   ($errtext,$fatal)=&LONCAPA::map::mapread($fn,$errtext);
  765: 
  766:   if ($fatal==1) { $adv=1; }
  767: 
  768: # ----------------------------------- adv==1 now means "graphical MUST be used"
  769: 
  770:   if ($env{'form.forceadv'}) {
  771:       &ratedt($r,$url);
  772:   } elsif ($env{'form.forcesmp'}) {
  773:       &smpedt($r,$url,$errtext);
  774:   } else {
  775:       &viewmap($r,$url,$adv,$errtext);
  776:   }
  777:   return OK;
  778: }
  779: 
  780: 1;
  781: __END__
  782: 
  783: 
  784: 
  785: =pod
  786: 
  787: =head1 NAME
  788: 
  789: Apache::lonratedt: simple resource assembly tool
  790: 
  791: =head1 SYNOPSIS
  792: 
  793: lonratedt provides the routines and the handler for the Advanced
  794:     Resource Assembly Tool (RAT), and ties the various pieces together
  795:     with Javascript.
  796: 
  797: =head1 OVERVIEW
  798: 
  799: =head2 Map Representation
  800: 
  801: =begin latex
  802: 
  803: %
  804: \begin{figure}
  805: \begin{center}\includegraphics[%
  806:   width=0.55\paperwidth,bb = 0 0 200 100, draft, type=eps]{Map_Example}\end{center}
  807: 
  808: 
  809: \caption{\label{Map_In_Advanced_Editor}Example of a Map in the Advanced Editor}
  810: \end{figure}
  811: %
  812: \begin{figure}
  813: \begin{lyxcode}
  814: <map>
  815: 
  816: ~~<resource~id=\char`\"{}1\char`\"{}
  817: 
  818: ~~~~src=\char`\"{}/res/msu/korte/phy231welcome.html\char`\"{}
  819: 
  820: ~~~~type=\char`\"{}start\char`\"{}
  821: 
  822: ~~~~title=\char`\"{}Start\char`\"{}>
  823: 
  824: ~~~~</resource>
  825: 
  826: ~~<resource~id=\char`\"{}2\char`\"{}
  827: 
  828: ~~~~src=\char`\"{}\char`\"{}~type=\char`\"{}finish\char`\"{}
  829: 
  830: ~~~~title=\char`\"{}Finish\char`\"{}>
  831: 
  832: ~~~~</resource>
  833: 
  834: ~~<resource~id=\char`\"{}6\char`\"{}
  835: 
  836: ~~~~src=\char`\"{}/res/msu/korte/tests/units.problem\char`\"{}
  837: 
  838: ~~~~type=\char`\"{}mandatory\char`\"{}
  839: 
  840: ~~~~title=\char`\"{}Physical~Units~Test\char`\"{}>
  841: 
  842: ~~~~</resource>
  843: 
  844: ~~<resource~id=\char`\"{}9\char`\"{}
  845: 
  846: ~~~~src=\char`\"{}/res/msu/korte/chapters/onedim.sequence\char`\"{}
  847: 
  848: ~~~~title=\char`\"{}Motion~in~One~Dimension\char`\"{}>
  849: 
  850: ~~~~</resource>
  851: 
  852: ~~<resource~id=\char`\"{}11\char`\"{}
  853: 
  854: ~~~~src=\char`\"{}/res/msu/bauer/bridges/units.sequence\char`\"{}
  855: 
  856: ~~~~title=\char`\"{}Physical~Units~Refresher\char`\"{}>
  857: 
  858: ~~~~</resource>
  859: 
  860: ~~<condition~id=\char`\"{}19\char`\"{}
  861: 
  862: ~~~~type=\char`\"{}stop\char`\"{}
  863: 
  864: ~~~~value=\char`\"{}user.assessments{[}this./res/msu/korte/tests/units.problem{]}.status=solved\char`\"{}>
  865: 
  866: ~~~~</condition>
  867: 
  868: ~~<link~from=\char`\"{}1\char`\"{}~to=\char`\"{}6\char`\"{}></link>
  869: 
  870: ~~<link~from=\char`\"{}6\char`\"{}~to=\char`\"{}9\char`\"{}~condition=\char`\"{}19\char`\"{}></link>
  871: 
  872: ~~<link~from=\char`\"{}6\char`\"{}~to=\char`\"{}11\char`\"{}></link>
  873: 
  874: ~~<link~from=\char`\"{}11\char`\"{}~to=\char`\"{}6\char`\"{}></link>
  875: 
  876: ~~</map>
  877: \end{lyxcode}
  878: 
  879: \caption{\label{XML}XML for Map in Figure \ref{Map_In_Advanced_Editor}}
  880: \end{figure}
  881: 
  882: =end latex
  883: 
  884: Fig. "XML for Map in Figure" shows the XML representation of the
  885: resource map shown in Fig. "Example of a Map in the Advanced Editor",
  886: which is the format in which maps are stored. In the figure, however,
  887: additional graphical map layout information generated by the Advanced
  888: Resource Assembly Tool is not displayed. This graphical information is
  889: optional to re-generate the same graphical layout when the map is
  890: brought up again in the Resource Assembly Tool, and is not needed for
  891: any other system functionality.
  892: 
  893: Maps can be generated by tools other than the Resource Assembly
  894: Tool. In particular, an author might have some other representation of
  895: a course sequence, which can be converted into a map using scripts. If
  896: this map then were to be brought up in the Resource Assembly Tool, the
  897: Tool would automatically generate a graphical layout for it. Each
  898: entry of the map (resources, conditions and links) is stored in a
  899: separate tag.
  900: 
  901: Resources and conditionsX<conditions> have to have unique ID
  902: numbers. These numbers are automatically generated by the Resource
  903: Assembly Tool when the entry is first created, or added to the entries
  904: when a map generated outside the Resource Assembly Tool is first
  905: retrieved. They can also be assigned by custom scripts or added in by
  906: hand.
  907: 
  908: In the XML example, entry 1 is the start resource of the map. When
  909: this map is accessed, the source (src) URL of this tag will be the
  910: first resource rendered. Entry 2 is the finish resource of this
  911: map. This resource will be the last resource in the sequence of
  912: resources. Entry 6 is a problem resource with the given URL and title,
  913: as well as the priority "mandatory". Entry 19 is a condition, which is
  914: used by the link between entries 6, the problem, and 9, a
  915: sequence. I<The final syntax for conditions has not yet been
  916: determined.>
  917: 
  918: =cut
  919: 
  920: 
  921: 

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