version 1.3, 2010/08/16 13:37:41
|
version 1.13, 2012/05/16 11:26:03
|
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 { |
my $startPagePopup = &Apache::loncommon::start_page('Wishlist',undef, |
my $startPagePopup = &Apache::loncommon::start_page('Stored Links',undef, |
{'only_body' => 1, |
{'only_body' => 1, |
'js_ready' => 1, |
'js_ready' => 1, |
'bgcolor' => '#FFFFFF',}); |
'bgcolor' => '#FFFFFF',}); |
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 929 sub wishlistView {
|
Line 1103 sub wishlistView {
|
|
|
# checkboxes |
# checkboxes |
$wishlistHTMLview .= '<td><input type="checkbox" name="mark" id="check'.$index.'" value="'.$index.'" '. |
$wishlistHTMLview .= '<td><input type="checkbox" name="mark" id="check'.$index.'" value="'.$index.'" '. |
'onclick="selectAction('."'row".$index."'".')"/></td>'; |
'onclick="selectAction('."'row".$index."'".')" /></td>'; |
|
|
# entry is a folder |
# entry is a folder |
if ($n->value()->path() eq '') { |
if ($n->value()->path() eq '') { |
Line 997 sub wishlistEdit {
|
Line 1171 sub wishlistEdit {
|
|
|
# checkboxes |
# checkboxes |
$wishlistHTMLedit .= '<td><input type="checkbox" name="mark" id="check'.$index.'" value="'.$index.'" '. |
$wishlistHTMLedit .= '<td><input type="checkbox" name="mark" id="check'.$index.'" value="'.$index.'" '. |
'onclick="selectAction('."'row".$index."'".')"/></td>'; |
'onclick="selectAction('."'row".$index."'".')" /></td>'; |
|
|
# option-tags for sorting entries. we need the numbers from 1 to n with n being the number of entries on the same level as the current entry. |
# option-tags for sorting entries. we need the numbers from 1 to n with n being the number of entries on the same level as the current entry. |
# set the number for the current entry into brackets |
# set the number for the current entry into brackets |
Line 1020 sub wishlistEdit {
|
Line 1194 sub wishlistEdit {
|
'<a href="javascript:;" onclick="folderAction('."'row".$index."'".')" style="vertical-align:top" >'. |
'<a href="javascript:;" onclick="folderAction('."'row".$index."'".')" style="vertical-align:top" >'. |
'<img src="/adm/lonIcons/arrow.closed.gif" id="img'.$index.'" alt = "" class="LC_icon"/>'. |
'<img src="/adm/lonIcons/arrow.closed.gif" id="img'.$index.'" alt = "" class="LC_icon"/>'. |
'<img src="/adm/lonIcons/navmap.folder.closed.gif" id="imgFolder'.$index.'" alt="folder"/></a>'. |
'<img src="/adm/lonIcons/navmap.folder.closed.gif" id="imgFolder'.$index.'" alt="folder"/></a>'. |
'<input type="text" name="newtitle" value="'.$n->value()->title().'" alt = "'.$n->value()->title().'"/>'. |
'<input type="text" name="newtitle" value="'.$n->value()->title().'" alt = "'.$n->value()->title().'" />'. |
'</td><td></td>'; |
'</td><td></td>'; |
|
|
} |
} |
Line 1030 sub wishlistEdit {
|
Line 1204 sub wishlistEdit {
|
$options.'</select></td>'. |
$options.'</select></td>'. |
'<td id="padd'.$index.'" style="padding-left:'.(($indent-$indentConst)<=0?$indentConst:$indent).'px;">'. |
'<td id="padd'.$index.'" style="padding-left:'.(($indent-$indentConst)<=0?$indentConst:$indent).'px;">'. |
'<img src="/res/adm/pages/wishlist-link.png" id="img'.$index.'" alt="link"/>'. |
'<img src="/res/adm/pages/wishlist-link.png" id="img'.$index.'" alt="link"/>'. |
'<input type="text" name="newtitle" value="'.$n->value()->title().'" alt = "'.$n->value()->title().'"/></td>'. |
'<input type="text" name="newtitle" value="'.$n->value()->title().'" alt = "'.$n->value()->title().'" /></td>'. |
'<td><input type="text" name="newpath" value="'.$n->value()->path().'" alt = "'.$n->value()->path().'"/></td>'; |
'<td><input type="text" name="newpath" value="'.$n->value()->path().'" alt = "'.$n->value()->path().'" /></td>'; |
} |
} |
|
|
# note-icon, different icons for an entries with note and those without |
# note-icon, different icons for an entries with note and those without |
Line 1174 sub wishlistImport {
|
Line 1348 sub wishlistImport {
|
# checkboxes |
# checkboxes |
$wishlistHTMLimport .= '<td>'. |
$wishlistHTMLimport .= '<td>'. |
'<input type="checkbox" name="check" id="check'.$index.'" value="'.$index.'" '. |
'<input type="checkbox" name="check" id="check'.$index.'" value="'.$index.'" '. |
'onclick="selectAction('."'row".$index."'".')"/>'. |
'onclick="selectAction('."'row".$index."'".')" />'. |
'<input type="hidden" name="title'.$index.'" value="'.&escape($n->value()->title()).'">'. |
'<input type="hidden" name="title'.$index.'" value="'.&escape($n->value()->title()).'" />'. |
'<input type="hidden" name="filelink'.$index.'" value="'.&escape($n->value()->path()).'">'. |
'<input type="hidden" name="filelink'.$index.'" value="'.&escape($n->value()->path()).'" />'. |
'<input type="hidden" name="id'.$index.'">'. |
'<input type="hidden" name="id'.$index.'" />'. |
'</td>'; |
'</td>'; |
|
|
# entry is a folder |
# entry is a folder |
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( |
{ href => '/adm/wishlist?mode='.$mode, |
{ href => '/adm/wishlist?mode='.$mode, |
text => 'Wishlist'}); |
text => 'Stored Links'}); |
my $startPage = &Apache::loncommon::start_page('Wishlist',undef, |
my $startPage = &Apache::loncommon::start_page('Stored Links',undef, |
{'add_entries' => { |
{'add_entries' => { |
'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('Stored Links').&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 1322 sub makePage {
|
Line 1497 sub makePage {
|
|
|
# start form |
# start form |
my $inner .= '<form name="list" action ="/adm/wishlist" method="post">'. |
my $inner .= '<form name="list" action ="/adm/wishlist" method="post">'. |
'<input type="hidden" id="action" name="action" value=""/>'; |
'<input type="hidden" id="action" name="action" value="" />'; |
|
|
# only display subbox in view- or edit-mode |
# only display subbox in view- or edit-mode |
if ($mode eq 'view' || $mode eq 'edit') { |
if ($mode eq 'view' || $mode eq 'edit') { |
Line 1338 sub makePage {
|
Line 1513 sub makePage {
|
$inner .= &Apache::loncommon::end_data_table(); |
$inner .= &Apache::loncommon::end_data_table(); |
} |
} |
else { |
else { |
$inner .= '<span class="LC_info">'.&mt("Your wishlist ist currently empty.").'</span>'; |
$inner .= '<span class="LC_info">'.&mt("Your Stored Links list is currently empty.").'</span>'; |
} |
} |
$wishlistHTMLedit = ''; |
$wishlistHTMLedit = ''; |
} |
} |
Line 1348 sub makePage {
|
Line 1523 sub makePage {
|
$inner .= '<table class="LC_data_table LC_tableOfContent">'.$wishlistHTMLview.'</table>'; |
$inner .= '<table class="LC_data_table LC_tableOfContent">'.$wishlistHTMLview.'</table>'; |
} |
} |
else { |
else { |
$inner .= '<span class="LC_info">'.&mt("Your wishlist ist currently empty.").'</span>'; |
$inner .= '<span class="LC_info">'.&mt("Your Stored Links list is currently empty.").'</span>'; |
} |
} |
$wishlistHTMLview = ''; |
$wishlistHTMLview = ''; |
} |
} |
Line 1359 sub makePage {
|
Line 1534 sub makePage {
|
} |
} |
if ($markStr) { |
if ($markStr) { |
$markStr = substr($markStr, 0, length($markStr)-1); |
$markStr = substr($markStr, 0, length($markStr)-1); |
$inner .= '<input type="hidden" value="'.$markStr.'" name="markedToMove"/>'; |
$inner .= '<input type="hidden" value="'.$markStr.'" name="markedToMove" />'; |
$inner .= '<p><span class="LC_info">'.&mt('You have selected the red marked entries to be moved to another folder. '. |
$inner .= '<p><span class="LC_info">'.&mt('You have selected the red marked entries to be moved to another folder. '. |
'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>'. |
'<td>'.&mt('Top level').'</td><td></td></tr>'; |
'<td>'.&mt('Top level').'</td><td></td></tr>'; |
} |
} |
else { |
else { |
$inner .= '<p><span class="LC_info">'.&mt("You haven't marked any entry to move.").'</span></p>'. |
$inner .= '<p><span class="LC_info">'.&mt("You haven't marked any entry to move.").'</span></p>'. |
'<input type="button" value="'.&mt('Back').'" onclick="go('."'/adm/wishlist'".')"/>'; |
'<input type="button" value="'.&mt('Back').'" onclick="go('."'/adm/wishlist'".')" />'; |
} |
} |
} |
} |
|
|
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('Save to Stored Links',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('Save to Stored Links').'</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 |
my $startPage = &Apache::loncommon::start_page('Wishlist',undef, |
my $startPage = &Apache::loncommon::start_page('Stored Links',undef, |
{'only_body' => 1}); |
{'only_body' => 1}); |
|
|
# confirm success and offer link to wishlist |
# confirm success and offer link to wishlist |
my $message = &Apache::lonhtmlcommon::confirm_success(&mt('Link successfully set!')); |
my $message = &Apache::lonhtmlcommon::confirm_success(&mt('Link successfully saved!')); |
$message = &Apache::loncommon::confirmwrapper($message); |
$message = &Apache::loncommon::confirmwrapper($message); |
|
|
my $inner .= '<br>'.$message.'<br/><br/>'. |
my $inner .= '<br>'.$message.'<br/><br/>'. |
'<a href="javascript:;" onclick="opener.open('."'/adm/wishlist'".');window.close();">'.&mt('Go to wishlist').'</a>'. |
'<a href="javascript:;" onclick="opener.open('."'/adm/wishlist'".');window.close();">'.&mt('Go to Stored Links').'</a>'.(' ' x 3). |
' <a href="javascript:;" onclick="window.close();">'.&mt('Close this window').'</a>'; |
'<a href="javascript:;" onclick="window.close();">'.&mt('Close this window').'</a>'; |
|
|
# end_page |
# end_page |
my $endPage = &Apache::loncommon::end_page(); |
my $endPage = &Apache::loncommon::end_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('Stored Links',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 Stored Links').'</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; |
|
|
|
$inner .= '<form method="post" name="groupsort">'. |
#FIXME Saved string containing all folders in wishlist.db-file (key 'folders') in first version of lonwishlist |
'<input type="hidden" value="'.$fnum.'" name="fnum">'. |
#After splitting lonwishlist into two modules, this is not necessary anymore. So, dependent from when the wishlist |
'<input type="button" onclick="javascript:checkAll()" id="checkallbutton" value="'.&mt('Check All').'">'. |
#was first called (i.e. when wishlist.db was created), there might be an entry 'folders' or not. Number of links in |
'<input type="button" onclick="javascript:uncheckAll()" id="uncheckallbutton" value="'.&mt('Uncheck All').'">'. |
#wishlist.db depends on wether this entry exists or not...JW |
'<input type="button" value="'.&mt('Import Checked').'" onclick="finish_import();">'. |
my $fnum; |
'<input type="button" value="'.&mt('Cancel').'" onclick="window.close();"><br/><br/>'; |
if (defined $wishlist{'folders'}) { |
|
$fnum = (keys %wishlist)-2; |
|
} |
|
else { |
|
$fnum = (keys %wishlist)-1; |
|
} |
|
|
|
$inner .= '<form method="post" name="groupsort" action="">'. |
|
'<input type="hidden" value="'.$fnum.'" name="fnum" />'. |
|
'<input type="button" onclick="javascript:checkAll()" id="checkallbutton" value="'.&mt('Check All').'" />'. |
|
'<input type="button" onclick="javascript:uncheckAll()" id="uncheckallbutton" value="'.&mt('Uncheck All').'" />'. |
|
'<input type="button" value="'.&mt('Import Checked').'" onclick="finish_import();" />'. |
|
'<input type="button" value="'.&mt('Cancel').'" onclick="window.close();" /><br/><br/>'; |
|
|
|
|
# wishlist-table |
# wishlist-table |
Line 1444 sub makePageImport {
|
Line 1818 sub makePageImport {
|
$inner .= '<table class="LC_data_table LC_tableOfContent">'.$wishlistHTMLimport.'</table>'; |
$inner .= '<table class="LC_data_table LC_tableOfContent">'.$wishlistHTMLimport.'</table>'; |
} |
} |
else { |
else { |
$inner .= '<span class="LC_info">'.&mt("Your wishlist ist currently empty.").'</span>'; |
$inner .= '<span class="LC_info">'.&mt("Your Stored Links list is currently empty.").'</span>'; |
} |
} |
$wishlistHTMLimport = ''; |
$wishlistHTMLimport = ''; |
|
|
Line 1466 sub makeErrorPage {
|
Line 1840 sub makeErrorPage {
|
&Apache::lonhtmlcommon::add_breadcrumb( |
&Apache::lonhtmlcommon::add_breadcrumb( |
{ href => '/adm/wishlist', |
{ href => '/adm/wishlist', |
text => 'Wishlist'}); |
text => 'Wishlist'}); |
my $startPage = &Apache::loncommon::start_page('Wishlist'); |
my $startPage = &Apache::loncommon::start_page('Stored Links'); |
|
|
my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Wishlist '. |
my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs(&mt('Stored Links').&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; |
} |
} |