Index: extensions/BatchDownloader/download.php
===================================================================
--- extensions/BatchDownloader/download.php	(revision 16598)
+++ extensions/BatchDownloader/download.php	(revision 16609)
@@ -3,20 +3,27 @@
 include(PHPWG_ROOT_PATH.'include/common.inc.php');
 
-// check_status(ACCESS_CLASSIC);
+check_status(ACCESS_CLASSIC);
 
-$BatchDownloader = new BatchDownloader($_GET['set_id']);
-$file = $BatchDownloader->getArchivePath();
+try {
+  $BatchDownloader = new BatchDownloader($_GET['set_id']);
+  $file = $BatchDownloader->getArchivePath();
 
-header('Content-Type: application/force-download; name="'.basename($file).'"');
-header('Content-Disposition: attachment; filename="'.basename($file).'"');
-header('Content-Description: File Transfer');
-header('Content-Transfer-Encoding: binary');
-header('Content-Length: '.filesize($file).'');
+  header('Content-Type: application/force-download; name="'.basename($file).'"');
+  header('Content-Disposition: attachment; filename="'.basename($file).'"');
+  header('Content-Description: File Transfer');
+  header('Content-Transfer-Encoding: binary');
+  header('Content-Length: '.filesize($file).'');
 
-header('Cache-Control: no-cache, must-revalidate');
-header('Pragma: no-cache');
-header('Expires: 0');
+  header('Cache-Control: no-cache, must-revalidate');
+  header('Pragma: no-cache');
+  header('Expires: 0');
 
-readfile($file);
+  readfile($file);
+}
+catch (Exception $e)
+{
+  echo $e->getMessage();
+}
+    
 exit(0);
 
Index: extensions/BatchDownloader/include/BatchDownloader.class.php
===================================================================
--- extensions/BatchDownloader/include/BatchDownloader.class.php	(revision 16598)
+++ extensions/BatchDownloader/include/BatchDownloader.class.php	(revision 16609)
@@ -95,5 +95,5 @@
       else
       {
-        trigger_error('BatchDownloader::__construct, invalid set id', E_USER_ERROR);
+        throw new Exception(l10n('Invalid dowload set'));
       }
     }
