Index: /trunk/admin.php
===================================================================
--- /trunk/admin.php	(revision 5142)
+++ /trunk/admin.php	(revision 5143)
@@ -124,4 +124,5 @@
     'U_CONFIG_EXTENTS'=> $link_start.'extend_for_templates',
     'U_CONFIG_MENUBAR'=> $link_start.'menubar',
+    'U_CONFIG_THEMES'=> $link_start.'themes_new',
     'U_CATEGORIES'=> $link_start.'cat_list',
     'U_MOVE'=> $link_start.'cat_move',
Index: /trunk/admin/include/plugins.class.php
===================================================================
--- /trunk/admin/include/plugins.class.php	(revision 5142)
+++ /trunk/admin/include/plugins.class.php	(revision 5143)
@@ -269,12 +269,18 @@
    * Retrieve PEM server datas to $server_plugins
    */
-  function get_server_plugins($new=false)
+  function get_server_plugins($new=false, $ext_type='plugin')
   {
     global $user;
+
+    $pem_category_id = 12;
+    if ('theme' == $ext_type)
+    {
+      $pem_category_id = 10;
+    }
 
     // Retrieve PEM versions
     $version = PHPWG_VERSION;
     $versions_to_check = array();
-    $url = PEM_URL . '/api/get_version_list.php?category_id=12&format=php';
+    $url = PEM_URL . '/api/get_version_list.php?category_id='.$pem_category_id.'&format=php';
     if (fetchRemote($url, $result) and $pem_versions = @unserialize($result))
     {
@@ -308,5 +314,5 @@
 
     // Retrieve PEM plugins infos
-    $url = PEM_URL . '/api/get_revision_list.php?category_id=12&format=php&last_revision_only=true';
+    $url = PEM_URL . '/api/get_revision_list.php?category_id='.$pem_category_id.'&format=php&last_revision_only=true';
     $url .= '&version=' . implode(',', $versions_to_check);
     $url .= '&lang=' . substr($user['language'], 0, 2);
@@ -365,7 +371,22 @@
     * @param string - plugin id or extension id
    */
-  function extract_plugin_files($action, $revision, $dest)
-  {
-    if ($archive = tempnam( PHPWG_PLUGINS_PATH, 'zip'))
+  function extract_plugin_files($action, $revision, $dest, $ext_type = 'plugin')
+  {
+    if ('plugin' == $ext_type)
+    {
+      $install_basedir = PHPWG_PLUGINS_PATH;
+      $main_filename = 'main.inc.php';
+    }
+    elseif ('theme' == $ext_type)
+    {
+      $install_basedir = PHPWG_ROOT_PATH.'themes/';
+      $main_filename = 'themeconf.inc.php';
+    }
+    else
+    {
+      fatal_error('unknown extension type "'.$ext_type.'"');
+    }
+    
+    if ($archive = tempnam( $install_basedir, 'zip'))
     {
       $url = PEM_URL . '/download.php?rid=' . $revision;
@@ -382,5 +403,5 @@
           {
             // we search main.inc.php in archive
-            if (basename($file['filename']) == 'main.inc.php'
+            if (basename($file['filename']) == $main_filename
               and (!isset($main_filepath)
               or strlen($file['filename']) < strlen($main_filepath)))
@@ -394,9 +415,9 @@
             if ($action == 'upgrade')
             {
-              $extract_path = PHPWG_PLUGINS_PATH . $dest;
+              $extract_path = $install_basedir . $dest;
             }
             else
             {
-              $extract_path = PHPWG_PLUGINS_PATH
+              $extract_path = $install_basedir
                   . ($root == '.' ? 'extension_' . $dest : basename($root));
             }
Index: /trunk/admin/themes/default/template/admin.tpl
===================================================================
--- /trunk/admin/themes/default/template/admin.tpl	(revision 5142)
+++ /trunk/admin/themes/default/template/admin.tpl	(revision 5143)
@@ -23,4 +23,5 @@
         <li><a href="{$U_CONFIG_MENUBAR}">{'Menu'|@translate}</a></li>
         <li><a href="{$U_CONFIG_EXTENTS}">{'Templates'|@translate}</a></li>
+        <li><a href="{$U_CONFIG_THEMES}">{'Themes'|@translate}</a></li>
       </ul>
     </dd>
Index: /trunk/admin/themes/default/template/themes_new.tpl
===================================================================
--- /trunk/admin/themes/default/template/themes_new.tpl	(revision 5143)
+++ /trunk/admin/themes/default/template/themes_new.tpl	(revision 5143)
@@ -0,0 +1,13 @@
+<div class="titrePage">
+  <h2>{'Install New Theme'|@translate}</h2>
+</div>
+
+{if isset($themes)}
+<ul>
+{foreach from=$new_themes item=theme name=themes_loop}
+  <li>
+    <img src="{$theme.src}"> {$theme.name} <a href="{$theme.install_url}">Install</a>
+  </li>
+{/foreach}
+</ul>
+{/if}
Index: /trunk/admin/themes_new.php
===================================================================
--- /trunk/admin/themes_new.php	(revision 5143)
+++ /trunk/admin/themes_new.php	(revision 5143)
@@ -0,0 +1,133 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
+
+$base_url = get_root_url().'admin.php?page='.$page['page'];
+
+$themes = new plugins();
+
+// +-----------------------------------------------------------------------+
+// |                           setup check                                 |
+// +-----------------------------------------------------------------------+
+
+$themes_dir = PHPWG_ROOT_PATH.'themes';
+if (!is_writable($themes_dir))
+{
+  array_push(
+    $page['errors'],
+    sprintf(
+      l10n('Add write access to the "%s" directory'),
+      'themes'
+      )
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                       perform installation                            |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['revision']) and isset($_GET['extension']) and !is_adviser())
+{
+  $install_status = $themes->extract_plugin_files(
+    'install',
+    $_GET['revision'],
+    $_GET['extension'],
+    'theme'
+    );
+  
+  redirect($base_url.'&installstatus='.$install_status);
+}
+
+// +-----------------------------------------------------------------------+
+// |                        installation result                            |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['installstatus']))
+{
+  switch ($_GET['installstatus'])
+  {
+    case 'ok':
+      array_push(
+        $page['infos'],
+        l10n('Theme has been successfully installed')
+        );
+      break;
+
+    case 'temp_path_error':
+      array_push($page['errors'], l10n('Can\'t create temporary file.'));
+      break;
+
+    case 'dl_archive_error':
+      array_push($page['errors'], l10n('Can\'t download archive.'));
+      break;
+
+    case 'archive_error':
+      array_push($page['errors'], l10n('Can\'t read or extract archive.'));
+      break;
+
+    default:
+      array_push(
+        $page['errors'],
+        sprintf(l10n('An error occured during extraction (%s).'), $_GET['installstatus'])
+        );
+  }  
+}
+
+// +-----------------------------------------------------------------------+
+// |                          template output                              |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('themes' => 'themes_new.tpl'));
+
+if ($themes->get_server_plugins(true, 'theme'))
+{
+  foreach($themes->server_plugins as $theme)
+  {
+    $url_auto_install = htmlentities($base_url)
+      . '&amp;revision=' . $theme['revision_id']
+      . '&amp;extension=' . $theme['extension_id']
+      ;
+
+    $template->append(
+      'new_themes',
+      array(
+        'name' => $theme['extension_name'],
+        'src' => PEM_URL.'/upload/extension-'.$theme['extension_id'].'/thumbnail.jpg',
+        'install_url' => $url_auto_install,
+        )
+      );
+  }
+}
+else
+{
+  array_push($page['errors'], l10n('Can\'t connect to server.'));
+}
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'themes');
+?>
