Diff for /loncom/interface/lonwishlist.pm between versions 1.3 and 1.10

version 1.3, 2010/08/16 13:37:41 version 1.10, 2011/02/15 14:54:51
Line 1 Line 1
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # Routines to control the wishlist  # Utility-routines for wishlist
 #  #
 # $Id$  # $Id$
 #  #
Line 26 Line 26
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
   
   =pod
   
   =head1 NAME
   
   Apache::lonwishlist - Wishlist-Module
     
   =head1 SYNOPSIS
   
   The wishlist offers a possibility to store links to resources from the resource-pool and external websites in a hierarchical list.
   It is only available for user with access to the resource-pool. The list can be structured by folders.
   
   The wishlist-module uses the CPAN-module "Tree" for easily handling the directory-structure of the wishlist. Each node in the tree has an index to be referenced by.
   
   =back
   
   =cut
   
 package Apache::lonwishlist;  package Apache::lonwishlist;
   
 use strict;  use strict;
 use Apache::Constants qw(:common);  
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonhtmlcommon;  use Apache::lonhtmlcommon;
Line 48  my %TreeToHash; Line 62  my %TreeToHash;
 my @allFolders;  my @allFolders;
 my @allNodes;  my @allNodes;
 my $indentConst = 20;  my $indentConst = 20;
   my $foldersOption;
   
   =pod
   
   =head2 Routines for getting and putting the wishlist data from and accordingly to users data.
   
   =over 4
   
   =item * &getWishlist()
   
        Get the wishlist-data via lonnet::getkeys() and lonnet::get() and returns the got data in a hash.
   
   
   =item * &putWishlist(wishlist)
   
        Parameter is a reference to a hash. Puts the wishlist-data contained in the given hash via lonnet::put() to user-data.
   
   
   =item * &deleteWishlist()
   
        Deletes all entries from the user-data for wishlist. Do this before putting in new data.
   
   
   =back
   
   =cut
   
   
 # Read wishlist from user-data  # Read wishlist from user-data
 sub getWishlist {  sub getWishlist {
     my %wishlist = &Apache::lonnet::dump('wishlist');      my @keys = &Apache::lonnet::getkeys('wishlist');
       my %wishlist = &Apache::lonnet::get('wishlist',\@keys);
     foreach my $i ( keys %wishlist) {      foreach my $i ( keys %wishlist) {
         #File not found. This appears at the first time using the wishlist          #File not found. This appears at the first time using the wishlist
         #Create file and put 'root' into it          #Create file and put 'root' into it
        if ($i =~m/^error:No such file/) {         if ($i =~m/^error:No such file/) {
            &Apache::lonnet::logthis($i.'! Create file by putting in the "root" of the directory tree.');             &Apache::lonnet::logthis($i.'! Create file by putting in the "root" of the directory tree.');
            &Apache::lonnet::put('wishlist', {'root' => ''});             &Apache::lonnet::put('wishlist', {'root' => ''});
            %wishlist = &Apache::lonnet::dump('wishlist');             my $options = '<option value="" selected="selected">('.&mt('Top level').')</option>';
              &Apache::lonnet::put('wishlist', {'folders' => $options});
              @keys = &Apache::lonnet::getkeys('wishlist');
              %wishlist = &Apache::lonnet::get('wishlist',\@keys);
        }         }
        elsif ($i =~ /^(con_lost|error|no_such_host)/i) {         elsif ($i =~ /^(con_lost|error|no_such_host)/i) {
            &Apache::lonnet::logthis('ERROR while attempting to get wishlist: '.$i);             &Apache::lonnet::logthis('ERROR while attempting to get wishlist: '.$i);
Line 67  sub getWishlist { Line 111  sub getWishlist {
        }         }
     }      }
   
     # if we got no keys in hash returned by dump(), return error.      # if we got no keys in hash returned by get(), return error.
     # wishlist will not be loaded, instead the user will be asked to try again later      # wishlist will not be loaded, instead the user will be asked to try again later
     if ((keys %wishlist) == 0) {      if ((keys %wishlist) == 0) {
         &Apache::lonnet::logthis('ERROR while attempting to get wishlist: no keys retrieved!');          &Apache::lonnet::logthis('ERROR while attempting to get wishlist: no keys retrieved!');
Line 92  sub deleteWishlist { Line 136  sub deleteWishlist {
 }  }
   
   
   =pod
   
   =head2 Routines for changing the directory struture of the wishlist.
   
   =over 4
   
   =item * &newEntry(title, path, note)
   
        Creates a new entry in the wishlist containing the given informations. Additionally saves the date of creation in the entry.  
   
   
   =item * &deleteEntries(marked)
   
        Parameter is a reference to an array containing the indices of all nodes that should be removed from the tree. 
   
   
   =item * &sortEntries(indexNode, at)
   
        Changes the position of a node given by indexNode within its siblings. New position is given by at.
   
   
   =item * &moveEntries(indexNodesToMove, indexParent)
   
        Parameter is a reference to an array containing the indices of all nodes that should be moved. indexParent specifies the node that will become the new Parent for these nodes. 
   
   
   =item * &setNewTitle(nodeindex, newTitle)
   
        Sets the title for the node given by nodeindex to newTitle.
   
   
   =item * &setNewPath(nodeindex, newPath)
   
        Sets the path for the node given by nodeindex to newPath.
   
   
   =item * &setNewNote(nodeindex, newNote)
   
        Sets the note for the node given by nodeindex to newNote.     
   
   
   =item * &saveChanges()
   
        Prepares the wishlist-hash to save it via &putWishlist(wishlist).   
   
   
   =back
   
   =cut
   
   
 # Create a new entry  # Create a new entry
 sub newEntry() {  sub newEntry() {
     my ($title, $path, $note) = @_;      my ($rootgiven, $title, $path, $note) = @_;
   
       $root = $rootgiven;
       @childrenRt = $root->children();
   
     my $date = gmtime();      my $date = gmtime();
     # Create Entry-Object      # Create Entry-Object
     my $entry = Entry->new(title => $title, path => $path, note => $note, date => $date);      my $entry = Entry->new(title => $title, path => $path, note => $note, date => $date);
Line 105  sub newEntry() { Line 204  sub newEntry() {
     if ($folderIndex ne '') {      if ($folderIndex ne '') {
         @allFolders = ();          @allFolders = ();
         &getFoldersToArray(\@childrenRt);          &getFoldersToArray(\@childrenRt);
         my $folderToInsertOn = &Tree::getNodeByIndex($folderIndex,\@allFolders);          my $folderToInsertOn = &Apache::Tree::getNodeByIndex($folderIndex,\@allFolders);
         $folderToInsertOn->add_child($tree);          $folderToInsertOn->add_child($tree);
     }      }
     else {      else {
         $root->add_child($tree);          $root->add_child($tree);
     }      }
     &saveChanges();      return &saveChanges();
 }  }
   
   
 # Delete entries  # Delete entries
 sub deleteEntries {  sub deleteEntries {
       my $rootgiven = shift;
     my $marked = shift;      my $marked = shift;
     &getNodesToArray(\@childrenRt);  
   
       $root = $rootgiven;
       @childrenRt = $root->children();
   
       &getNodesToArray(\@childrenRt);
     foreach my $m (@$marked) {      foreach my $m (@$marked) {
         my $found = &Tree::getNodeByIndex($m, \@allNodes);          my $found = &Apache::Tree::getNodeByIndex($m, \@allNodes);
         &Tree::removeNode($found);          # be sure, that entry exists (may have been deleted before, e.g. in an other browsertab)
           if (defined $found) {
               &Apache::Tree::removeNode($found);
           }
     }      }
     @allNodes = ();      @allNodes = ();
     &saveChanges();      return &saveChanges();
 }  }
   
   
 # Sort entries  # Sort entries
 sub sortEntries {  sub sortEntries {
       my $rootgiven = shift;
     my $indexNode = shift;      my $indexNode = shift;
     my $at = shift;      my $at = shift;
   
       $root = $rootgiven;
       @childrenRt = $root->children();
           
     &getNodesToArray(\@childrenRt);      &getNodesToArray(\@childrenRt);
     my $foundNode = &Tree::getNodeByIndex($indexNode, \@allNodes);      my $foundNode = &Apache::Tree::getNodeByIndex($indexNode, \@allNodes);
   
     &Tree::moveNode($foundNode,$at,undef);      &Apache::Tree::moveNode($foundNode,$at,undef);
     @allNodes = ();      @allNodes = ();
       return &saveChanges();
 }  }
   
   
 # Move entries  # Move entries
 sub moveEntries {  sub moveEntries {
       my $rootgiven = shift;
     my $indexNodesToMove = shift;      my $indexNodesToMove = shift;
     my $indexParent = shift;      my $indexParent = shift;
     my @nodesToMove = ();      my @nodesToMove = ();
   
       $root = $rootgiven;
       @childrenRt = $root->children();
   
     # get all nodes that should be moved      # get all nodes that should be moved
     &getNodesToArray(\@childrenRt);      &getNodesToArray(\@childrenRt);
     foreach my $index (@$indexNodesToMove) {      foreach my $index (@$indexNodesToMove) {
         my $foundNode = &Tree::getNodeByIndex($index, \@allNodes);          my $foundNode = &Apache::Tree::getNodeByIndex($index, \@allNodes);
         push(@nodesToMove, $foundNode);          push(@nodesToMove, $foundNode);
     }      }
   
Line 167  sub moveEntries { Line 282  sub moveEntries {
         }          }
         if (!$parentIsIn) {          if (!$parentIsIn) {
             if ($indexParent ne "root") {              if ($indexParent ne "root") {
                 $foundParent = &Tree::getNodeByIndex($indexParent, \@allNodes);                  $foundParent = &Apache::Tree::getNodeByIndex($indexParent, \@allNodes);
                 &Tree::moveNode($node,undef,$foundParent);                  &Apache::Tree::moveNode($node,undef,$foundParent);
             }              }
             else {              else {
                 &Tree::moveNode($node,undef,$root);                  &Apache::Tree::moveNode($node,undef,$root);
             }              }
         }          }
     }      }
     @allNodes = ();      @allNodes = ();
       return &saveChanges();
 }  }
   
   
 # Set a new title for an entry  # Set a new title for an entry
 sub setNewTitle {  sub setNewTitle {
     my ($nodeindex, $newTitle) = @_;      my ($rootgiven, $nodeindex, $newTitle) = @_;
   
       $root = $rootgiven;
       @childrenRt = $root->children();
   
     &getNodesToArray(\@childrenRt);      &getNodesToArray(\@childrenRt);
     my $found = &Tree::getNodeByIndex($nodeindex, \@allNodes);      my $found = &Apache::Tree::getNodeByIndex($nodeindex, \@allNodes);
     $found->value()->title($newTitle);       $found->value()->title($newTitle); 
     @allNodes = ();      @allNodes = ();
       return &saveChanges();
 }  }
   
   
 # Set a new path for an entry  # Set a new path for an entry
 sub setNewPath {  sub setNewPath {
     my ($nodeindex, $newPath) = @_;      my ($rootgiven, $nodeindex, $newPath) = @_;
   
       $root = $rootgiven;
       @childrenRt = $root->children();
   
     &getNodesToArray(\@childrenRt);      &getNodesToArray(\@childrenRt);
     my $found = &Tree::getNodeByIndex($nodeindex, \@allNodes);      my $found = &Apache::Tree::getNodeByIndex($nodeindex, \@allNodes);
     if ($found->value()->path()) {      if ($found->value()->path()) {
         $found->value()->path($newPath);           $found->value()->path($newPath); 
         return 1;          return &saveChanges();
     }      }
     @allNodes = ();      @allNodes = ();
     return 0;      return 0;
Line 205  sub setNewPath { Line 330  sub setNewPath {
   
 # Set a new note for an entry  # Set a new note for an entry
 sub setNewNote {  sub setNewNote {
     my ($nodeindex, $newNote) = @_;      my ($rootgiven, $nodeindex, $newNote) = @_;
   
       $root = $rootgiven;
       @childrenRt = $root->children();
   
     &getNodesToArray(\@childrenRt);      &getNodesToArray(\@childrenRt);
     my $found = &Tree::getNodeByIndex($nodeindex, \@allNodes);      my $found = &Apache::Tree::getNodeByIndex($nodeindex, \@allNodes);
     $found->value()->note($newNote);       $found->value()->note($newNote); 
     @allNodes = ();      @allNodes = ();
       return &saveChanges();
 }  }
   
   
 # Save all changes  # Save all changes
 sub saveChanges {  sub saveChanges {
     @childrenRt = $root->children();      @childrenRt = $root->children();
     &Tree::TreeIndex(\@childrenRt);      &Apache::Tree::TreeIndex(\@childrenRt);
     &Tree::setCountZero();      &Apache::Tree::setCountZero();
     &Tree::RootToHash(\@childrenRt);      &Apache::Tree::RootToHash(\@childrenRt);
     &Tree::TreeToHash(\@childrenRt);      &Apache::Tree::TreeToHash(\@childrenRt);
     &deleteWishlist();      &deleteWishlist();
     &putWishlist(\%TreeToHash);      &putWishlist(\%TreeToHash);
       return $root;
   
 }  }
   
   
   =pod
   
   =head2 Routines for handling the directory structure
   
   =over 4
   
   =item * &getFoldersForOption(nodes)
   
        Return the titles for all exiting folders in an option-tag, used to offer the users a possibility to create a new link or folder in an existing folder.
        Recursive call starting with all children of the root of the tree (parameter nodes is reference to an array containing the nodes of the current level). 
   
   
   =item * &getFoldersToArray(children)
   
        Puts all nodes that represent folders in the wishlist into an array. 
        Recursive call starting with all children of the root of the tree (parameter nodes is reference to an array containing the nodes of the current level).     
   
   
   =item * &getNodesToArray(children)
   
        Puts all existing nodes into an array (apart from the root node, because this one does not represent an entry in the wishlist).
        Recursive call starting with all children of the root of the tree (parameter nodes is reference to an array containing the nodes of the current level).     
    
   
   =back
   
   =cut
   
   
 # Return the names for all exiting folders in option-tags, so  # Return the names for all exiting folders in option-tags, so
 # a new link or a new folder can be created in an existing folder  # a new link or a new folder can be created in an existing folder
 my $indent = 0;  my $indent = 0;
 my $foldersOption;  
 sub getFoldersForOption {  sub getFoldersForOption {
     my $nodes = shift;      my $nodes = shift;
   
Line 250  sub getFoldersForOption { Line 409  sub getFoldersForOption {
 }  }
   
   
 sub getfoldersOption {  
    if (&getWishlist ne 'error') {  
        %TreeHash = &getWishlist();  
        $root = &Tree::HashToTree();  
        @childrenRt = $root->children();  
        &getFoldersForOption(\@childrenRt);  
        my $options = '<option value="" selected="selected">('.&mt('Top level').')</option>'.$foldersOption;  
        $foldersOption = '';  
        return $options;  
    }  
    else {  
        return '';  
    }  
 }  
   
   
 # Put all folder-nodes to an array  # Put all folder-nodes to an array
 sub getFoldersToArray {  sub getFoldersToArray {
     my $children = shift;      my $children = shift;
Line 294  sub getNodesToArray { Line 437  sub getNodesToArray {
 }  }
   
   
   =pod
   
   =head2 Routines for the user-interface of the wishlist
   
   =over 4
   
   =item * &JSforWishlist()
   
        Returns JavaScript-functions needed for wishlist actions like open and close folders.
   
   
   =item * &wishlistView(nodes)
   
        Returns the table-HTML-markup for the wishlist in mode "view".
        Recursive call starting with all children of the root of the tree (parameter nodes is reference to an array containing the nodes of the current level).     
   
   
   =item * &wishlistEdit(nodes)
   
        Returns the table-HTML-markup for the wishlist in mode "edit".
        Recursive call starting with all children of the root of the tree (parameter nodes is reference to an array containing the nodes of the current level).     
   
   
   =item * &wishlistMove(nodes, marked)
   
        Returns the table-HTML-markup for the wishlist in mode "move". Highlights all entry "selected to move" contained in marked (reference to array).
        Recursive call starting with all children of the root of the tree (parameter nodes is reference to an array containing the nodes of the current level).     
   
   
   =item * &wishlistImport(nodes)
   
        Returns the table-HTML-markup for the wishlist in mode "import".
        Recursive call starting with all children of the root of the tree (parameter nodes is reference to an array containing the nodes of the current level).     
    
   
   =item * &makePage(mode, marked)
   
        Returns the HTML-markup for the whole wishlist depending on mode. If mode is "move" we need the marked entries to be highlighted a "selected to move". 
        Calls &wishlistView(nodes), &wishlistEdit(nodes) or &wishlistMove(nodes, marked).
    
   
   =item * &makePopUpNewLink(title, path)
   
        Returns the HTML-markup for the pop-up-window 'Add Link'. If this is called up from a browsed resource, the input-fields titel and path are pre-filled with the resources' meta-data-title and it's path. 
   
   
   =item * &makePopUpNewFolder()
   
        Returns the HTML-markup for the pop-up-window 'Add Folder'.
   
   
   =item * &makePageSet()
   
        Returns the HTML-Markup for the page shown when a link was set by using the icon when viewing a resource.
   
   
   =item * &makePageImport()
   
        Returns the HTML-Markup for the page shown when links should be imported into courses.
    
   
   =item * &makeErrorPage ()
   
        Returns the HTML-Markup for an error-page shown if the wishlist could not be loaded.
    
   
   =back
   
   =cut
   
   
 # Return a script-tag containing Javascript-function  # Return a script-tag containing Javascript-function
 # needed for wishlist actions like 'new link' ect.  # needed for wishlist actions like 'new link' ect.
 sub JSforWishlist {  sub JSforWishlist {
Line 307  sub JSforWishlist { Line 521  sub JSforWishlist {
     &getFoldersToArray(\@childrenRt);      &getFoldersToArray(\@childrenRt);
     &getFoldersForOption(\@childrenRt);      &getFoldersForOption(\@childrenRt);
   
     # texthash  
     my %lt = &Apache::lonlocal::texthash(  
                  'nl' => 'New Link',  
                  'nf' => 'New Folder',  
                  'lt' => 'Link Title',  
                  'ft' => 'Folder Title',  
                  'pa' => 'Path',  
                  'nt' => 'Note',  
                  'si' => 'Save in',  
                  'cl' => 'Cancel');  
   
   
     my $inPageNewLink = '<h1>'.$lt{'nl'}.'</h1>'.  
                         '<form method="post" name="newlink" action="/adm/wishlist" target="wishlist" '.  
                         'onsubmit="return newlinksubmit();" >'.  
                         &Apache::lonhtmlcommon::start_pick_box().  
                         &Apache::lonhtmlcommon::row_title($lt{'lt'}).  
                         '<input type="text" name="title" size="45" value="" />'.  
                         &Apache::lonhtmlcommon::row_closure().  
                         &Apache::lonhtmlcommon::row_title($lt{'pa'}).  
                         '<input type="text" name="path" size="45" value="" />'.  
                         &Apache::lonhtmlcommon::row_closure().  
                         &Apache::lonhtmlcommon::row_title($lt{'nt'}).  
                         '<textarea name="note" rows="3" cols="35" style="width:100%"></textarea>'.  
                         &Apache::lonhtmlcommon::row_closure(1).  
                         &Apache::lonhtmlcommon::end_pick_box().  
                         '<br/><br/>'.  
                         '<input type="submit" value="'.$lt{'si'}.'" />'.  
                         '<select name="folders">'.  
                         '<option value="" selected="selected">('.&mt('Top level').')</option>'.  
                         $foldersOption.  
                         '</select>'.  
                         '<input type="button" value="'.$lt{'cl'}.'" onclick="javascript:window.close();" />'.  
                         '</form>';  
       
     my $inPageNewFolder = '<h1>'.$lt{'nf'}.'</h1>'.  
                           '<form method="post" name="newfolder" action="/adm/wishlist" target="wishlist" '.  
                           'onsubmit="return newfoldersubmit();" >'.  
                           &Apache::lonhtmlcommon::start_pick_box().  
                           &Apache::lonhtmlcommon::row_title($lt{'ft'}).  
                           '<input type="text" name="title" size="45" value="" /><br />'.  
                           &Apache::lonhtmlcommon::row_closure().  
                           &Apache::lonhtmlcommon::row_title($lt{'nt'}).  
                           '<textarea name="note" rows="3" cols="35" style="width:100%"></textarea><br />'.  
                           &Apache::lonhtmlcommon::row_closure(1).  
                           &Apache::lonhtmlcommon::end_pick_box().  
                           '<br/><br/>'.  
                           '<input type="submit" value="'.$lt{'si'}.'" />'.  
                           '<select name="folders">'.  
                           '<option value="" selected="selected">('.&mt('Top level').')</option>'.  
                           $foldersOption.  
                           '</select>'.  
                           '<input type="button" value="'.$lt{'cl'}.'" onclick="javascript:window.close();" />'.  
                           '</form>';  
   
     # Remove all \n for inserting on javascript document.write  
     $inPageNewLink =~ s/\n//g;  
     $inPageNewFolder =~ s/\n//g;  
   
     # it is checked, wether a path links to a LON-CAPA-resource or an external website. links to course-contents are not allowed      # it is checked, wether a path links to a LON-CAPA-resource or an external website. links to course-contents are not allowed
     # because they probably will return a kind of 'no access' (unless the user is already in the course, the path links to).      # because they probably will return a kind of 'no access' (unless the user is already in the course, the path links to).
     # also importing these kind of links into a course does not make much sense.      # also importing these kind of links into a course does not make much sense.
Line 381  sub JSforWishlist { Line 536  sub JSforWishlist {
     my $warningFolder = &mt('You must insert a title!');      my $warningFolder = &mt('You must insert a title!');
     my $warningDelete = &mt('Are you sure you want to delete the selected entries? Deleting a folder also deletes all entries within this folder!');      my $warningDelete = &mt('Are you sure you want to delete the selected entries? Deleting a folder also deletes all entries within this folder!');
     my $warningSave = &mt('You have unsaved changes. You can either save these changes now by clicking "ok" or click "cancel" if you do not want to save your changes.');      my $warningSave = &mt('You have unsaved changes. You can either save these changes now by clicking "ok" or click "cancel" if you do not want to save your changes.');
     my $warningMove = &mt('You must select a destination folder!');      my $warningMoveS = &mt('You must select at minimum one entry to move!');
       my $warningMoveD = &mt('You must select a destination folder!');
     $foldersOption = '';      $foldersOption = '';
   
     my $js = &Apache::lonhtmlcommon::scripttag(<<JAVASCRIPT);      my $js = &Apache::lonhtmlcommon::scripttag(<<JAVASCRIPT);
     function newLink() {      function newLink() {
         newlinkWin=window.open('','newlinkWin','width=580,height=320,scrollbars=yes');          newlinkWin=window.open('/adm/wishlist?mode=newLink','newlinkWin','width=580,height=350, scrollbars=yes');
         newlinkWin.document.write('$startPagePopup'   
                               +'<script type="text\/javascript">'  
                               +'function newlinksubmit(){'  
                               +'var path = document.getElementsByName("path")[0].value;'  
                               +'var title = document.getElementsByName("title")[0].value;'  
                               +'if (!path || !title) {'  
                               +'alert("$warningLink");'  
                               +'return false;}'  
                               +'var linkOK = (path.match(/^http:(\\\\/\\\\/)/) || path.match(/^https:(\\\\/\\\\/)/))'  
                               +'&& !(path.match(/\\.problem/) || path.match(/\\.exam/)'  
                               +'|| path.match(/\\.quiz/) || path.match(/\\.assess/)'  
                               +'|| path.match(/\\.survey/) || path.match(/\\.form/)'  
                               +'|| path.match(/\\.library/) || path.match(/\\.page/)'  
                               +'|| path.match(/\\.sequence/));'  
                               +'if (!path.match(/^(\\\\/res\\\\/)/) && !linkOK) {'  
                               +'alert("$warningLinkNotAllowed1");'  
                               +'return false;}'  
                               +'else {'  
                               +'window.close();'  
                               +'return true;}}'  
                               +'<\/scr'+'ipt>'  
                               +'$inPageNewLink'  
                               +'$endPagePopup');  
         newlinkWin.document.close();  
     }      }
   
     function newFolder() {      function newFolder() {
         newfolderWin=window.open('','newfolderWin','width=580,height=270, scrollbars=yes');          newfolderWin=window.open('/adm/wishlist?mode=newFolder','newfolderWin','width=580,height=270, scrollbars=yes');
         newfolderWin.document.write('$startPagePopup'   
                               +'<script type="text\/javascript">'  
                               +'function newfoldersubmit(){'  
                               +'var title = document.getElementsByName("title")[0].value;'  
                               +'if (!title) {'  
                               +'alert("$warningFolder");'  
                               +'return false;}'  
                               +'else {'  
                               +'window.close();'  
                               +'return true;}}'  
                               +'<\/scr'+'ipt>'  
                               +'$inPageNewFolder'  
                               +'$endPagePopup');  
         newfolderWin.document.close();  
     }      }
   
     function setFormAction(action,mode) {      function setFormAction(action,mode) {
Line 453  sub JSforWishlist { Line 571  sub JSforWishlist {
         else if (action == 'saveOK') {          else if (action == 'saveOK') {
             r = linksOK();              r = linksOK();
         }          }
           else if (action == 'move') {
               r = selectDestinationFolder(mode);
           }
         document.getElementsByName('list')[0].setAttribute("action", "/adm/wishlist?mode="+mode);           document.getElementsByName('list')[0].setAttribute("action", "/adm/wishlist?mode="+mode); 
         if (r) {          if (r) {
             document.getElementsByName('list')[0].submit();               document.getElementsByName('list')[0].submit(); 
Line 855  sub JSforWishlist { Line 976  sub JSforWishlist {
         }          }
     }      }
   
     function selectDestinationFolder() {      function selectDestinationFolder(mode) {
         var mark = document.getElementsByName('mark');          var mark = document.getElementsByName('mark');
         var i = 0;          var i = 0;
         for (i = 0; i < mark.length; i++) {          for (i = 0; i < mark.length; i++) {
Line 864  sub JSforWishlist { Line 985  sub JSforWishlist {
                 return true;                  return true;
             }              }
         }          }
         alert('$warningMove');          if (mode == 'move') {
               alert('$warningMoveS');
           }
           else {
               alert('$warningMoveD');
           }
         return false;          return false;
     }      }
   
Line 879  sub JSforWishlist { Line 1005  sub JSforWishlist {
        newWin.focus();         newWin.focus();
     }      }
   
     function finish_import() {  
         opener.document.forms.simpleedit.importdetail.value='';  
         for (var num = 0; num < document.forms.groupsort.fnum.value; num++) {  
             if (eval("document.forms.groupsort.check"+num+".checked") && eval("document.forms.groupsort.filelink"+num+".value") != '') {  
                 opener.document.forms.simpleedit.importdetail.value+='&'+  
                 eval("document.forms.groupsort.title"+num+".value")+'='+  
                 eval("document.forms.groupsort.filelink"+num+".value")+'='+  
                 eval("document.forms.groupsort.id"+num+".value");  
             }  
         }  
         opener.document.forms.simpleedit.submit();  
         self.close();  
     }  
   
     function checkAll() {      function checkAll() {
         var checkboxes = document.getElementsByName('check');          var checkboxes = document.getElementsByName('check');
         for (var i = 0; i < checkboxes.length; i++) {          for (var i = 0; i < checkboxes.length; i++) {
Line 911  JAVASCRIPT Line 1023  JAVASCRIPT
    return $js;     return $js;
 }  }
   
   sub JSforImport{
       my $rat = shift;
   
       my $js;
       if ($rat eq 'simple' || $rat eq '') {
           $js = &Apache::lonhtmlcommon::scripttag(<<JAVASCRIPT);
           function finish_import() {
               opener.document.forms.simpleedit.importdetail.value='';
               for (var num = 0; num < document.forms.groupsort.fnum.value; num++) {
                   if (eval("document.forms.groupsort.check"+num+".checked") && eval("document.forms.groupsort.filelink"+num+".value") != '') {
                       opener.document.forms.simpleedit.importdetail.value+='&'+
                       eval("document.forms.groupsort.title"+num+".value")+'='+
                       eval("document.forms.groupsort.filelink"+num+".value")+'='+
                       eval("document.forms.groupsort.id"+num+".value");
                   }
               }
               opener.document.forms.simpleedit.submit();
               self.close();
           }
   JAVASCRIPT
       }
       else {
           $js = &Apache::lonhtmlcommon::scripttag(<<JAVASCRIPT);
           function finish_import() {
               var linkflag=false;
               for (var num=0; num<document.forms.groupsort.fnum.value; num++) {
                   if (eval("document.forms.groupsort.check"+num+".checked") && eval("document.forms.groupsort.filelink"+num+".value") != '') {
                       insertRowInLastRow();
                       placeResourceInLastRow(
                           eval("document.forms.groupsort.title"+num+".value"),
                           eval("document.forms.groupsort.filelink"+num+".value"),
                           eval("document.forms.groupsort.id"+num+".value"),
                           linkflag
                           );
                       linkflag=true;
                   }
               }
               opener.editmode=0;
               opener.notclear=0;
               opener.linkmode=0;
               opener.draw();
               self.close();
           }
   
           function insertRowInLastRow() {
               opener.insertrow(opener.maxrow);
               opener.addobj(opener.maxrow,'e&2');
           }
   
           function placeResourceInLastRow (title,url,id,linkflag) {
               opener.mostrecent=opener.newresource(opener.maxrow,2,opener.unescape(title),
                                 opener.unescape(url),'false','normal',id);
               opener.save();
               if (linkflag) {
                   opener.joinres(opener.linkmode,opener.mostrecent,0);
               }
               opener.linkmode=opener.mostrecent;
           }
   JAVASCRIPT
       }
       return $js;
   }
   
 # HTML-Markup for table if in view-mode  # HTML-Markup for table if in view-mode
 my $wishlistHTMLview;  my $wishlistHTMLview;
Line 1230  sub wishlistImport { Line 1404  sub wishlistImport {
   
 # Returns the HTML-Markup for wishlist  # Returns the HTML-Markup for wishlist
 sub makePage {  sub makePage {
       my $rootgiven = shift;
     my $mode = shift;      my $mode = shift;
     my $marked = shift;      my $marked = shift;
   
       $root = $rootgiven;
       @childrenRt = $root->children();
   
     # breadcrumbs and start_page      # breadcrumbs and start_page
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
     &Apache::lonhtmlcommon::add_breadcrumb(      &Apache::lonhtmlcommon::add_breadcrumb(
Line 1243  sub makePage { Line 1421  sub makePage {
                                                         'onload' => 'javascript:onLoadAction('."'".$mode."'".');',                                                          'onload' => 'javascript:onLoadAction('."'".$mode."'".');',
                                                         'onunload' => 'javascript:window.name = '."'loncapaclient'"}});                                                          'onunload' => 'javascript:window.name = '."'loncapaclient'"}});
   
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Wishlist '.      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs(&mt('Wishlist').&Apache::loncommon::help_open_topic('Wishlist'));
                            '<a title="Online-Hilfe" href="/adm/help/Wishlist.hlp" target="_top">'.  
                            '<img src="/adm/help/help.png" alt="'.&mt('Help').'" '.  
                            'title="'.&mt('Help').'" class="LC_icon" /></a>');  
   
     # get javascript-code for wishlist-interactions      # get javascript-code for wishlist-interactions
     my $js = &JSforWishlist();      my $js = &JSforWishlist();
Line 1364  sub makePage { Line 1539  sub makePage {
                                                    'Now choose the new destination folder.').'</span></p>';                                                     'Now choose the new destination folder.').'</span></p>';
             &wishlistMove(\@childrenRt, $marked);              &wishlistMove(\@childrenRt, $marked);
             $inner .= '<table class="LC_data_table LC_tableOfContent">'.$wishlistHTMLmove.'</table><br/><br/>';              $inner .= '<table class="LC_data_table LC_tableOfContent">'.$wishlistHTMLmove.'</table><br/><br/>';
             $inner .= '<input type="button" value="'.&mt('Move').'" onclick="setFormAction('."'','view'".'); selectDestinationFolder()"/>'.              $inner .= '<input type="button" value="'.&mt('Move').'" onclick="setFormAction('."'move','view'".');"/>'.
                       '<input type="button" value="'.&mt('Cancel').'" onclick="go('."'/adm/wishlist'".')"/>';                        '<input type="button" value="'.&mt('Cancel').'" onclick="go('."'/adm/wishlist'".')"/>';
   
             $wishlistHTMLmove ='<tr id="root" class="LC_odd_row"><td><input type="radio" name="mark" id="radioRoot" value="root" /></td>'.              $wishlistHTMLmove ='<tr id="root" class="LC_odd_row"><td><input type="radio" name="mark" id="radioRoot" value="root" /></td>'.
Line 1389  sub makePage { Line 1564  sub makePage {
 }  }
   
   
   # Returns the HTML-Markup for the PopUp, shown when a new link should set, when NOT
   # beeing in the wishlist-interface (method is called in lonmenu and lonsearchcat)
   sub makePopUpNewLink {
       my ($title, $path) = @_;
   
       # Get all existing folders to offer posibility to set a new link
       # into a folder
       my %TreeHashLink = &Apache::lonwishlist::getWishlist();
       my $rootLink = &Apache::Tree::HashToTree(\%TreeHashLink);
       my @childrenRtLink = $rootLink->children();
   
       $foldersOption = '';
       @allFolders = ();
       &getFoldersToArray(\@childrenRtLink);
       &getFoldersForOption(\@childrenRtLink);
   
       my $options = '<option value="" selected="selected">('.&mt('Top level').')</option>'.$foldersOption;
       $foldersOption = '';
       @allFolders = ();
   
       # HTML-Markup for the Pop-Up-window 'Set a link for this resource to wishlist'
       my $startPageWishlistlink = 
           &Apache::loncommon::start_page('Set link to wishlist',undef,
                                         {'only_body' => 1,
                                          'bgcolor'   => '#FFFFFF',});
   
       my $warningLink = &mt('You must insert a title!');
       my $warningLinkNotAllowed1 = &mt('You can only insert links to LON-CAPA resources from the resource-pool '.
                                       'or to external websites. Paths to LON-CAPA resources must be of the form /res/dom/usr... . '.
                                       'Paths to external websites must contain the network protocol (e.g. http://...).');
   
       my $inPageWishlistlink1 = '<h1>'.&mt('Set a link to wishlist').'</h1>';
       # If no title is delivered, 'New Link' is called up from the wishlist-interface, so after
       # submitting the window should close instead of offering a link to wishlist (like it should do
       # if we call 'Set New Link' from within a browsed ressource)
       if (!$title) {
           $inPageWishlistlink1 .= '<form method="post" name="newlink" action="/adm/wishlist" target="wishlist"'.
                                   'onsubmit="return newlinksubmit();" >';
       }
       else {
           $inPageWishlistlink1 .= '<form method="post" name="newlink" action="/adm/wishlist?mode=set" '.
                                   'onsubmit="return newlinksubmit();" >';
       }
       $inPageWishlistlink1 .= &Apache::lonhtmlcommon::start_pick_box().
                               &Apache::lonhtmlcommon::row_title(&mt('Link Title'));
   
       my $inPageWishlistlink2 = &Apache::lonhtmlcommon::row_closure().
                                 &Apache::lonhtmlcommon::row_title(&mt('Path'));
   
       my $inPageWishlistlink3 = &Apache::lonhtmlcommon::row_closure().
                                 &Apache::lonhtmlcommon::row_title(&mt('Note')).
                                 '<textarea name="note" rows="3" cols="35" style="width:100%"></textarea>'.
                                 &Apache::lonhtmlcommon::row_closure(1).
                                 &Apache::lonhtmlcommon::end_pick_box().
                                 '<br/><br/>'.
                                 '<input type="submit" value="'.&mt('Save in').'" />'.
                                 '<select name="folders">'.
                                 $options.
                                 '</select>'.
                                 '<input type="button" value="'.&mt('cancel').'" onclick="javascript:window.close();" />'.
                                 '</form>';
       $options = '';
   
       my $endPageWishlistlink = &Apache::loncommon::end_page();
   
       my $popUp = $startPageWishlistlink.
       $inPageWishlistlink1.
       '<input type="text" name="title" size="45" value=""/>'.
       $inPageWishlistlink2.
       '<input type="text" name="path" size="45" value=""/>'.
       $inPageWishlistlink3;
   
       # JavaScript-function to set title and path of ressource automatically
       # and show warning, if no title was set or path is invalid
       $popUp .= <<SCRIPT;
       <script type="text\/javascript">
       document.getElementsByName("title")[0].value = '$title';
       document.getElementsByName("path")[0].value = '$path';
       var fromwishlist = false;
       var titleget = '$title';
       if (!titleget) {
           fromwishlist = true;
       } 
       function newlinksubmit(){
       var title = document.getElementsByName("title")[0].value;
       var path = document.getElementsByName("path")[0].value;
       if (!title) {
           alert("$warningLink");
           return false;}
       var linkOK = (path.match(/\^http:(\\\/\\\/)/) || path.match(/\^https:(\\\/\\\/)/))
       && !(path.match(/\\.problem/) || path.match(/\\.exam/)
       || path.match(/\\.quiz/) || path.match(/\\.assess/)
       || path.match(/\\.survey/) || path.match(/\\.form/)
       || path.match(/\\.library/) || path.match(/\\.page/)
       || path.match(/\\.sequence/));
       if (!path.match(/\^(\\\/res\\\/)/) && !linkOK) {
           alert("$warningLinkNotAllowed1");
           return false;}
       if (fromwishlist) {
           window.close();
       }
       return true;}
       <\/script>
   SCRIPT
   
       $popUp .= $endPageWishlistlink;
   
       return $popUp;
   }
   
   sub makePopUpNewFolder {
       # Get all existing folders to offer posibility to create a new folder
       # into an existing folder
       my %TreeHashLink = &Apache::lonwishlist::getWishlist();
       my $rootLink = &Apache::Tree::HashToTree(\%TreeHashLink);
       my @childrenRtLink = $rootLink->children();
   
       $foldersOption = '';
       @allFolders = ();
       &getFoldersToArray(\@childrenRtLink);
       &getFoldersForOption(\@childrenRtLink);
   
       my $options = '<option value="" selected="selected">('.&mt('Top level').')</option>'.$foldersOption;
       $foldersOption = '';
       @allFolders = ();
   
       # HTML-Markup for the Pop-Up-window 'New Folder'
       my $startPageWishlistfolder = 
           &Apache::loncommon::start_page('New Folder',undef,
                                         {'only_body' => 1,
                                          'bgcolor'   => '#FFFFFF',});
   
       my $warningFolder = &mt('You must insert a title!');
   
   
       my $inPageNewFolder = '<h1>'.&mt('New Folder').'</h1>'.
                             '<form method="post" name="newfolder" action="/adm/wishlist" target="wishlist" '.
                             'onsubmit="return newfoldersubmit();" >'.
                             &Apache::lonhtmlcommon::start_pick_box().
                             &Apache::lonhtmlcommon::row_title(&mt('Folder title')).
                             '<input type="text" name="title" size="45" value="" /><br />'.
                             &Apache::lonhtmlcommon::row_closure().
                             &Apache::lonhtmlcommon::row_title(&mt('Note')).
                             '<textarea name="note" rows="3" cols="35" style="width:100%"></textarea><br />'.
                             &Apache::lonhtmlcommon::row_closure(1).
                             &Apache::lonhtmlcommon::end_pick_box().
                             '<br/><br/>'.
                             '<input type="submit" value="'.&mt('Save in').'" />'.
                             '<select name="folders">'.
                             $options.
                             '</select>'.
                             '<input type="button" value="'.&mt('Cancel').'" onclick="javascript:window.close();" />'.
                             '</form>';
       my $endPageWishlistfolder = &Apache::loncommon::end_page();
   
       my $popUp = $startPageWishlistfolder.
       $inPageNewFolder;
   
       $popUp .= <<SCRIPT;
       <script type="text\/javascript">
           function newfoldersubmit(){
               var title = document.getElementsByName("title")[0].value;
               if (!title) {
               alert("$warningFolder");
               return false;}
               else {
               window.close();
               return true;}}
       <\/script>
   SCRIPT
   
       $popUp .= $endPageWishlistfolder;
   
       return $popUp;
   }
   
 # Returns the HTML-Markup for the page, shown when a link was set  # Returns the HTML-Markup for the page, shown when a link was set
 sub makePageSet {  sub makePageSet {
     # start_page       # start_page 
Line 1415  sub makePageSet { Line 1766  sub makePageSet {
   
 # Returns the HTML-Markup for the page, shown when links should be imported into a course  # Returns the HTML-Markup for the page, shown when links should be imported into a course
 sub makePageImport {  sub makePageImport {
       my $rootgiven = shift;
       my $rat = shift;
   
       $root = $rootgiven;
       @childrenRt = $root->children();
     # start_page       # start_page 
     my $startPage = &Apache::loncommon::start_page('Wishlist',undef,      my $startPage = &Apache::loncommon::start_page('Wishlist',undef,
                                                    {'only_body' => 1});                                                     {'only_body' => 1});
           
     # get javascript-code for wishlist-interactions      # get javascript-code for wishlist-interactions
     my $js = &JSforWishlist();      my $js = &JSforWishlist();
       $js .= &JSforImport($rat);
   
     my $inner = '<h1>'.&mt('Import Resources from Wishlist').'</h1>';      my $inner = '<h1>'.&mt('Import Resources from Wishlist').'</h1>';
     $inner .= '<p><span class="LC_info">'.&mt("Please note that you  can use the checkboxes corresponding to a folder to ".      if (!$rat) {
                                               "easily check all links within this folder. The folder structure itself can't be imported. ".          $inner .= '<p><span class="LC_info">'.&mt("Please note that you  can use the checkboxes corresponding to a folder to ".
                                               "All checked links will be imported into the current folder of your course.").'</span></p>';                                                    "easily check all links within this folder. The folder structure itself can't be imported. ".
                                                     "All checked links will be imported into the current folder of your course.").'</span></p>';
       }
       else {
           $inner .= '<p><span class="LC_info">'.&mt("Please note that you  can use the checkboxes corresponding to a folder to ".
                                                     "easily check all links within this folder. The folder structure itself can't be imported. ")
                                                     .'</span></p>';
       }
     my %wishlist = &getWishlist();      my %wishlist = &getWishlist();
     my $fnum = (keys %wishlist)-1;  
       #FIXME Saved string containing all folders in wishlist.db-file (key 'folders') in first version of lonwishlist
       #After splitting lonwishlist into two modules, this is not necessary anymore. So, dependent from when the wishlist
       #was first called (i.e. when wishlist.db was created), there might be an entry 'folders' or not. Number of links in
       #wishlist.db depends on wether this entry exists or not...JW  
       my $fnum;
       if (defined $wishlist{'folders'}) {
           $fnum = (keys %wishlist)-2;
       }
       else {
           $fnum = (keys %wishlist)-1;
       }
   
     $inner .= '<form method="post" name="groupsort">'.      $inner .= '<form method="post" name="groupsort">'.
               '<input type="hidden" value="'.$fnum.'" name="fnum">'.                '<input type="hidden" value="'.$fnum.'" name="fnum">'.
Line 1468  sub makeErrorPage { Line 1842  sub makeErrorPage {
                 text => 'Wishlist'});                  text => 'Wishlist'});
     my $startPage = &Apache::loncommon::start_page('Wishlist');      my $startPage = &Apache::loncommon::start_page('Wishlist');
           
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Wishlist '.      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs(&mt('Wishlist').&Apache::loncommon::help_open_topic('Wishlist'));
                            '<a title="Online-Hilfe" href="/adm/help/Wishlist.hlp" target="_top">'.  
                            '<img src="/adm/help/help.png" alt="'.&mt('Help').'" '.  
                            'title="'.&mt('Help').'" class="LC_icon" /></a>');  
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
   
     # error-message      # error-message
Line 1486  sub makeErrorPage { Line 1857  sub makeErrorPage {
     return $page;      return $page;
 }  }
   
 # ----------------------------------------------------- Main Handler, package lonwishlist  
 sub handler {  
     my ($r) = @_;  
     &Apache::loncommon::content_type($r,'text/html');  
     $r->send_http_header;  
   
     if (&getWishlist() ne 'error') {  
         # get wishlist entries from user-data db-file and build a tree out of these entries  
         %TreeHash = &getWishlist();  
         $root = &Tree::HashToTree();  
         @childrenRt = $root->children();  
   
         # greate a new entry  
         if ($env{'form.title'}) {  
            &newEntry($env{'form.title'}, $env{'form.path'}, $env{'form.note'});  
         }  
   
         # get unprocessed_cgi (i.e. marked entries, mode ...)   
         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['action','mark','markedToMove','mode','newtitle','note']);  
   
         # change the order of entries within a level, that means sorting the entries  
         my $changeOrder = 0;  
         if (defined $env{'form.sel'}) {  
             my @sel = &Apache::loncommon::get_env_multiple('form.sel');  
             my $indexNode;  
             my $at;  
             for (my $s=0; $s<($#sel+1); $s++) {  
                 if ($sel[$s] ne '') {  
                     $indexNode = $s;  
                     $at = $sel[$s]-1;  
                 }  
             }  
             if ($at ne '') {  
                 $changeOrder = 1;  
                 &sortEntries($indexNode,$at);  
                 &saveChanges();  
             }  
         }  
   
         # get all marked (checkboxes) entries  # ----------------------------------------------------- package Tree
         my @marked = ();  # Extend CPAN-Module Tree by function like 'moveNode' or 'deleteNode'
         if (defined $env{'form.mark'}) {  package Apache::Tree;
             @marked = &Apache::loncommon::get_env_multiple('form.mark');  
         }  
   
         # move entries from one folder to another  
         if (defined $env{'form.markedToMove'}) {  
            my $markedToMove = $env{'form.markedToMove'};  
            my @ToMove = split(/\,/,$markedToMove);  
            my $moveTo = $env{'form.mark'};  
            if (defined $moveTo){   
                &moveEntries(\@ToMove,$moveTo);  
                &saveChanges();  
            }  
            $changeOrder = 1;  
       
         }  
   
         # delete entries  =pod
         if ($env{'form.action'} eq 'delete') {  
             &deleteEntries(\@marked);  =head2 Routines from package Tree
         }  
   =over 4
   
   =item * &getNodeByIndex(index, nodes)
   
        Searches for a node, specified by the index, in nodes (reference to array) and returns it. 
    
   
   =item * &moveNode(node, at, newParent)
   
        Moves a given node to a new parent (if new parents is defined) or change the position from a node within its siblings (means sorting, at must be defined).
   
   
   =item * &removeNode(node)
   
        Removes a node given by node from the tree.
   
   
   =item * &TreeIndex(children)
   
        Sets an index for every node in the tree, beginning with 0.
        Recursive call starting with all children of the root of the tree (parameter children is reference to an array containing the nodes of the current level).     
   
   
   =item * &setCountZero()
   
        Resets index counter.
   
   
   =item * &RootToHash(childrenRt)
   
        Converts the root-node to a hash-entry: the key is root and values are just the indices of root's children.
         
   
         # get all titles and notes and save them  =item * &TreeToHash(childrenRt)
         # only save, if user wants to save changes  
         # do not save, when current action is 'delete' or 'sort' or 'move'        Converts all other nodes in the tree to hash. Each node is one hash-entry where the keys are the index of a node and the values are all other attributes (containing tile, path, note, date and indices for all direct children).
         my @newTitles = ();       Recursive call starting with all children of the root of the tree (parameter childrenRT is reference to an array containing the nodes of the current level).     
         my @newPaths = ();  
         my @newNotes = ();  
         if ((defined $env{'form.newtitle'} || defined $env{'form.newpath'} || defined $env{'form.newnote'})  =item * &HashToTree()
             && ($env{'form.action'} ne 'noSave') && ($env{'form.action'} ne 'delete') && !$changeOrder) {  
             @newTitles = &Apache::loncommon::get_env_multiple('form.newtitle');       Converts the hash to a tree. Builds a tree-object for each entry in the hash. Afterwards call &buildTree(node, childrenIn, TreeNodes, TreeHash) to connect the tree-objects.
             @newPaths = &Apache::loncommon::get_env_multiple('form.newpath');  
             @newNotes = &Apache::loncommon::get_env_multiple('form.newnote');  
             my $node = 0;  =item * &buildTree(node, childrenIn, TreeNodes, TreeHash)
             foreach my $t (@newTitles) {  
                &setNewTitle($node, $t);       Joins the nodes to a tree.
                $node++;       Recursive call starting with root and all children of root (parameter childrenIn is reference to an array containing the nodes indices of the current level).
             }     
             $node = 0;  
             my $path = 0;  =back
             for (my $i = 0; $i < ($#newTitles+1); $i++ ) {  
                if (&setNewPath($node, $newPaths[$path])) {  =cut
                      $path++;  
                }  
                $node++;  
             }  
             $node = 0;  
             foreach my $n (@newNotes) {  
                &setNewNote($node, $n);  
                $node++;  
             }  
             &saveChanges();  
         }  
   
         # Create HTML-markup  
         my $page;  
         if ($env{'form.mode'} eq 'edit') {  
             $page = &makePage("edit");  
         }  
         elsif ($env{'form.mode'} eq 'move') {  
             $page = &makePage("move", \@marked);  
         }  
         elsif ($env{'form.mode'} eq 'import') {  
             $page = &makePageImport();  
         }  
         elsif ($env{'form.mode'} eq 'set') {  
             $page = &makePageSet();  
         }  
         else {  
             $page = &makePage("view");  
         }  
         @marked = ();  
         $r->print($page);  
     }  
     # An error occured, print an error-page  
     else {  
         my $errorPage = &makeErrorPage();  
         $r->print($errorPage);  
     }  
     return OK;  
 }  
   
 # ----------------------------------------------------- package Tree  
 # Extend CPAN-Module Tree by function like 'moveNode' or 'deleteNode'  
 package Tree;  
   
 # returns the node with a given index from a list of nodes  # returns the node with a given index from a list of nodes
 sub getNodeByIndex {  sub getNodeByIndex {
Line 1620  sub getNodeByIndex { Line 1927  sub getNodeByIndex {
     my $nodes = shift;      my $nodes = shift;
     my $found;      my $found;
           
     for my $n (@$nodes) {      foreach my $n (@$nodes) {
         my $curIndex = $n->value()->nindex();          my $curIndex = $n->value()->nindex();
         if ($n->value()->nindex() == $index) {          if ($curIndex == $index) {
             $found = $n;              $found = $n;
         }          }
     }      }
Line 1736  sub TreeToHash { Line 2043  sub TreeToHash {
 # build a tree-object for each entry in the hash  # build a tree-object for each entry in the hash
 # afterwards call &buildTree to connect the tree-objects  # afterwards call &buildTree to connect the tree-objects
 sub HashToTree {  sub HashToTree {
       my $TreeHash = shift;
     my @TreeNodes = ();      my @TreeNodes = ();
     my $root;      my $root;
   
     foreach my $key (keys %TreeHash) {      foreach my $key (keys %$TreeHash) {
         if ($key eq 'root') {          if ($key eq 'root') {
             $root = Tree->new("root");              $root = Tree->new("root");
         }          }
         else {          elsif ($key ne 'folders') {
         my @attributes = @{ $TreeHash{$key} };          my @attributes = @{ $$TreeHash{$key} };
         my $tmpNode;          my $tmpNode;
             $tmpNode = Tree->new(Entry->new(title=>$attributes[0],              $tmpNode = Tree->new(Entry->new(title=>$attributes[0],
                                             path=>$attributes[1],                                              path=>$attributes[1],
Line 1758  sub HashToTree { Line 2066  sub HashToTree {
         shift(@attributes);          shift(@attributes);
         shift(@attributes);          shift(@attributes);
         shift(@attributes);          shift(@attributes);
         $TreeHash{$key} = [ @attributes ];          $$TreeHash{$key} = [ @attributes ];
         }          }
     }      }
     # if there are nodes, build up the tree-structure      # if there are nodes, build up the tree-structure
     if (defined $TreeHash{'root'} && $TreeHash{'root'} ne '') {      if (defined $$TreeHash{'root'} && $$TreeHash{'root'} ne '') {
         my @childrenRtIn = @{ $TreeHash{'root'} };          my @childrenRtIn = @{ $$TreeHash{'root'} };
         &buildTree(\$root, \@childrenRtIn,\@TreeNodes,\%TreeHash);          &buildTree(\$root, \@childrenRtIn,\@TreeNodes,$TreeHash);
     }      }
     return $root;       return $root; 
 }  }

Removed from v.1.3  
changed lines
  Added in v.1.10


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