@@ -270,5 +270,5 @@
   function createNextArchive($force_one_archive=false)
   {
-    // set already downloaded
+    // set already downloaded (we should never be there !)
     if ( $this->data['status'] == 'done' or $this->data['nb_images'] == 0 )
     {
Index: extensions/BatchDownloader/include/download.inc.php
===================================================================
--- extensions/BatchDownloader/include/download.inc.php	(revision 16598)
+++ extensions/BatchDownloader/include/download.inc.php	(revision 16609)
@@ -13,48 +13,52 @@
     $template->set_filename('index', dirname(__FILE__) . '/../template/init_zip.tpl');
     
-    $BatchDownloader = new BatchDownloader($_GET['set_id']);
-    
-    if ( isset($_GET['cancel']) )
+    try
     {
-      $BatchDownloader->deleteLastArchive();
-      $BatchDownloader->clearImages();
-      pwg_query('DELETE FROM '.BATCH_DOWNLOAD_TSETS.' WHERE id = '.$_GET['set_id'].';');
-      $_SESSION['page_infos'][] = l10n('Download set deleted');
-      redirect('index.php');
-    }
-    
-    if ( isset($_GET['zip']) and $BatchDownloader->getParam('status') != 'done' and $_GET['zip'] > $BatchDownloader->getParam('last_zip') )
-    {
-      $BatchDownloader->deleteLastArchive();
-      $next_file = $BatchDownloader->createNextArchive();
-    }
+      $BatchDownloader = new BatchDownloader($_GET['set_id']);
+      
+      if ( isset($_GET['cancel']) )
+      {
+        $BatchDownloader->deleteLastArchive();
+        $BatchDownloader->clearImages();
+        pwg_query('DELETE FROM '.BATCH_DOWNLOAD_TSETS.' WHERE id = '.$_GET['set_id'].';');
+        $_SESSION['page_infos'][] = l10n('Download set deleted');
+        redirect('index.php');
+      }
+      
+      if ( isset($_GET['zip']) and $BatchDownloader->getParam('status') != 'done' and $_GET['zip'] > $BatchDownloader->getParam('last_zip') )
+      {
+        $BatchDownloader->deleteLastArchive();
+        $next_file = $BatchDownloader->createNextArchive();
+      }
 
-    $set = $BatchDownloader->getSetInfo();
-    
-    if (isset($next_file))
-    {
-      $set['U_DOWNLOAD'] = BATCH_DOWNLOAD_PATH . 'download.php?set_id='.$_GET['set_id'].'&amp;zip='.$_GET['zip'];
-      array_push($page['infos'], sprintf(l10n('The archive is downloading, if the download doesn\'t start automatically please <a href="%s">click here</a>'), $set['U_DOWNLOAD']));
-    }
-    
-    if ($BatchDownloader->getParam('nb_images') > $conf['batch_download']['max_elements'])
-    {
-      $template->assign('elements_error', sprintf(
-        l10n('You choose to download %d pictures, but the system is limited to %d. You can edit the set, or the last %d pictures will not be downloaded.'),
-        $BatchDownloader->getParam('nb_images'),
-        $conf['batch_download']['max_elements'],
-        $BatchDownloader->getParam('nb_images') - $conf['batch_download']['max_elements']
+      $set = $BatchDownloader->getSetInfo();
+      
+      if (isset($next_file))
+      {
+        $set['U_DOWNLOAD'] = BATCH_DOWNLOAD_PATH . 'download.php?set_id='.$_GET['set_id'].'&amp;zip='.$_GET['zip'];
+        array_push($page['infos'], sprintf(l10n('The archive is downloading, if the download doesn\'t start automatically please <a href="%s">click here</a>'), $set['U_DOWNLOAD']));
+      }
+      
+      if ($BatchDownloader->getParam('nb_images') > $conf['batch_download']['max_elements'])
+      {
+        $template->assign('elements_error', sprintf(
+          l10n('You choose to download %d pictures, but the system is limited to %d. You can edit the set, or the last %d pictures will not be downloaded.'),
+          $BatchDownloader->getParam('nb_images'),
+          $conf['batch_download']['max_elements'],
+          $BatchDownloader->getParam('nb_images') - $conf['batch_download']['max_elements']
+          ));
+      }
+      
+      $set['U_CANCEL'] = BATCH_DOWNLOAD_PUBLIC . 'init_zip&amp;set_id='.$_GET['set_id'].'&amp;cancel';
+      
+      $template->assign(array(
+        'set' => $set,
+        'archive_timeout' => $conf['batch_download']['archive_timeout'],
         ));
     }
-    
-    if ($BatchDownloader->getParam('status') == 'new')
+    catch (Exception $e)
     {
-      $set['U_CANCEL'] = BATCH_DOWNLOAD_PUBLIC . 'init_zip&amp;set_id='.$_GET['set_id'].'&amp;cancel';
+      array_push($page['errors'], $e->getMessage());
     }
-    
-    $template->assign(array(
-      'set' => $set,
-      'archive_timeout' => $conf['batch_download']['archive_timeout'],
-      ));
     
     break;
@@ -71,39 +75,47 @@
       'U_VIEW' => $self_url,
       'U_INIT_ZIP' => BATCH_DOWNLOAD_PUBLIC . 'init_zip&amp;set_id='.$_GET['set_id'],
+      'SET_ID' => $_GET['set_id'],
       ));
     
-    $BatchDownloader = new BatchDownloader($_GET['set_id']);
-    
-    if ($BatchDownloader->getParam('status') != 'new')
+    try
     {
-      array_push($page['errors'], l10n('You can not edit this set'));
-      break;
+      $BatchDownloader = new BatchDownloader($_GET['set_id']);
+      
+      if ($BatchDownloader->getParam('status') != 'new')
+      {
+        array_push($page['errors'], l10n('You can not edit this set'));
+        break;
+      }
+      
+      if ( isset($_GET['remove']) and preg_match('#^[0-9]+$#', $_GET['remove']) )
+      {
+        $BatchDownloader->removeImages(array($_GET['remove']));
+      }
+      
+      $template->assign('set', $BatchDownloader->getSetInfo());
+      
+      $template->set_prefilter('index_thumbnails', 'batch_download_thumbnails_list_prefilter');
+      
+      $page['start'] = isset($_GET['start']) ? $_GET['start'] : 0;
+      $page['items'] = array_keys($BatchDownloader->getImages());
+      
+      if (count($page['items']) > $page['nb_image_page'])
+      {
+        $page['navigation_bar'] = create_navigation_bar(
+          $self_url,
+          count($page['items']),
+          $page['start'],
+          $page['nb_image_page'],
+          false
+          );
+        $template->assign('navbar', $page['navigation_bar']);
+      }
+      
+      include(PHPWG_ROOT_PATH . 'include/category_default.inc.php');
     }
-    
-    if ( isset($_GET['remove']) and preg_match('#^[0-9]+$#', $_GET['remove']) )
+    catch (Exception $e)
     {
-      $BatchDownloader->removeImages(array($_GET['remove']));
+      array_push($page['errors'], $e->getMessage());
     }
-    
-    $template->assign('set', $BatchDownloader->getSetInfo());
-    
-    $template->set_prefilter('index_thumbnails', 'batch_download_thumbnails_list_prefilter');
-    
-    $page['start'] = isset($_GET['start']) ? $_GET['start'] : 0;
-    $page['items'] = array_keys($BatchDownloader->getImages());
-    
-    if (count($page['items']) > $page['nb_image_page'])
-    {
-      $page['navigation_bar'] = create_navigation_bar(
-        $self_url,
-        count($page['items']),
-        $page['start'],
-        $page['nb_image_page'],
-        false
-        );
-      $template->assign('navbar', $page['navigation_bar']);
-    }
-    
-    include(PHPWG_ROOT_PATH . 'include/category_default.inc.php');
     
     break;
@@ -116,11 +128,44 @@
 function batch_download_thumbnails_list_prefilter($content, &$smarty)
 {
-  $search = '<span class="thumbName">';
+  // custom style
+  $search[0] = '{/html_style}';
+  $replace[0] = '.thumbnails  .wrap1 {ldelim} position:relative; }
+.removeSet {ldelim} width:100%;height:16px;display:none;position:absolute;top:0;background:rgba(0,0,0,0.8);padding:2px;border-radius:2px;font-size:0.8em; }
+.wrap1:hover .removeSet {ldelim} display:block; }'
+.$search[0];
+
+  // links
+  $search[1] = '<span class="wrap1">';
+  $replace[1] = $search[1].'
+{strip}<a class="removeSet" href="{$U_VIEW}&amp;remove={$thumbnail.id}" data-id="{$thumbnail.id}" rel="nofollow">
+{\'Remove from download set\'|@translate}&nbsp;<img src="{$BATCH_DOWNLOAD_PATH}template/image_delete.png" title="{\'Remove from download set\'|@translate}">
+</a>{/strip}';
+
+  // AJAX request
+  $search[2] = '{/html_style}';
+  $replace[2] = $search[2].'
+{footer_script require=\'jquery\'}
+jQuery(".removeSet").click(function() {ldelim}
+  var toggle_id = jQuery(this).data("id");
+  var $trigger = jQuery(this);
   
-  $add = '<a href="{$U_VIEW}&amp;remove={$thumbnail.id}" rel="nofollow">
-<img src="{$BATCH_DOWNLOAD_PATH}template/image_delete.png" title="{\'Remove from download set\'|@translate}">
-</a>&nbsp;';
+  jQuery.ajax({ldelim}
+    type: "POST",
+    url: "{$BATCH_DOWNLOAD_PATH}remove_image.php",
+    data: {ldelim} "set_id": "{$SET_ID}", "toggle_id": toggle_id }
+  }).done(function(msg) {ldelim}
+    if (msg == "false") {ldelim}
+      $trigger.parent(".wrap1").hide("fast", function() {ldelim} $trigger.remove() });
+      jQuery(".nbImages").html(jQuery(".nbImages").html() -1);
+    } else {ldelim}
+      $trigger.html(\'{\'Un unknown error occured\'|@translate}\');
+    }
+  });
+  
+  return false;
+});
+{/footer_script}';
 
-  return str_replace($search, $search.$add, $content);
+  return str_replace($search, $replace, $content);
 }
 
Index: extensions/BatchDownloader/include/events.inc.php
===================================================================
--- extensions/BatchDownloader/include/events.inc.php	(revision 16598)
+++ extensions/BatchDownloader/include/events.inc.php	(revision 16609)
@@ -24,5 +24,5 @@
     
     $page['section'] = 'download';
-    $page['title'] = l10n('Batch Downloader').$conf['level_separator'].' ';
+    $page['title'] = '<a href="'.get_absolute_root_url().'">'.l10n('Home').'</a>'.$conf['level_separator'].l10n('Batch Downloader').$conf['level_separator'];
     
     switch (@$tokens[1])
@@ -164,5 +164,5 @@
       array_push($data, array(
         'URL' => BATCH_DOWNLOAD_PUBLIC . 'init_zip&amp;set_id='.$BatchDownloader->getParam('set_id'),
-        'TITLE' => strip_tags($set['COMMENT']),
+        'TITLE' => str_replace('"', "'", strip_tags($set['COMMENT'])),
         'NAME' => $set['sNAME'],
         'COUNT' => $set['NB_IMAGES'],
Index: extensions/BatchDownloader/language/en_UK/plugin.lang.php
===================================================================
--- extensions/BatchDownloader/language/en_UK/plugin.lang.php	(revision 16598)
+++ extensions/BatchDownloader/language/en_UK/plugin.lang.php	(revision 16609)
@@ -6,5 +6,5 @@
 $lang['Random'] = 'Random';
 $lang['User collection'] = 'User collection';
-$lang['Nb images'] = 'Nb images';
+$lang['Nb images'] = 'Nb photos';
 $lang['Nb archives'] = 'Nb archives';
 $lang['Total size'] = 'Total size';
@@ -32,4 +32,5 @@
 $lang['Cancel this set'] = 'Cancel this set';
 $lang['Download info'] = 'Download info';
+$lang['Estimated size'] = 'Estimated size';
 $lang['Estimated number of archives'] = 'Estimated number of archives';
 $lang['real number of archives can differ'] = 'real number of archives can differ';
Index: extensions/BatchDownloader/language/fr_FR/plugin.lang.php
===================================================================
--- extensions/BatchDownloader/language/fr_FR/plugin.lang.php	(revision 16598)
+++ extensions/BatchDownloader/language/fr_FR/plugin.lang.php	(revision 16609)
@@ -32,4 +32,5 @@
 $lang['Cancel this set'] = 'Annuler ce lot';
 $lang['Download info'] = 'Informations sur le téléchargement';
+$lang['Estimated size'] = 'Taille estimée';
 $lang['Estimated number of archives'] = 'Nombre estimé d\'archives';
 $lang['real number of archives can differ'] = 'le nombre réel d\'archives peut différer';
Index: extensions/BatchDownloader/remove_image.php
===================================================================
--- extensions/BatchDownloader/remove_image.php	(revision 16609)
+++ extensions/BatchDownloader/remove_image.php	(revision 16609)
@@ -0,0 +1,25 @@
+<?php
+define('PHPWG_ROOT_PATH', '../../');
+include(PHPWG_ROOT_PATH.'include/common.inc.php');
+
+check_status(ACCESS_CLASSIC);
+
+if (isset($_POST['set_id']) and isset($_POST['toggle_id']))
+{
+  try
+  {
+    $BatchDownloader = new BatchDownloader($_POST['set_id']);
+    $BatchDownloader->removeImages(array($_POST['toggle_id']));
+    echo "false";
+  }
+  catch (Exception $e)
+  {
+    echo 'error';
+  }
+}
+else
+{
+  echo 'error';
+}
+
+?>
Index: extensions/BatchDownloader/template/init_zip.tpl
===================================================================
--- extensions/BatchDownloader/template/init_zip.tpl	(revision 16598)
+++ extensions/BatchDownloader/template/init_zip.tpl	(revision 16609)
@@ -20,4 +20,5 @@
 
 
+{if $set}
 <fieldset>
   <legend>{'Download info'|@translate}</legend>
@@ -27,13 +28,10 @@
   <ul class="set-infos">
     <li class="error">{$elements_error}</li>
-    <li><b>{'%d images'|@translate|@sprintf:$set.NB_IMAGES}</b>{if $set.U_EDIT_SET}, <a href="{$set.U_EDIT_SET}" rel="nofollow">{'Edit the set'|@translate}</a>{/if}</li>
+    <li><b>{'%d photos'|@translate|@sprintf:$set.NB_IMAGES}</b>{if $set.U_EDIT_SET}, <a href="{$set.U_EDIT_SET}" rel="nofollow">{'Edit the set'|@translate}</a>{/if}</li>
     <li><b>{'Estimated size'|@translate}:</b> {$set.TOTAL_SIZE} MB</li>
     <li><b>{'Estimated number of archives'|@translate}:</b> {$set.NB_ARCHIVES} <i>({'real number of archives can differ'|@translate})</i></li>
     <li><b>{'Created on'|@translate}:</b> {$set.DATE_CREATION}</li>
   </ul>
-  
-  
 </fieldset>
-
 
 <fieldset>
@@ -45,6 +43,7 @@
   </ul>
   
-  {if $set.U_CANCEL}<a href="{$set.U_CANCEL}" class="cancel-down" onClick="return confirm('{'Are you sure?'|@translate}');">{'Cancel this download'|@translate}</a>{/if}
+  <a href="{$set.U_CANCEL}" class="cancel-down" onClick="return confirm('{'Are you sure?'|@translate}');">{'Cancel this download'|@translate}</a>
 </fieldset>
+{/if}
 
 </div>{* <!-- content --> *}
Index: extensions/BatchDownloader/template/view.tpl
===================================================================
--- extensions/BatchDownloader/template/view.tpl	(revision 16598)
+++ extensions/BatchDownloader/template/view.tpl	(revision 16609)
@@ -14,5 +14,5 @@
   <h3>{$set.NAME}</h3>
   {if $set.COMMENT}<blockquote>{$set.COMMENT}</blockquote>{/if}
-  <span>{'%d images'|@translate|@sprintf:$set.NB_IMAGES}</span>
+  {'Nb images'|@translate}: <span class="nbImages">{$set.NB_IMAGES}</span>
 </p>
 
