Index: .hgsubstate
===================================================================
--- .hgsubstate	(revision 1385)
+++ .hgsubstate	(revision 1486)
@@ -1,1 +1,1 @@
-4288bdc1f21d00f93331bbe098485727b276c1fe inc/libs/clearbricks
+716e99c54652d08c2e4395d5179e817e0f98182d inc/libs/clearbricks
Index: CHANGELOG
===================================================================
--- CHANGELOG	(revision 1216)
+++ CHANGELOG	(revision 1350)
@@ -1,2 +1,19 @@
+Dotclear 2.5.2 - 2013-08-14
+===========================================================
+* Security fix: Fixed potential XSS
+* Bugfix: l10n Clearbricks library
+* <tpl:LoopPosition> now works <tpl:Attachments>
+* Dotclear update check may now be forced (ignoring cache)
+* Enforce integration of daInstaller plugin
+* Tags link button is now available on page editor
+* Default cache age is now 1 week instead of 2 hours
+* Quick entry dashboard module is not activated by default on new installation
+* New template {{tpl:BlogParentThemeURL}} (return URL of parent theme of blog's theme if any, URL of blog's theme otherwise)
+* Fix post comments number on comments deletion
+* Fix order of backup files
+* Minor enhancements
+* Various bug fixes
+* Various cosmetic adjustments
+
 Dotclear 2.5.1 - 2013-07-20
 ===========================================================
Index: Makefile
===================================================================
--- Makefile	(revision 1046)
+++ Makefile	(revision 1451)
@@ -69,4 +69,5 @@
 	find $(DC)/admin/js/jquery/*.js -exec ./build-tools/min-js.php \{\} \;
 	find $(DC)/admin/js/jsToolBar/*.js -exec ./build-tools/min-js.php \{\} \;
+	find $(DC)/admin/js/jsUpload/*.js -exec ./build-tools/min-js.php \{\} \;
 	find $(DC)/admin/js/tool-man/*.js -exec ./build-tools/min-js.php \{\} \;
 	find $(DC)/plugins -name '*.js' -exec ./build-tools/min-js.php \{\} \;
Index: admin/blog.php
===================================================================
--- admin/blog.php	(revision 1399)
+++ admin/blog.php	(revision 1482)
@@ -79,5 +79,5 @@
 	'<form action="blog.php" method="post" id="blog-form">'.
 	
-	$core->formNonce().
+	'<div>'.$core->formNonce().'</div>'.
 	'<p><label class="required" for="blog_id"><abbr title="'.__('Required field').'">*</abbr> '.__('Blog ID:').'</label> '.
 	form::field('blog_id',30,32,html::escapeHTML($blog_id)).'</p>'.
Index: admin/blog_pref.php
===================================================================
--- admin/blog_pref.php	(revision 1399)
+++ admin/blog_pref.php	(revision 1474)
@@ -504,5 +504,5 @@
 		(html::escapeHTML($blog_settings->system->media_img_default_size) != '' ? html::escapeHTML($blog_settings->system->media_img_default_size) : 'm')).
 	'</p>'.
-	'<p><label for="media_img_default_alignment">'.__('Image alignment').'</label>'.
+	'<p><label for="media_img_default_alignment">'.__('Image alignment:').'</label>'.
 	form::combo('media_img_default_alignment',$img_default_alignment_combo,html::escapeHTML($blog_settings->system->media_img_default_alignment)).
 	'</p>'.
@@ -548,7 +548,7 @@
 	} else {
 		if ($blog_id == $core->blog->id) {
-			echo '<p class="message">'.__('The current blog cannot be deleted').'</p>';
+			echo '<p class="message">'.__('The current blog cannot be deleted.').'</p>';
 		} else {
-			echo '<p class="message">'.__('Only superadmin can delete a blog').'</p>';
+			echo '<p class="message">'.__('Only superadmin can delete a blog.').'</p>';
 		}
 	}
Index: admin/categories.php
===================================================================
--- admin/categories.php	(revision 1399)
+++ admin/categories.php	(revision 1468)
@@ -31,5 +31,5 @@
 		$mov_cat = $mov_cat ? $mov_cat : null;
 		if ($mov_cat !== null) {
-			$c = $core->blog->getCategory((integer) $_POST['del_cat']);
+			$c = $core->blog->getCategory((integer) $_POST['mov_cat']);
 			if ($c->isEmpty()) {
 				throw new Exception(__('This category does not exist.'));
@@ -144,4 +144,15 @@
 echo '</div>';
 
+$categories_combo = array();
+if (!$rs->isEmpty())
+{
+	while ($rs->fetch()) {
+		$catparents_combo[] = $categories_combo[] = new formSelectOption(
+			str_repeat('&nbsp;&nbsp;',$rs->level-1).($rs->level-1 == 0 ? '' : '&bull; ').html::escapeHTML($rs->cat_title),
+			$rs->cat_id
+		);
+	}
+}
+
 echo '<div class="col">'.
 
@@ -149,49 +160,25 @@
 '<h3>'.__('Add a new category').'</h3>'.
 '<p><label class="required" for="cat_title"><abbr title="'.__('Required field').'">*</abbr> '.__('Title:').'</label> '.
-form::field('cat_title',30,255).'</p>'.
+form::field('cat_title',30,255,'','maximal').'</p>'.
 '<p><label for="new_cat_parent">'.__('Parent:').'</label> '.
-'<select id="new_cat_parent" name="new_cat_parent">'.
-'<option value="0">'.__('Top level').'</option>';
-while ($rs->fetch()) {
-	echo '<option value="'.$rs->cat_id.'">'.
-		str_repeat('&nbsp;&nbsp;',$rs->level-1).($rs->level-1 == 0 ? '' : '&bull; ').
-		html::escapeHTML($rs->cat_title).'</option>';
-}
-echo
-'</select></p>'.
+form::combo('new_cat_parent',array_merge(array(__('(No cat)') => 0),$categories_combo),'','maximal').
+'</p>'.
 '<p><input type="submit" value="'.__('Create').'" />'.
 $core->formNonce().'</p>'.
+
 '</form>';
 
 if (!$rs->isEmpty())
 {
-	$cats = array();
-	$dest = array('&nbsp;' => '');
-	$l = $rs->level;
-	$full_name = array($rs->cat_title);
-	while ($rs->fetch())
-	{
-		if ($rs->level < $l) {
-			$full_name = array();
-		} elseif ($rs->level == $l) {
-			array_pop($full_name);
-		}
-		$full_name[] = html::escapeHTML($rs->cat_title);
-		
-		$cats[implode(' / ',$full_name)] = $rs->cat_id;
-		$dest[implode(' / ',$full_name)] = $rs->cat_id;
-		
-		$l = $rs->level;
-	}
-	
 	echo
-	'<form action="categories.php" method="post" id="delete-category" class="border-top">'.
+	'<form action="categories.php" method="post" id="delete-category">'.
 	'<h3>'.__('Remove a category').'</h3>'.
 	'<p><label for="del_cat">'.__('Choose a category to remove:').'</label> '.
-	form::combo('del_cat',$cats).'</p> '.
+	form::combo('del_cat',$categories_combo,'','maximal').'</p> '.
 	'<p><label for="mov_cat">'.__('And choose the category which will receive its entries:').'</label> '.
-	form::combo('mov_cat',$dest).'</p> '.
+	form::combo('mov_cat',array_merge(array(__('(No cat)') => ''),$categories_combo),'','maximal').'</p> '.
 	'<p><input type="submit" value="'.__('Delete').'" class="delete" />'.
 	$core->formNonce().'</p>'.
+
 	'</form>';
 	
Index: admin/comments.php
===================================================================
--- admin/comments.php	(revision 1424)
+++ admin/comments.php	(revision 1480)
@@ -37,6 +37,6 @@
 $type_combo = array(
 '-' => '',
-__('comment') => 'co',
-__('trackback') => 'tb'
+__('Comment') => 'co',
+__('Trackback') => 'tb'
 );
 
@@ -134,8 +134,8 @@
 if ($core->auth->check('publish,contentadmin',$core->blog->id))
 {
-	$combo_action[__('publish')] = 'publish';
-	$combo_action[__('unpublish')] = 'unpublish';
-	$combo_action[__('mark as pending')] = 'pending';
-	$combo_action[__('mark as junk')] = 'junk';
+	$combo_action[__('Publish')] = 'publish';
+	$combo_action[__('Unpublish')] = 'unpublish';
+	$combo_action[__('Mark as pending')] = 'pending';
+	$combo_action[__('Mark as junk')] = 'junk';
 }
 if ($core->auth->check('delete,contentadmin',$core->blog->id))
@@ -261,5 +261,5 @@
 	
 	'<p class="col right"><label for="action" class="classic">'.__('Selected comments action:').'</label> '.
-	form::combo('action',$combo_action,$default,'','','','title="'.__('action: ').'"').
+	form::combo('action',$combo_action,$default,'','','','title="'.__('Actions').'"').
 	$core->formNonce().
 	'<input type="submit" value="'.__('ok').'" /></p>'.
Index: admin/comments_actions.php
===================================================================
--- admin/comments_actions.php	(revision 1179)
+++ admin/comments_actions.php	(revision 1474)
@@ -137,5 +137,5 @@
 $core->callBehavior('adminCommentsActionsContent',$core,$action,$hidden_fields);
 
-echo '<p><a class="back" href="'.str_replace('&','&amp;',$redir).'">'.__('back').'</a></p>';
+echo '<p><a class="back" href="'.str_replace('&','&amp;',$redir).'">'.__('Back to comments list').'</a></p>';
 
 dcPage::close();
Index: admin/js/_index.js
===================================================================
--- admin/js/_index.js	(revision 1140)
+++ admin/js/_index.js	(revision 1418)
@@ -61,4 +61,8 @@
 			});
 		}
+		$('#new_cat').toggleWithLegend(
+			$('#new_cat').parent().children().not('#new_cat'),
+			{} // no cookie on new category as we don't use this every day
+		);
 	}
 
Index: admin/js/_post.js
===================================================================
--- admin/js/_post.js	(revision 1490)
+++ admin/js/_post.js	(revision 1492)
@@ -115,4 +115,8 @@
 			hide: $('#post_notes').val() == ''
 		});
+		$('#new_cat').toggleWithLegend(
+			$('#new_cat').parent().children().not('#new_cat'),
+			{} // no cookie on new category as we don't use this every day
+		);
 		$('#post_lang').parent().toggleWithLegend($('#post_lang'),{
 			cookie: 'dcx_post_lang'
Index: admin/js/_posts_actions.js
===================================================================
--- admin/js/_posts_actions.js	(revision 1035)
+++ admin/js/_posts_actions.js	(revision 1419)
@@ -6,3 +6,7 @@
 		matchContains: true
 	});
+	$('#new_cat').toggleWithLegend(
+		$('#new_cat').parent().children().not('#new_cat'),
+		{} // no cookie on new category as we don't use this every day
+	);
 });
Index: admin/js/_update.js
===================================================================
--- admin/js/_update.js	(revision 1462)
+++ admin/js/_update.js	(revision 1462)
@@ -0,0 +1,5 @@
+$(function() {
+	$('form input[type=submit][name=b_del]').click(function(){
+ 		return window.confirm(dotclear.msg.confirm_delete_backup);
+ 	});
+});
Index: admin/js/_users_actions.js
===================================================================
--- admin/js/_users_actions.js	(revision 935)
+++ admin/js/_users_actions.js	(revision 1449)
@@ -1,4 +1,5 @@
 jQuery.fn.updatePermissionsForm = function() {
 	return this.each(function() {
+		
 		var perms = {};
 		var re = /^perm\[(.+?)\]\[(.+?)\]$/;
@@ -12,4 +13,5 @@
 				continue;
 			}
+			var prop;
 			prop = e.name.match(re);
 			if (!prop) {
@@ -20,37 +22,70 @@
 			}
 			perms[prop[1]][prop[2]] = e;
+			
+			// select related permissions for admin
+			if (prop[2] == 'admin') {
+				if (e.checked) {
+					admin(e,perms,re);
+				}
+				$(e).click(function(){
+					admin(this,perms,re);
+				});
+			// select related permissions for content admin
+			} else if (prop[2] == 'contentadmin') {
+				if (e.checked) {
+					contentadmin(e,perms,re);
+				}
+				$(e).click(function(){
+					contentadmin(this,perms,re);
+				});
+			// select related permissions for media admin
+			} else if (prop[2] == 'media_admin') {
+				if (e.checked) {
+					mediaadmin(e,perms,re);
+				}
+				$(e).click(function(){
+					mediaadmin(this,perms,re);
+				});
+			}
 		}
 		
-		// Update elements status
-		var E;
-		for (blog in perms) {
-			for (perm in perms[blog]) {
-				E = perms[blog][perm];
-				E.onclick = function() {};
-				
-				if (perm == 'admin' && !E.disabled) {
-					perms[blog]['usage'].disabled = E.checked;
-					perms[blog]['publish'].disabled = E.checked;
-					perms[blog]['delete'].disabled = E.checked;
-					perms[blog]['contentadmin'].disabled = E.checked;
-					perms[blog]['categories'].disabled = E.checked;
-					perms[blog]['media'].disabled = E.checked;
-					perms[blog]['media_admin'].disabled = E.checked;
-					E.onclick = function() { $(this.form).updatePermissionsForm(); };
-				} else if (perm == 'contentadmin' && !E.disabled) {
-					perms[blog]['usage'].checked = E.checked;
-					perms[blog]['publish'].checked = E.checked;
-					perms[blog]['delete'].checked = E.checked;
-					perms[blog]['usage'].disabled = E.checked;
-					perms[blog]['publish'].disabled = E.checked;
-					perms[blog]['delete'].disabled = E.checked;
-					E.onclick = function() { $(this.form).updatePermissionsForm(); };
-				} else if (perm == 'media_admin' && !E.disabled) {
-					perms[blog]['media'].checked = E.checked;
-					perms[blog]['media'].disabled = E.checked;
-					E.onclick = function() { $(this.form).updatePermissionsForm(); };
-				}
-			}
+		function admin(E,perms,re) {
+					P = E.name.match(re);
+					
+					perms[P[1]]['usage'].checked = E.checked;
+					perms[P[1]]['publish'].checked = E.checked;
+					perms[P[1]]['delete'].checked = E.checked;
+					perms[P[1]]['contentadmin'].checked = E.checked;
+					perms[P[1]]['categories'].checked = E.checked;
+					perms[P[1]]['media'].checked = E.checked;
+					perms[P[1]]['media_admin'].checked = E.checked;
+					perms[P[1]]['usage'].disabled = E.checked;
+					perms[P[1]]['publish'].disabled = E.checked;
+					perms[P[1]]['delete'].disabled = E.checked;
+					perms[P[1]]['contentadmin'].disabled = E.checked;
+					perms[P[1]]['categories'].disabled = E.checked;
+					perms[P[1]]['media'].disabled = E.checked;
+					perms[P[1]]['media_admin'].disabled = E.checked;
 		}
+		
+		function contentadmin(E,perms,re) {
+					P = E.name.match(re);
+					
+					perms[P[1]]['usage'].checked = E.checked;
+					perms[P[1]]['publish'].checked = E.checked;
+					perms[P[1]]['delete'].checked = E.checked;
+					perms[P[1]]['usage'].disabled = E.checked;
+					perms[P[1]]['publish'].disabled = E.checked;
+					perms[P[1]]['delete'].disabled = E.checked;
+		}
+		
+		function mediaadmin(E,perms,re) {
+					P = E.name.match(re);
+					
+					perms[P[1]]['media'].checked = E.checked;
+					perms[P[1]]['media'].disabled = E.checked;
+		}
+		
+		
 	});
 };
Index: admin/js/jquery/jquery.pwstrength.js
===================================================================
--- admin/js/jquery/jquery.pwstrength.js	(revision 1371)
+++ admin/js/jquery/jquery.pwstrength.js	(revision 1371)
@@ -0,0 +1,66 @@
+/**
+ * jquery.pwstrength http://matoilic.github.com/jquery.pwstrength
+ *
+ * @version v0.1.1
+ * @author Mato Ilic <info@matoilic.ch>
+ * @copyright 2013 Mato Ilic
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */
+;(function($) {
+    $.pwstrength = function(password) {
+        var score = 0, length = password.length, upperCase, lowerCase, digits, nonAlpha;
+        
+        if(length < 5) score += 0;
+        else if(length < 8) score += 5;
+        else if(length < 16) score += 10;
+        else score += 15;
+        
+        lowerCase = password.match(/[a-z]/g);
+        if(lowerCase) score += 1;
+        
+        upperCase = password.match(/[A-Z]/g);
+        if(upperCase) score += 5;
+        
+        if(upperCase && lowerCase) score += 2;
+        
+        digits = password.match(/\d/g);
+        if(digits && digits.length > 1) score += 5;
+        
+        nonAlpha = password.match(/\W/g)
+        if(nonAlpha) score += (nonAlpha.length > 1) ? 15 : 10;
+        
+        if(upperCase && lowerCase && digits && nonAlpha) score += 15;
+
+        if(password.match(/\s/)) score += 10;
+
+        if(score < 15) return 0;
+        if(score < 20) return 1;
+        if(score < 35) return 2;
+        if(score < 50) return 3;
+        return 4;
+    };
+    
+    function updateIndicator(event) {
+        var strength = $.pwstrength($(this).val()), options = event.data, klass;
+        klass = options.classes[strength];
+        
+        options.indicator.removeClass(options.indicator.data('pwclass'));
+        options.indicator.data('pwclass', klass);
+        options.indicator.addClass(klass);
+        options.indicator.find(options.label).html(options.texts[strength]);
+    }
+    
+    $.fn.pwstrength = function(options) {
+        var options = $.extend({
+            label: '.label',
+            classes: ['pw-very-weak', 'pw-weak', 'pw-mediocre', 'pw-strong', 'pw-very-strong'],
+            texts: ['very weak', 'weak', 'mediocre', 'strong', 'very strong']
+        }, options || {});
+        options.indicator = $('#' + this.data('indicator'));
+        
+        return this.keyup(options, updateIndicator);
+    };
+})(jQuery);
Index: admin/plugins.php
===================================================================
--- admin/plugins.php	(revision 1399)
+++ admin/plugins.php	(revision 1474)
@@ -236,8 +236,8 @@
 
 if ($is_writable) {
-	echo __('To install or upgrade a plugin you generally just need to upload it '.
+	echo '<p>'.__('To install or upgrade a plugin you generally just need to upload it '.
 	'in "Install or upgrade a plugin" section.');
 } else {
-	echo __('To install or upgrade a plugin you just need to extract it in your plugins directory.');
+	echo '<p>'.__('To install or upgrade a plugin you just need to extract it in your plugins directory.');
 }
 echo '</p>';
Index: admin/posts_actions.php
===================================================================
--- admin/posts_actions.php	(revision 1399)
+++ admin/posts_actions.php	(revision 1476)
@@ -17,4 +17,121 @@
 $params = array();
 
+/**
+* FieldsList - Compatibility class for hidden fields & entries[] fields
+*
+*/
+class FieldsList {
+	/** @var array list of hidden fields */
+	protected $hidden;
+	/** @var array list of selected entries */
+	protected $entries;
+
+
+   /**
+     * Class constructor
+	*/
+	public function __construct() {
+		$this->hidden=array();
+		$this->entries =array();
+	}
+
+    /**
+     * addHidden - adds a hidden field
+     * 
+     * @param string $name the field name.
+     * @param mixed $value the field value.
+     *
+     * @access public
+	 * @return the FieldsList instance, enabling to chain requests
+     */	
+	 public function addHidden($name,$value) {
+		$this->hidden[] = form::hidden($name,$value);
+		return $this;
+	}
+
+    /**
+     * addEntry - adds a antry field
+     * 
+     * @param string $id the entry id.
+     * @param mixed $title the entry title.
+     *
+     * @access public
+	 * @return the FieldsList instance, enabling to chain requests
+     */	
+	 public function addEntry($id,$title) {
+		$this->entries[$id]=$title;
+		return $this;
+	}
+
+    /**
+     * getHidden - returns the list of hidden fields, html encoded
+     *
+     * @access public
+	 * @return the list of hidden fields, html encoded
+     */
+	 public function getHidden() {
+		return join('',$this->hidden);
+	}
+	
+    /**
+     * getEntries - returns the list of entry fields, html encoded
+     *
+	 * @param boolean $hidden if set to true, returns entries as a list of hidden field
+	 *                if set to false, returns html code displaying the list of entries
+	 *                with a list of checkboxes to enable to select/deselect entries
+     * @access public
+	 * @return the list of entry fields, html encoded
+     */
+	public function getEntries ($hidden=false) {
+		$ret = '';
+		if ($hidden) {
+			foreach ($this->entries as $id=> $e) {
+				$ret .= form::hidden('entries[]',$id);
+			}
+		} else {
+			$ret = 
+				'<table class="posts-list"><tr>'.
+				'<th colspan="2">'.__('Title').'</th>'.
+				'</tr>';
+			foreach ($this->entries as $id=>$title) {
+				$ret .= 
+					'<tr><td>'.
+					form::checkbox(array('entries[]'),$id,true,'','').'</td>'.
+					'<td>'.	$title.'</td></tr>';
+			}
+			$ret .= '</table>';
+		}
+		return $ret;
+	}
+	
+    /**
+     * getEntriesQS - returns the list of entry fields as query string
+     *
+     * @access public
+	 * @return the list of entry fields, html encoded
+     */
+	public function getEntriesQS() {
+		$ret=array();
+		foreach ($this->entries as $id=>$title) {
+			$ret[] = 'entries[]='.$id;
+		}
+		return join('&',$ret);
+	}
+	
+    /**
+     * __toString - magic method. -- DEPRECATED here
+	 *              This method is only used to preserve compatibility with plugins 
+	 *				relying on previous versions of adminPostsActionsContent behavior, 
+	 *
+     * @access public
+	 * @return the list of hidden fields and entries (as hidden fields too), html encoded
+     */
+	public function __toString() {
+		return join('',$this->hidden).$this->getEntries(true);
+	}
+}
+
+$fields = new FieldsList();
+
 /* Actions
 -------------------------------------------------------- */
@@ -62,5 +179,8 @@
 	while ($posts->fetch())	{
 		$posts_ids[] = $posts->post_id;
-	}
+		$fields->addEntry($posts->post_id,$posts->post_title);
+	}
+	// Redirection including selected entries
+	$redir_sel = $redir.'&'.$fields->getEntriesQS();
 	
 	# --BEHAVIOR-- adminPostsActions
@@ -80,5 +200,5 @@
 			$core->blog->updPostsStatus($posts_ids,$status);
 			
-			http::redirect($redir);
+			http::redirect($redir_sel.'&upd=1');
 		}
 		catch (Exception $e)
@@ -93,5 +213,5 @@
 			$core->blog->updPostsSelected($posts_ids,$action == 'selected');
 			
-			http::redirect($redir);
+			http::redirect($redir_sel."&upd=1");
 		}
 		catch (Exception $e)
@@ -116,5 +236,5 @@
 			$core->blog->delPosts($posts_ids);
 			
-			http::redirect($redir);
+			http::redirect($redir."&del=1");
 		}
 		catch (Exception $e)
@@ -126,9 +246,28 @@
 	elseif ($action == 'category' && isset($_POST['new_cat_id']))
 	{
+		$new_cat_id = $_POST['new_cat_id'];
+		
 		try
 		{
-			$core->blog->updPostsCategory($posts_ids,$_POST['new_cat_id']);
-			
-			http::redirect($redir);
+			if (!empty($_POST['new_cat_title']) && $core->auth->check('categories', $core->blog->id))
+			{
+				$cur_cat = $core->con->openCursor($core->prefix.'category');
+				$cur_cat->cat_title = $_POST['new_cat_title'];
+				$cur_cat->cat_url = '';
+				
+				$parent_cat = !empty($_POST['new_cat_parent']) ? $_POST['new_cat_parent'] : '';
+				
+				# --BEHAVIOR-- adminBeforeCategoryCreate
+				$core->callBehavior('adminBeforeCategoryCreate', $cur_cat);
+				
+				$new_cat_id = $core->blog->addCategory($cur_cat, (integer) $parent_cat);
+				
+				# --BEHAVIOR-- adminAfterCategoryCreate
+				$core->callBehavior('adminAfterCategoryCreate', $cur_cat, $new_cat_id);
+			}
+			
+			$core->blog->updPostsCategory($posts_ids, $new_cat_id);
+			
+			http::redirect($redir_sel."&upd=1");
 		}
 		catch (Exception $e)
@@ -152,5 +291,5 @@
 			$cur->update('WHERE post_id '.$core->con->in($posts_ids));
 			
-			http::redirect($redir);
+			http::redirect($redir_sel."&upd=1");
 		}
 		catch (Exception $e)
@@ -168,5 +307,5 @@
 			$cur->update('WHERE post_id '.$core->con->in($posts_ids));
 			
-			http::redirect($redir);
+			http::redirect($redir_sel."&upd=1");
 		}
 		catch (Exception $e)
@@ -175,6 +314,24 @@
 		}
 	}
-}
-
+} else {
+	if (empty($_POST['entries'])) {
+		$core->error->add(__('At least one entry should be selected'));
+	} else {
+		$core->error->add(__('No action specified.'));
+	}
+	dcPage::open(
+		__('Entries'),'',dcPage::breadcrumb(
+		array(
+			html::escapeHTML($core->blog->name) => '',
+			__('Entries') => 'posts.php',
+			'<span class="page-title">'.__('Entries actions').'</span>' => ''
+		))
+	);
+	
+	echo '<p><a class="back" href="'.html::escapeURL($redir_sel).'">'.__('Back to entries list').'</a></p>';
+
+	dcPage::close();
+	exit;
+}
 /* DISPLAY
 -------------------------------------------------------- */
@@ -211,60 +368,77 @@
 }
 
-$hidden_fields = '';
-while ($posts->fetch()) {
-	$hidden_fields .= form::hidden(array('entries[]'),$posts->post_id);
-}
-
 if (isset($_POST['redir']) && strpos($_POST['redir'],'://') === false)
 {
-	$hidden_fields .= form::hidden(array('redir'),html::escapeURL($_POST['redir']));
+	$fields->addHidden(array('redir'),html::escapeURL($_POST['redir']));
 }
 else
 {
-	$hidden_fields .=
-	form::hidden(array('user_id'),$_POST['user_id']).
-	form::hidden(array('cat_id'),$_POST['cat_id']).
-	form::hidden(array('status'),$_POST['status']).
-	form::hidden(array('selected'),$_POST['selected']).
-	form::hidden(array('month'),$_POST['month']).
-	form::hidden(array('lang'),$_POST['lang']).
-	form::hidden(array('sortby'),$_POST['sortby']).
-	form::hidden(array('order'),$_POST['order']).
-	form::hidden(array('page'),$_POST['page']).
-	form::hidden(array('nb'),$_POST['nb']);
+	$fields
+		->addHidden(array('user_id'),$_POST['user_id'])
+		->addHidden(array('cat_id'),$_POST['cat_id'])
+		->addHidden(array('status'),$_POST['status'])
+		->addHidden(array('selected'),$_POST['selected'])
+		->addHidden(array('month'),$_POST['month'])
+		->addHidden(array('lang'),$_POST['lang'])
+		->addHidden(array('sortby'),$_POST['sortby'])
+		->addHidden(array('order'),$_POST['order'])
+		->addHidden(array('page'),$_POST['page'])
+		->addHidden(array('nb'),$_POST['nb'])
+	;
 }
 
 if (isset($_POST['post_type'])) {
-	$hidden_fields .= form::hidden(array('post_type'),$_POST['post_type']);
+	$fields->addHidden(array('post_type'),$_POST['post_type']);
 }
 
 # --BEHAVIOR-- adminPostsActionsContent
-$core->callBehavior('adminPostsActionsContent',$core,$action,$hidden_fields);
+$core->callBehavior('adminPostsActionsContent',$core,$action,$fields);
 
 if ($action == 'category')
 {
-	echo '<h2 class="page-title">'.__('Change category for entries').'</h2>';
-	
+	echo dcPage::breadcrumb(
+		array(
+			html::escapeHTML($core->blog->name) => '',
+			__('Entries') => 'posts.php',
+			__('Change category for entries') => ''
+	));
+	
+	echo '<p><a class="back" href="'.html::escapeURL($redir_sel).'">'.__('Back to entries list').'</a></p>';
+
 	# categories list
 	# Getting categories
-	$categories_combo = array('&nbsp;' => '');
+	$categories_combo = array(__('(No cat)') => '');
 	try {
 		$categories = $core->blog->getCategories(array('post_type'=>'post'));
+		if (!$categories->isEmpty()) {
 		while ($categories->fetch()) {
-			$categories_combo[] = new formSelectOption(
-				str_repeat('&nbsp;&nbsp;',$categories->level-1).
-				($categories->level-1 == 0 ? '' : '&bull; ').html::escapeHTML($categories->cat_title),
+				$catparents_combo[] = $categories_combo[] = new formSelectOption(
+					str_repeat('&nbsp;&nbsp;',$categories->level-1).($categories->level-1 == 0 ? '' : '&bull; ').html::escapeHTML($categories->cat_title),
 				$categories->cat_id
 			);
 		}
+		}
 	} catch (Exception $e) { }
 	
 	echo
 	'<form action="posts_actions.php" method="post">'.
+	$fields->getEntries().
 	'<p><label for="new_cat_id" class="classic">'.__('Category:').'</label> '.
 	form::combo('new_cat_id',$categories_combo,'');
 	
+	if ($core->auth->check('categories', $core->blog->id)) {
+		echo 
+		'<div>'.
+		'<p id="new_cat">'.__('Add a new category').'</p>'.
+		'<p><label for="new_cat_title">'.__('Title:').' '.
+		form::field('new_cat_title',30,255,'','maximal').'</label></p>'.
+		'<p><label for="new_cat_parent">'.__('Parent:').' '.
+		form::combo('new_cat_parent',$categories_combo,'','maximal').
+		'</label></p>'.
+		'</div>';
+	}
+	
 	echo
-	$hidden_fields.
+	$fields->getHidden().
 	$core->formNonce().
 	form::hidden(array('action'),'category').
@@ -274,6 +448,12 @@
 elseif ($action == 'lang')
 {
-	echo '<h2 class="page-title">'.__('Change language for entries').'</h2>';
-	
+	echo dcPage::breadcrumb(
+		array(
+			html::escapeHTML($core->blog->name) => '',
+			__('Entries') => 'posts.php',
+			'<span class="page-title">'.__('Change language for entries').'</span>' => ''
+	));
+	echo '<p><a class="back" href="'.html::escapeURL($redir_sel).'">'.__('Back to entries list').'</a></p>';
+
 	# lang list
 	# Languages combo
@@ -294,9 +474,11 @@
 	echo
 	'<form action="posts_actions.php" method="post">'.
+	$fields->getEntries().
+	
 	'<p><label for="new_lang" class="classic">'.__('Entry lang:').'</label> '.
 	form::combo('new_lang',$lang_combo,'');
 	
 	echo
-	$hidden_fields.
+	$fields->getHidden().
 	$core->formNonce().
 	form::hidden(array('action'),'lang').
@@ -307,13 +489,20 @@
 elseif ($action == 'author' && $core->auth->check('admin',$core->blog->id))
 {
-	echo '<h2 class="page-title">'.__('Change author for entries').'</h2>';
-	
+	echo dcPage::breadcrumb(
+		array(
+			html::escapeHTML($core->blog->name) => '',
+			__('Entries') => 'posts.php',
+			'<span class="page-title">'.__('Change author for entries').'</span>' => ''
+	));
+	echo '<p><a class="back" href="'.html::escapeURL($redir_sel).'">'.__('Back to entries list').'</a></p>';
+
 	echo
 	'<form action="posts_actions.php" method="post">'.
+	$fields->getEntries().
 	'<p><label for="new_auth_id" class="classic">'.__('Author ID:').'</label> '.
 	form::field('new_auth_id',20,255);
 	
 	echo
-	$hidden_fields.
+	$fields->getHidden().
 	$core->formNonce().
 	form::hidden(array('action'),'author').
@@ -322,6 +511,4 @@
 }
 
-echo '<p><a class="back" href="'.html::escapeURL($redir).'">'.__('back').'</a></p>';
-
 dcPage::close();
 ?>
Index: admin/preferences.php
===================================================================
--- admin/preferences.php	(revision 1399)
+++ admin/preferences.php	(revision 1474)
@@ -344,4 +344,17 @@
 	($user_acc_nodragdrop ? '' : dcPage::jsLoad('js/_preferences-dragdrop.js')).
 	dcPage::jsLoad('js/jquery/jquery-ui.custom.js').
+	dcPage::jsLoad('js/jquery/jquery.pwstrength.js').
+		'<script type="text/javascript">'."\n".
+		"//<![CDATA[\n".
+		"\$(function() {\n".
+		"	\$('#new_pwd').pwstrength({texts: ['".
+				sprintf(__('Password strength: %s'),__('very weak'))."', '".
+				sprintf(__('Password strength: %s'),__('weak'))."', '".
+				sprintf(__('Password strength: %s'),__('mediocre'))."', '".
+				sprintf(__('Password strength: %s'),__('strong'))."', '".
+				sprintf(__('Password strength: %s'),__('very strong'))."']});\n".
+		"});\n".
+		"\n//]]>\n".
+		"</script>\n".
 	dcPage::jsPageTabs($default_tab).
 	dcPage::jsConfirmClose('user-form').
@@ -411,5 +424,4 @@
 '</div>'.
 '</div>'.
-'<br class="clear" />'. //Opera sucks
 '</fieldset>';
 
@@ -420,8 +432,14 @@
 	'<legend>'.__('Change your password').'</legend>'.
 	
-	'<p><label for="new_pwd">'.__('New password:').'</label>'.
-	form::password('new_pwd',20,255).'</p>'.
+	'<div class="pw-table">'.
+	'<p class="pw-cell"><label for="new_pwd">'.__('New password:').'</label>'.
+	form::password('new_pwd',20,255,'','','',false,' data-indicator="pwindicator" ').'</p>'.
+	'<div id="pwindicator">'.
+	'    <div class="bar"></div>'.
+	'    <p class="label no-margin"></p>'.
+	'</div>'.
+	'</div>'.
 	
-	'<p><label for="new_pwd_c">'.__('Confirm password:').'</label>'.
+	'<p><label for="new_pwd_c">'.__('Confirm new password:').'</label>'.
 	form::password('new_pwd_c',20,255).'</p>'.
 	'</fieldset>'.
@@ -481,9 +499,9 @@
 	form::checkbox('user_ui_hide_std_favicon',1,$user_ui_hide_std_favicon).' '.
 	__('Do not use standard favicon').'</label></p>'.
-	'<p class="clear form-note info">'.__('This will be applied for all users').'</p>';
+	'<p class="clear form-note info">'.__('This will be applied for all users').
+	'<br class="clear" /></p>';//Opera sucks;
 }
 
 echo 
-'<br class="clear" />'. //Opera sucks
 '</fieldset>';
 
@@ -511,7 +529,7 @@
 '<p><label for="user_dm_quickentry" class="classic">'.
 form::checkbox('user_dm_quickentry',1,$user_dm_quickentry).' '.
-__('Display quick entry form').'</label></p>'.
-
-'<br class="clear" />'. //Opera sucks
+__('Display quick entry form').'</label><br class="clear" />'. //Opera sucks
+'</p>'.
+
 '</fieldset>';
 
Index: admin/style/default.css
===================================================================
--- admin/style/default.css	(revision 1490)
+++ admin/style/default.css	(revision 1492)
@@ -420,5 +420,5 @@
 #login-screen {
 	display: block;
-	width: 18em;
+	width: 20em;
 	margin: 1.5em auto 0;
 	font-size: 1.4rem;
@@ -431,5 +431,5 @@
 	margin-left: 0;
 }
-#login-screen fieldset, #login-screen .fieldset {
+#login-screen .fieldset {
 	border: 1px solid #A8DC26;
 	padding: 1em 1em 0 1em;
@@ -437,7 +437,4 @@
 	background: #fff;
 }
-#login-screen legend {
-	border: 1px solid #A8DC26;
-}
 #login-screen input[type=text], #login-screen input[type=password], #login-screen input[type=submit] {
 	width: 100%;
@@ -448,5 +445,4 @@
 }
 #login-screen #issue strong {font-weight: normal;}
-
 
 /* ------------------------------------------------------------------ dashboard */
@@ -481,11 +477,20 @@
 #icons a img {
 	padding: 2em;
-	background: #eee;
-	border-radius: 1.6rem;
-	box-shadow: 0 3px 3px 0 #ccc;
-	margin-bottom: .6rem;
+	margin-bottom: .3em;
+	-moz-box-shadow: 0px 1px 0px 0px #ffffff;
+	-webkit-box-shadow: 0px 1px 0px 0px #ffffff;
+	box-shadow: 0px 1px 0px 0px #ffffff;
+	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #f9f9f9), color-stop(1, #e9e9e9) );
+	background:-moz-linear-gradient( center top, #f9f9f9 5%, #e9e9e9 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e9e9e9');
+	background-color:#f9f9f9;
+	-moz-border-radius:1em;
+	-webkit-border-radius:1em;
+	border-radius:1em;
+	border:1px solid #dcdcdc;
+	display:inline-block;
 }
 #icons a img:hover, #icons a:focus img {
-	background-color: #BBDB58;
+	background: #BBDB58;
 }
 #icons a:focus span, #icons a:hover span {
@@ -501,5 +506,5 @@
 #quick p.qinfo {
 	margin: -.7em -1em 1em;
-	background: #eef url(info.png) no-repeat .2em .2em;
+	background: #f3f3ff url(info.png) no-repeat .2em .2em;
 	border: 1px solid #99f;
 	padding: .2em 1em .1em 24px;
@@ -541,4 +546,12 @@
 }
 
+#upg-notify {
+}
+#upg-notify ul {
+	padding-left: 15px;
+}
+#upg-notify li {
+	color: #fff;
+}
 /* ------------------------------------------------------------------ post */
 #entry-wrapper {
@@ -1201,5 +1214,5 @@
 }
 table.settings th, table.prefs th {
-	background: #eef;
+	background: #f3f3ff;
 }
 table.settings th:first-child, table.prefs th:first-child {
@@ -1340,5 +1353,5 @@
 }
 p.form-note.info {
-	background: #f5eaff url(info.png) no-repeat .3em .2em;
+	background: #f5eaff url(info.png) no-repeat .3em .3em;
 	border: 1px solid #ddbaff;
 }
@@ -1415,13 +1428,12 @@
 a.submit {
 	display: inline-block;
-	outline: none;
 	cursor: pointer;
 	text-align: center;
 	text-decoration: none;
 	padding: .1em .5em;
-	text-shadow: 0 1px 1px rgba(0,0,0,.3);
 	border-radius: .2em;
 	margin-bottom: .1em;
-}
+	font-size: 1.2rem;
+ }
 h4 a.button {font-weight: normal;}
 
@@ -1431,8 +1443,12 @@
 a.submit {
 	color: #fff;
-	border: 1px solid #2373A8;
-	background: #2373A8;
-	background: -webkit-gradient(linear, left top, left bottom, from(#2C8FD1), to(#2373A8));
-	background: -moz-linear-gradient(top,  #2C8FD1,  #2373A8);
+	text-shadow: 0 -1px 1px #1A87B9;
+	background:#25A6E1;
+	background:-moz-linear-gradient(top,#25A6E1 0%,#188BC0 100%);
+	background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#25A6E1),color-stop(100%,#188BC0));
+	background:linear-gradient(top,#25A6E1 0%,#188BC0 100%);
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#25A6E1',endColorstr='#188BC0',GradientType=0);
+	border:1px solid #2C8FD1;
+
 }
 input[type=submit]:hover,
@@ -1442,9 +1458,9 @@
 input[type=button]:focus,
 a.submit:focus {
-	background: #2373A8;
-	background: -webkit-gradient(linear, left top, left bottom, from(#2373A8), to(#2C8FD1));
-	background: -moz-linear-gradient(top,  #2373A8,  #2C8FD1);
-	filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#2373A8', endColorstr='#2C8FD1');
-	border: 1px solid #2C8FD1;
+	background:#188BC0;
+	background:-moz-linear-gradient(top,#188BC0 0%,#25A6E1 100%);
+	background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#188BC0),color-stop(100%,#25A6E1));
+	background:linear-gradient(top,#188BC0 0%,#25A6E1 100%);
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#25A6E1',endColorstr='#25A6E1',GradientType=0);
 }
 /* suppression et reset */
@@ -1457,5 +1473,5 @@
 	background: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#dfdfdf));
 	background: -moz-linear-gradient(top,  #f5f5f5,  #dfdfdf);
-	text-shadow: none;
+	text-shadow:1px 1px 0px #fff;
 	}
 a.button:hover,
@@ -1467,8 +1483,8 @@
 input[type=submit].reset:focus,
 input[type=submit].delete:focus {
-	background: #dfdfdf;
-	background: -webkit-gradient(linear, left top, left bottom, from(#dfdfdf), to(#f5f5f5));
-	background: -moz-linear-gradient(top,  #dfdfdf,  #f5f5f5);
-	filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#e5e5e5', endColorstr='#f5f5f5');
+	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #e9e9e9), color-stop(1, #f9f9f9) );
+	background:-moz-linear-gradient( center top, #e9e9e9 5%, #f9f9f9 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e9e9e9', endColorstr='#f9f9f9');
+	background-color:#e9e9e9;
 	}
 a.delete,
@@ -1509,5 +1525,5 @@
 	font-size: 1.4rem;
 }
-.button.add:hover, .button.add:focus {
+.button.add:hover, .button.add:active, .button.add:focus {
 	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #8cb82b), color-stop(1, #9dce2c) );
 	background:-moz-linear-gradient( center top, #8cb82b 5%, #9dce2c 100% );
@@ -1615,4 +1631,44 @@
 	border-color : #ccc;
 	background-color: #fff;
+}
+
+/* --------------------------------------------------------------- password indcator */
+.pw-table {
+	display: table;
+	margin-bottom: 1em;
+}
+.pw-cell {
+	display: table-cell;
+	margin-bottom: 1em;
+}
+#pwindicator {
+	display: table-cell;
+	vertical-align: bottom;
+	padding-left: 1.5em;
+	height: 3.8em;
+}
+#pwindicator .bar {
+	height: 6px;
+	margin-bottom: 4px;
+}
+.pw-very-weak .bar {
+	background: #900;
+	width: 30px;
+}
+.pw-weak .bar {
+	background: #c00;
+	width: 60px;
+}
+.pw-mediocre .bar {
+	background: #f60;
+	width: 90px;
+}
+.pw-strong .bar {
+	background: #060;
+	width: 120px;
+}
+.pw-very-strong .bar {
+	background: #0c0;
+	width: 150px;
 }
 
Index: admin/style/jsToolBar/jsToolBar.css
===================================================================
--- admin/style/jsToolBar/jsToolBar.css	(revision 1399)
+++ admin/style/jsToolBar/jsToolBar.css	(revision 1475)
@@ -82,19 +82,17 @@
 	display: block;
 	list-style: none;
-	margin: 0 0 0 -5px;
+	margin: 0;
 	padding: 0 0 5px 0;
 	background: #dfdfdf;
 	border-top: 1px solid #999;
-	font-size: 90%;
-	font-weight: bold;
 }
 .jstSwitcher li {
 	display: inline;
 	margin: 0 0 0 5px;
-	padding: 2px 4px;
+	padding: 2px 8px;
 }
 .jstSwitcher li.jstSwitcherCurrent {
 	color: #fff;
-	background: #999;
+	background: #575859;
 	border-radius: 0 0 2px 2px;
 }
Index: admin/update.php
===================================================================
--- admin/update.php	(revision 1358)
+++ admin/update.php	(revision 1474)
@@ -27,5 +27,5 @@
 
 $updater = new dcUpdate(DC_UPDATE_URL,'dotclear',DC_UPDATE_VERSION,DC_TPL_CACHE.'/versions');
-$new_v = $updater->check(DC_VERSION);
+$new_v = $updater->check(DC_VERSION, !empty($_GET['nocache']));
 $zip_file = $new_v ? DC_BACKUP_PATH.'/'.basename($updater->getFileURL()) : '';
 $version_info = $new_v ? $updater->getInfoURL() : '';
@@ -168,5 +168,8 @@
 -------------------------------------------------------- */
 dcPage::open(__('Dotclear update'),
-	(!$step ? dcPage::jsPageTabs($default_tab) : ''),
+	(!$step ? 
+		dcPage::jsPageTabs($default_tab).
+		dcPage::jsLoad('js/_update.js')
+		: ''),
 	dcPage::breadcrumb(
 		array(
@@ -176,4 +179,10 @@
 );
 
+if (!$core->error->flag()) {
+	if (!empty($_GET['nocache'])) {
+		dcPage::message(__('Manual checking of update done successfully.'));
+	}
+}
+
 if (!$step)
 {
@@ -181,5 +190,9 @@
 	if (empty($new_v))
 	{
-		echo '<p><strong>'.__('No newer Dotclear version available.').'</strong></p>';
+		echo '<p><strong>'.__('No newer Dotclear version available.').'</strong></p>'.
+		'<form action="'.$p_url.'" method="get">'.
+		'<p><input type="hidden" name="nocache" value="1" />'.
+		'<input type="submit" value="'.__('Force checking update Dotclear').'" /></p>'.
+		'</form>';
 	}
 	else
@@ -187,5 +200,5 @@
 		echo
 			'<p class="static-msg">'.sprintf(__('Dotclear %s is available.'),$new_v).
-				($version_info ? ' <a href="'.$version_info.'">('.__('information about this version').')</a>' : '').
+				($version_info ? ' <a href="'.$version_info.'">('.__('Information about this version').')</a>' : '').
 				'</p>'.
 		
@@ -233,5 +246,5 @@
 	'<p class="message">'.
 	__("Congratulations, you're one click away from the end of the update.").
-	' <strong><a href="index.php?logout=1">'.__('Finish the update.').'</a></strong>'.
+	' <strong><a href="index.php?logout=1">'.__('Finish the update').'</a>.</strong>'.
 	'</p>';
 }
Index: admin/user.php
===================================================================
--- admin/user.php	(revision 1399)
+++ admin/user.php	(revision 1474)
@@ -226,7 +226,7 @@
 '<p><label for="user_firstname">'.__('First Name:').'</label> '.
 form::field('user_firstname',20,255,html::escapeHTML($user_firstname)).
-'</label></p>'.
-
-'<p><label for="user_displayname">'.__('Display name:').' '.
+'</p>'.
+
+'<p><label for="user_displayname">'.__('Display name:').'</label> '.
 form::field('user_displayname',20,255,html::escapeHTML($user_displayname)).
 '</p>'.
Index: admin/users.php
===================================================================
--- admin/users.php	(revision 1426)
+++ admin/users.php	(revision 1474)
@@ -39,5 +39,5 @@
 
 
-# Get users
+#?Get users
 $page = !empty($_GET['page']) ? $_GET['page'] : 1;
 $nb_per_page =  30;
@@ -134,5 +134,5 @@
 	form::combo('order',$order_combo,$order).'</p>'.
 	'<p><span class="label ib">'.__('Show').'</span> <label for="nb" class="classic">'.	
-	form::field('nb',3,3,$nb_per_page).' '.__('users per page').'</p> '.
+	form::field('nb',3,3,$nb_per_page).' '.__('users per page').'</label></p> '.
 	'</div>'.
 	'</div>'.
Index: admin/users_actions.php
===================================================================
--- admin/users_actions.php	(revision 1399)
+++ admin/users_actions.php	(revision 1477)
@@ -255,5 +255,4 @@
 	
 	echo 
-	'<h2><a href="users.php">'.__('Users').'</a> &rsaquo; <span class="page-title">'.__('Permissions').'</span></h2>'.
 	'<p>'.sprintf(
 		__('You are about to change permissions on the following blogs for users %s.'),
Index: inc/admin/lib.pager.php
===================================================================
--- inc/admin/lib.pager.php	(revision 1415)
+++ inc/admin/lib.pager.php	(revision 1476)
@@ -42,5 +42,10 @@
 			$pager->html_next = $this->html_next;
 			$pager->var_page = 'page';
-			
+			$entries = array();
+			if (isset($_REQUEST['entries'])) {
+				foreach ($_REQUEST['entries'] as $v) {
+					$entries[(integer)$v]=true;
+				}
+			}
 			$html_block =
 			'<table class="clear"><tr>'.
@@ -66,5 +71,5 @@
 			while ($this->rs->fetch())
 			{
-				echo $this->postLine();
+				echo $this->postLine(isset($entries[$this->rs->post_id]));
 			}
 			
@@ -75,5 +80,5 @@
 	}
 	
-	private function postLine()
+	private function postLine($checked)
 	{
 		if ($this->core->auth->check('categories',$this->core->blog->id)) {
@@ -87,5 +92,5 @@
 			html::escapeHTML($this->rs->cat_title));
 		} else {
-			$cat_title = __('None');
+			$cat_title = __('(No cat)');
 		}
 		
@@ -128,5 +133,5 @@
 		$res .=
 		'<td class="nowrap">'.
-		form::checkbox(array('entries[]'),$this->rs->post_id,'','','',!$this->rs->isEditable()).'</td>'.
+		form::checkbox(array('entries[]'),$this->rs->post_id,$checked,'','',!$this->rs->isEditable()).'</td>'.
 		'<td class="maximal"><a href="'.$this->core->getPostAdminURL($this->rs->post_type,$this->rs->post_id).'">'.
 		html::escapeHTML($this->rs->post_title).'</a></td>'.
Index: inc/core/class.dc.blog.php
===================================================================
--- inc/core/class.dc.blog.php	(revision 1491)
+++ inc/core/class.dc.blog.php	(revision 1492)
@@ -634,18 +634,55 @@
 	private function checkCategory($title,$url,$id=null)
 	{
-		$strReq = 'SELECT cat_id '.
-				'FROM '.$this->prefix.'category '.
-				"WHERE cat_url = '".$this->con->escape($url)."' ".
-				"AND blog_id = '".$this->con->escape($this->id)."' ";
-		
-		if ($id !== null) {
-			$strReq .= 'AND cat_id <> '.(integer) $id.' ';
-		}
+		# Let's check if URL is taken...
+		$strReq = 
+			'SELECT cat_url FROM '.$this->prefix.'category '.
+			"WHERE cat_url = '".$this->con->escape($url)."' ".
+			($id ? 'AND cat_id <> '.(integer) $id. ' ' : '').
+			"AND blog_id = '".$this->con->escape($this->id)."' ".
+			'ORDER BY cat_url DESC';
 		
 		$rs = $this->con->select($strReq);
 		
-		if (!$rs->isEmpty()) {
-			throw new Exception(__('Category URL must be unique.'));
-		}
+		if (!$rs->isEmpty())
+		{
+			if ($this->con->driver() == 'mysql') {
+				$clause = "REGEXP '^".$this->con->escape($url)."[0-9]+$'";
+			} elseif ($this->con->driver() == 'pgsql') {
+				$clause = "~ '^".$this->con->escape($url)."[0-9]+$'";
+			} else {
+				$clause = "LIKE '".$this->con->escape($url)."%'";
+			}
+			$strReq = 
+				'SELECT cat_url FROM '.$this->prefix.'category '.
+				"WHERE cat_url ".$clause.' '.
+				($id ? 'AND cat_id <> '.(integer) $id. ' ' : '').
+				"AND blog_id = '".$this->con->escape($this->id)."' ".
+				'ORDER BY cat_url DESC ';
+			
+			$rs = $this->con->select($strReq);
+			$a = array();
+			while ($rs->fetch()) {
+				$a[] = $rs->cat_url;
+			}
+			
+			natsort($a);
+			$t_url = end($a);
+			
+			if (preg_match('/(.*?)([0-9]+)$/',$t_url,$m)) {
+				$i = (integer) $m[2];
+				$url = $m[1];
+			} else {
+				$i = 1;
+			}
+			
+			return $url.($i+1);
+		}
+		
+		# URL is empty?
+		if ($url == '') {
+			throw new Exception(__('Empty category URL'));
+		}
+		
+		return $url;
 	}
 	
@@ -669,5 +706,5 @@
 		
 		# Check if title or url are unique
-		$this->checkCategory($cur->cat_title,$cur->cat_url,$id);
+		$cur->cat_url = $this->checkCategory($cur->cat_title,$cur->cat_url,$id);
 		
 		if ($cur->cat_desc !== null) {
Index: inc/core/class.dc.media.php
===================================================================
--- inc/core/class.dc.media.php	(revision 1280)
+++ inc/core/class.dc.media.php	(revision 1468)
@@ -30,4 +30,5 @@
 	
 	public $thumb_tp = '%s/.%s_%s.jpg';	///< <b>string</b> Thumbnail file pattern
+	public $thumb_tp_alpha = '%s/.%s_%s.png'; ///< <b>string</b> Thumbnail file pattern (with alpha layer)
 	
 	/**
@@ -298,6 +299,7 @@
 			$f->media_thumb = array();
 			$p = path::info($f->relname);
-			$thumb = sprintf($this->thumb_tp,$this->root.'/'.$p['dirname'],$p['base'],'%s');
-			$thumb_url = sprintf($this->thumb_tp,$this->root_url.$p['dirname'],$p['base'],'%s');
+			$alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
+			$thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$this->root.'/'.$p['dirname'],$p['base'],'%s');
+			$thumb_url = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$this->root_url.$p['dirname'],$p['base'],'%s');
 			
 			# Cleaner URLs
@@ -920,5 +922,6 @@
 		
 		$p = path::info($file);
-		$thumb = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s');
+		$alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
+		$thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
 		
 		try
@@ -939,5 +942,5 @@
 					$rate = ($s[0] < 100 ? 95 : ($s[0] < 600 ? 90 : 85));
 					$img->resize($s[0],$s[0],$s[1]);
-					$img->output('jpeg',$thumb_file,$rate);
+					$img->output(($alpha ? 'png' : 'jpeg'),$thumb_file,$rate);
 					$img->loadImage($file);
 				}
@@ -958,8 +961,10 @@
 		{
 			$p = path::info($file->relname);
-			$thumb_old = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s');
+			$alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
+			$thumb_old = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
 			
 			$p = path::info($newFile->relname);
-			$thumb_new = sprintf($this->thumb_tp,$p['dirname'],$p['base'],'%s');
+			$alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
+			$thumb_new = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),$p['dirname'],$p['base'],'%s');
 			
 			foreach ($this->thumb_sizes as $suffix => $s) {
@@ -974,5 +979,6 @@
 	{
 		$p = path::info($f);
-		$thumb = sprintf($this->thumb_tp,'',$p['base'],'%s');
+		$alpha = ($p['extension'] == 'png') || ($p['extension'] == 'PNG');
+		$thumb = sprintf(($alpha ? $this->thumb_tp_alpha : $this->thumb_tp),'',$p['base'],'%s');
 		
 		foreach ($this->thumb_sizes as $suffix => $s) {
Index: locales/en/main.po
===================================================================
--- locales/en/main.po	(revision 1425)
+++ locales/en/main.po	(revision 1468)
@@ -2139,4 +2139,7 @@
 msgstr ""
 
+msgid "Are you sure you want to delete this backup?"
+msgstr ""
+
 msgid "Zip file content"
 msgstr ""
@@ -2787,2 +2790,5 @@
 msgid "The following error was encountered while trying to read the database:"
 msgstr ""
+
+msgid "(No cat)"
+msgstr "(none)"
Index: locales/fr/main.po
===================================================================
--- locales/fr/main.po	(revision 1454)
+++ locales/fr/main.po	(revision 1484)
@@ -95,5 +95,5 @@
 
 msgid "This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems"
-msgstr "\"Ce mode vous permet de vous connecter sans activer de plugins. Il peut être utile pour résoudre un problème de compatibilité"
+msgstr "Ce mode vous permet de vous connecter sans activer de plugins. Il peut être utile pour résoudre un problème de compatibilité"
 
 msgid "Disable or delete any plugin suspected to cause trouble, then log out and log back in normally."
@@ -1038,5 +1038,5 @@
 #, fuzzy, php-format
 msgid "Path <strong>%s</strong> is not writable."
-msgstr "Le répertoire de cache %s n'est pas accessible en écriture."
+msgstr "Le répertoire de cache <strong>%s</strong> n'est pas accessible en écriture."
 
 #, fuzzy
@@ -1123,5 +1123,5 @@
 #, php-format
 msgid "You can change your user language in your <a href=\"%1$s\">preferences</a> or change your blog's main language in your <a href=\"%2$s\">blog settings</a>."
-msgstr "Vous pouvez changer votre langue d'utilisateur dans vos <a href=\"%1$s\">préférences</a> ou changer la langue principale de votre blog dans vos <a href=\"%2$s\">paramètres de blog</a>."
+msgstr "Vous pouvez changer votre langue d'utilisateur dans vos <a href=\"%1$s\">préférences</a> ou changer la langue principale de votre blog dans vos <a href=\"%2$s\">paramètres du blog</a>."
 
 msgid "Installed languages"
@@ -1193,4 +1193,10 @@
 msgstr "Gestionnaire de médias"
 
+msgid "Go to %s folder"
+msgstr "Aller au dossier %s"
+
+msgid "Media details of %s"
+msgstr "Détails du média %s"
+
 msgid "confirm removal"
 msgstr "Confirmer la suppression"
@@ -1784,5 +1790,5 @@
 
 msgid "If you want to change your email or password you must provide your current password."
-msgstr "Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe."
+msgstr "Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe actuel."
 
 msgid "No favorite selected"
@@ -1820,5 +1826,5 @@
 
 msgid "If you have changed this user email or password you must provide your current password to save these modifications."
-msgstr "Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe."
+msgstr "Si vous voulez changer votre adresse email ou votre mot de passe, vous devez indiquer votre mot de passe actuel pour enregistrer ces modifications."
 
 msgid "My options"
@@ -1994,7 +2000,13 @@
 msgstr "Les fichiers suivants de votre installation de Dotclear ne peuvent pas être écrits. Veuillez corriger la situation ou <a href=\"http://fr.dotclear.org/download\">mettre à jour manuellement</a>."
 
+msgid "Manual checking of update done successfully."
+msgstr "Vérification manuelle de mise à jour effectuée avec succès."
+
 msgid "No newer Dotclear version available."
 msgstr "Aucune nouvelle version de Dotclear n'est disponible."
 
+msgid "Force checking update Dotclear"
+msgstr "Forcer la vérification de mise à jour de Dotclear"
+
 #, php-format
 msgid "Dotclear %s is available."
@@ -2133,9 +2145,9 @@
 #, fuzzy
 msgid "Go to the content"
-msgstr "Voir ce billet sur le site"
+msgstr "Aller au contenu"
 
 #, fuzzy
 msgid "Go to the menu"
-msgstr "Aller sur le site"
+msgstr "Aller au menu"
 
 msgid "Go to site"
@@ -2201,5 +2213,5 @@
 
 msgid "Users with posts cannot be deleted."
-msgstr "Les utilisateurs ayant écrit des billets ne peuvent être effacées."
+msgstr "Les utilisateurs ayant écrit des billets ne peuvent être supprimés."
 
 #, php-format
@@ -2243,4 +2255,7 @@
 msgstr "Êtes-vous certain de vouloir supprimer le thème \"%s\" ?"
 
+msgid "Are you sure you want to delete this backup?"
+msgstr "Êtes-vous certain de vouloir supprimer cette sauvegarde ?"
+
 msgid "Zip file content"
 msgstr "Contenu du fichier zip"
@@ -2258,4 +2273,7 @@
 msgstr "Vous avez des modifications non sauvegardées. Changer de format vous fera perdre ces modifications. Continuer ?"
 
+msgid "Warning: post format change will not convert existing content. You will need to apply new format by yourself. Proceed anyway?"
+msgstr "Attention : le changement de syntaxe ne transformera pas les balises des contenus déjà saisis. Pensez à les réadapter après cette opération. Confirmez-vous ce changement de syntaxe ?"
+
 msgid "Loading enhanced uploader, please wait."
 msgstr "Chargement de l'interface avancée."
@@ -2506,5 +2524,5 @@
 #, fuzzy
 msgid "You are not allowed to reset categories order"
-msgstr "Vous n'êtes pas autorisé à supprimer des catégories"
+msgstr "Vous n'êtes pas autorisé à réinitialiser l'ordre des catégories"
 
 msgid "Category URL must be unique."
@@ -3034,4 +3052,7 @@
 msgstr "Filtrer la liste des commentaires et rétroliens"
 
+msgid "comments per page"
+msgstr "commentaires par page"
+
 msgid "Filter users list"
 msgstr "Filtrer la liste des utilisateurs"
@@ -3060,2 +3081,50 @@
 msgid "Add an introduction to the page."
 msgstr "Ajoute une introduction à la page."
+
+msgid "(No cat)"
+msgstr "(aucune)"
+
+msgid "Password strength: %s"
+msgstr "Force du mot de passe : %s"
+
+msgid "very weak"
+msgstr "très faible"
+
+msgid "weak"
+msgstr "faible"
+
+msgid "mediocre"
+msgstr "moyen"
+
+msgid "strong"
+msgstr "fort"
+
+msgid "very strong"
+msgstr "très fort"
+
+msgid "Confirm new password:"
+msgstr "Confirmez le nouveau mot de passe :"
+
+msgid "Not selected"
+msgstr "Non sélectionné"
+
+msgid "Back to comments list"
+msgstr "Retour à la liste des commentaires"
+
+msgid "The current blog cannot be deleted."
+msgstr "Le blog courant ne peut être détruit."
+
+msgid "Only superadmin can delete a blog."
+msgstr "Seul un superadministrateur peut supprimer un blog."
+
+msgid "Invalid publication date"
+msgstr "Date de publication invalide."
+
+msgid "Image alignment:"
+msgstr "Alignement de l'image :"
+
+msgid "Finish the update"
+msgstr "Finir la mise à jour"
+
+msgid "Information about this version"
+psgstr "Informations sur cette version"
Index: locales/fr/plugins.po
===================================================================
--- locales/fr/plugins.po	(revision 1396)
+++ locales/fr/plugins.po	(revision 1483)
@@ -42,5 +42,5 @@
 
 msgid "blog settings"
-msgstr "Réglages du blog"
+msgstr "paramètres du blog"
 
 msgid "Value"
@@ -305,5 +305,5 @@
 
 msgid "No attachment."
-msgstr "Pas de fichier attaché"
+msgstr "Pas de fichier attaché."
 
 msgid "Add files to this entry"
@@ -1166,4 +1166,10 @@
 msgstr "Pages"
 
+msgid "My first page"
+msgstr "Ma première page"
+
+msgid "This is your first page. When you\'re ready to blog, log in to edit or delete it."
+msgstr "Ceci est votre première page. Quand vous serez prêt à bloguer, connectez-vous pour l'éditer ou la supprimer."
+
 #, php-format
 msgid "%d page"
@@ -1750,11 +1756,11 @@
 
 msgid "Custom sidebar"
-msgstr "Bandeau supplémentaire"
+msgstr "Volet supplémentaire"
 
 msgid "Update sidebars"
-msgstr "Mettre à jour les bandeaux"
+msgstr "Mettre à jour les volets"
 
 msgid "Reset sidebars"
-msgstr "Réinitialiser les bandeaux"
+msgstr "Réinitialiser les volets"
 
 msgid "Use of widgets"
@@ -1928,2 +1934,8 @@
 msgid "Edit theme files"
 msgstr "Modifier les fichiers du thème"
+
+msgid "Blog settings"
+msgstr "Paramètres du blog"
+
+msgid "Move widgets from this list to one of the sidebars."
+msgstr "Déplacez des widgets de cette liste vers l'un des volets."
Index: plugins/antispam/_admin.php
===================================================================
--- plugins/antispam/_admin.php	(revision 1207)
+++ plugins/antispam/_admin.php	(revision 1474)
@@ -59,5 +59,5 @@
 		if ($ttl != null && $ttl >=0) {
 			echo '<p>'.sprintf(__('All spam comments older than %s day(s) will be automatically deleted.'), $ttl).' '.
-			sprintf(__('You can modify this duration in the %s'),'<a href="blog_pref.php#antispam_moderation_ttl"> '.__('Blog preferences').'</a>').
+			sprintf(__('You can modify this duration in the %s'),'<a href="blog_pref.php#antispam_moderation_ttl"> '.__('Blog settings').'</a>').
 			'</p>';
 		}
Index: plugins/antispam/filters/class.dc.filter.iplookup.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.iplookup.php	(revision 1454)
+++ plugins/antispam/filters/class.dc.filter.iplookup.php	(revision 1468)
@@ -44,19 +44,13 @@
 		}
 
-		$match = array();
-
 		$bls = $this->getServers();
 		$bls = preg_split('/\s*,\s*/',$bls);
 
-		foreach ($bls as $bl)
-		{
+		foreach ($bls as $bl) {
 			if ($this->dnsblLookup($ip,$bl)) {
-				$match[] = $bl;
+				// Pass by reference $status to contain matching DNSBL
+				$status = $bl;
+				return true;
 			}
-		}
-
-		if (!empty($match)) {
-			$status = substr(implode(', ',$match),0,128);
-			return true;
 		}
 	}
Index: plugins/antispam/filters/class.dc.filter.linkslookup.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.linkslookup.php	(revision 1179)
+++ plugins/antispam/filters/class.dc.filter.linkslookup.php	(revision 1366)
@@ -64,18 +64,8 @@
 	private function getLinks($text)
 	{
-		$res = array();
-		
-		# href attribute on "a" tags
-		if (preg_match_all('/<a ([^>]+)>/ms', $text, $match, PREG_SET_ORDER))
-		{
-			for ($i = 0; $i<count($match); $i++)
-			{
-				if (preg_match('/href="(http:\/\/[^"]+)"/ms', $match[$i][1], $matches)) {
-					$res[] = $matches[1];
-				}
-			}
-		}
-		
-		return $res;
+		// href attribute on "a" tags is second match
+		preg_match_all('|<a.*?href="(http.*?)"|', $text, $parts);
+
+		return $parts[1];
 	}
 }
Index: plugins/antispam/index.php
===================================================================
--- plugins/antispam/index.php	(revision 1423)
+++ plugins/antispam/index.php	(revision 1474)
@@ -170,5 +170,5 @@
 	if ($moderationTTL != null && $moderationTTL >=0) {
 		echo '<p>'.sprintf(__('All spam comments older than %s day(s) will be automatically deleted.'), $moderationTTL).' '.
-		sprintf(__('You can modify this duration in the %s'),'<a href="blog_pref.php#antispam_moderation_ttl"> '.__('Blog preferences').'</a>').
+		sprintf(__('You can modify this duration in the %s'),'<a href="blog_pref.php#antispam_moderation_ttl"> '.__('Blog settings').'</a>').
 			'</p>';
 	}
@@ -212,5 +212,5 @@
 		'<td class="nowrap">'.form::checkbox(array('filters_active[]'),$fid,$f->active, '', '', false, 'title="'.__('Active').'"').'</td>'.
 		'<td class="nowrap">'.form::checkbox(array('filters_auto_del[]'),$fid,$f->auto_delete, '', '', false, 'title="'.__('Auto Del.').'"').'</td>'.
-		'<td class="nowrap" scope="raw">'.$f->name.'</td>'.
+		'<td class="nowrap" scope="row">'.$f->name.'</td>'.
 		'<td class="maximal">'.$f->description.'</td>'.
 		'<td class="status">'.$gui_link.'</td>'.
Index: plugins/attachments/_admin.php
===================================================================
--- plugins/attachments/_admin.php	(revision 1398)
+++ plugins/attachments/_admin.php	(revision 1468)
@@ -41,5 +41,5 @@
 				'<img src="'.$f->media_icon.'" alt="" title="'.$f->basename.'" /></a>'.
 				'<ul>'.
-				'<li><a class="media-link" href="media_item.php?id='.$f->media_id.'"'.
+				'<li><a class="media-link" href="media_item.php?id='.$f->media_id.'" '.
 				'title="'.$f->basename.'">'.$ftitle.'</a></li>'.
 				'<li>'.$f->media_dtstr.'</li>'.
Index: plugins/pages/_define.php
===================================================================
--- plugins/pages/_define.php	(revision 1179)
+++ plugins/pages/_define.php	(revision 1442)
@@ -16,5 +16,5 @@
 	/* Description*/	"Serve entries as simple web pages",
 	/* Author */		"Olivier Meunier",
-	/* Version */		'1.2',
+	/* Version */		'1.3',
 	array(
 		'permissions' =>	'contentadmin,pages',
@@ -22,3 +22,2 @@
 	)
 );
-?>
Index: plugins/pages/_install.php
===================================================================
--- plugins/pages/_install.php	(revision 1445)
+++ plugins/pages/_install.php	(revision 1445)
@@ -0,0 +1,55 @@
+<?php
+# -- BEGIN LICENSE BLOCK ---------------------------------------
+#
+# This file is part of Dotclear 2.
+#
+# Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear
+# Licensed under the GPL version 2.0 license.
+# See LICENSE file or
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+#
+# -- END LICENSE BLOCK -----------------------------------------
+
+if (!defined('DC_CONTEXT_ADMIN')){return;}
+
+$version = $core->plugins->moduleInfo('pages','version');
+if (version_compare($core->getVersion('pages'),$version,'>=')) {
+	return;
+}
+
+/* Create first page
+-------------------------------------------------------- */
+$core->setBlog('default');
+
+$core->blog->settings->addNamespace('pages');
+
+$params = array(
+	'post_type' => 'page',
+	'no_content' => true
+);
+$counter = $core->blog->getPosts($params,true);
+
+If( $counter->f(0) == 0 && $core->blog->settings->pages->firstpage == null ) {
+	
+	$core->blog->settings->pages->put('firstpage',true, 'boolean');
+
+	$cur = $core->con->openCursor($core->prefix.'post');
+	$cur->user_id = $core->auth->userID();
+	$cur->post_type = 'page';
+	$cur->post_format = 'xhtml';
+	$cur->post_lang = $core->blog->settings->system->lang;
+	$cur->post_title = __('My first page');
+	$cur->post_content = __('<p>'.__('This is your first page. When you\'re ready to blog, log in to edit or delete it.').'</p>');
+	$cur->post_content_xhtml = $cur->post_content;
+	$cur->post_excerpt = '';
+	$cur->post_excerpt_xhtml = $cur->post_excerpt;
+	$cur->post_status = 1;
+	$cur->post_open_comment = 0;
+	$cur->post_open_tb = 0;
+	$post_id = $core->blog->addPost($cur);
+	
+}
+
+$core->setVersion('pages',$version);
+return true;
+?>
Index: plugins/pages/page.php
===================================================================
--- plugins/pages/page.php	(revision 1454)
+++ plugins/pages/page.php	(revision 1480)
@@ -455,12 +455,12 @@
 	
 	echo
-	'<p><label for="post_status">'.__('Page status:').'</label> '.
+	'<p><label for="post_status" class="ib">'.__('Page status:').'</label> '.
 	form::combo('post_status',$status_combo,$post_status,'','',!$can_publish).
 	'</p>'.
 	
-	'<p><label for="post_dt">'.__('Published on:').'</label>'.
+	'<p><label for="post_dt" class="ib">'.__('Published on:').'</label>'.
 	form::field('post_dt',16,16,$post_dt,($bad_dt ? 'invalid' : '')).'</p>'.
 	
-	'<p><label for="post_format">'.__('Text formating:').'</label>'.
+	'<p><label for="post_format" class="ib">'.__('Text formating:').'</label>'.
 	form::combo('post_format',$formaters_combo,$post_format).
 	($post_id && $post_format != 'xhtml' ? '<a class="button" href="'.html::escapeURL($redir_url).'&amp;id='.$post_id.'&amp;xconv=1">'.__('Convert to XHTML').'</a>' : '').
@@ -493,13 +493,13 @@
 	'</p>'.
 	
-	'<p><label for="post_lang">'.__('Page lang:').'</label>'.
+	'<p><label for="post_lang" class="ib">'.__('Page lang:').'</label>'.
 	form::combo('post_lang',$lang_combo,$post_lang).'</p>'.
 	
-	'<p><label for="post_password">'.__('Page password:').'</label>'.
+	'<p><label for="post_password" class="ib">'.__('Page password:').'</label>'.
 	form::field('post_password',10,32,html::escapeHTML($post_password),'maximal').
 	'</p>'.
 	
-	'<div class="lockable">'.
-	'<p><label for="post_url">'.__('Basename:').'</label>'.
+	'<div class="lockable ib">'.
+	'<p><label for="post_url" class="ib">'.__('Basename:').'</label>'.
 	form::field('post_url',10,255,html::escapeHTML($post_url),'maximal').
 	'</p>'.
@@ -512,5 +512,5 @@
 	{
 		echo
-		'<h3 class="clear">'.__('Attachments').'</h3>';
+		'<h4 class="clear">'.__('Attachments').'</h4>';
 		foreach ($post_media as $f)
 		{
@@ -541,5 +541,5 @@
 		
 		if (empty($post_media)) {
-			echo '<p>'.__('No attachment.').'</p>';
+			echo '<p class="form-note">'.__('No attachment.').'</p>';
 		}
 		echo '<p><a class="button" href="media.php?post_id='.$post_id.'">'.__('Add files to this page').'</a></p>';
Index: plugins/simpleMenu/index.php
===================================================================
--- plugins/simpleMenu/index.php	(revision 1358)
+++ plugins/simpleMenu/index.php	(revision 1474)
@@ -233,5 +233,5 @@
 				
 					// All done successfully, return to menu items list
-					http::redirect($p_url.'&added=1');
+					http::redirect($p_url.'&amp;added=1');
 				} else {
 					throw new Exception(__('Label and URL of menu item are mandatory.'));
@@ -268,5 +268,5 @@
 				
 				// All done successfully, return to menu items list
-				http::redirect($p_url.'&removed=1');
+				http::redirect($p_url.'&amp;removed=1');
 			} else {
 				throw new Exception(__('No menu items selected.'));
@@ -302,5 +302,5 @@
 
 			// All done successfully, return to menu items list
-			http::redirect($p_url.'&updated=1');
+			http::redirect($p_url.'&amp;updated=1');
 		}
 		catch (Exception $e) {
@@ -339,5 +339,5 @@
 
 			// All done successfully, return to menu items list
-			http::redirect($p_url.'&neworder=1');
+			http::redirect($p_url.'&amp;neworder=1');
 		} 
 		catch (Exception $e) {
@@ -402,5 +402,5 @@
 		case 1:
 			// Selection du type d'item
-			echo '<form id="additem" action="'.$p_url.'&add=2" method="post">';
+			echo '<form id="additem" action="'.$p_url.'&amp;add=2" method="post">';
 			echo '<fieldset><legend>'.__('Select type').'</legend>';
 			echo '<p class="field"><label for="item_type" class="classic">'.__('Type of item menu:').'</label>'.form::combo('item_type',$items_combo,'').'</p>';
@@ -412,5 +412,5 @@
 			if ($items[$item_type][1]) {
 				// Choix à faire
-				echo '<form id="additem" action="'.$p_url.'&add=3" method="post">';
+				echo '<form id="additem" action="'.$p_url.'&amp;add=3" method="post">';
 				echo '<fieldset><legend>'.$item_type_label.'</legend>';
 				switch ($item_type) {
@@ -449,5 +449,5 @@
 		case 3:
 			// Libellé et description
-			echo '<form id="additem" action="'.$p_url.'&add=4" method="post">';
+			echo '<form id="additem" action="'.$p_url.'&amp;add=4" method="post">';
 			echo '<fieldset><legend>'.$item_type_label.($item_select_label != '' ? ' ('.$item_select_label.')' : '').'</legend>';
 			echo '<p class="field"><label for="item_label" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.
@@ -467,5 +467,5 @@
 // Liste des items
 if (!$step) {
-	echo '<form id="menuitemsappend" action="'.$p_url.'&add=1" method="post">';
+	echo '<form id="menuitemsappend" action="'.$p_url.'&amp;add=1" method="post">';
 	echo '<p class="top-add">'.$core->formNonce().'<input class="button add" type="submit" name="appendaction" value="'.__('Add an item').'" /></p>';
 	echo '</form>';
Index: plugins/tags/_admin.php
===================================================================
--- plugins/tags/_admin.php	(revision 1454)
+++ plugins/tags/_admin.php	(revision 1471)
@@ -229,11 +229,16 @@
 		if ($action == 'tags')
 		{
-			echo
-			'<h2 class="page-title">'.__('Add tags to entries').'</h2>'.
+			echo dcPage::breadcrumb(
+				array(
+					html::escapeHTML($core->blog->name) => '',
+					__('Entries') => 'posts.php',
+					'<span class="page-title">'.__('Add tags to entries').'</span>' => ''
+			)).
 			'<form action="'.$form_uri.'" method="post">'.
+			$hidden_fields->getEntries().
 			'<div><label for="new_tags" class="area">'.__('Tags to add:').'</label> '.
 			form::textarea('new_tags',60,3).
 			'</div>'.
-			$hidden_fields.
+			$hidden_fields->getHidden().
 			$core->formNonce().
 			form::hidden(array('action'),'tags').
@@ -259,6 +264,10 @@
 				}
 			}
-			
-			echo '<h2 class="page-title">'.__('Remove selected tags from entries').'</h2>';
+			echo dcPage::breadcrumb(
+				array(
+					html::escapeHTML($core->blog->name) => '',
+					__('Entries') => 'posts.php',
+					'<span class="page-title">'.__('Remove selected tags from entries').'</span>' => ''
+			));
 			
 			if (empty($tags)) {
Index: plugins/tags/tag_posts.php
===================================================================
--- plugins/tags/tag_posts.php	(revision 1358)
+++ plugins/tags/tag_posts.php	(revision 1480)
@@ -130,6 +130,7 @@
 	{
 		echo
+		'<div class="fieldset">'.
 		'<form action="'.$this_url.'" method="post">'.
-		'<div class="fieldset"><h3>'.__('Actions for this tag').'</h3>'.
+		'<h3>'.__('Actions for this tag').'</h3>'.
 		'<p><label for="new_tag_id">'.__('Edit tag name:').'</label>'.
 		form::field('new_tag_id',20,255,html::escapeHTML($tag)).
@@ -161,5 +162,5 @@
 	'<p class="col right"><label for="action" class="classic">'.__('Selected entries action:').'</label> '.
 	form::combo('action',$combo_action).
-	'<input type="submit" value="'.__('ok').'" /></p>'.
+	'<input type="submit" value="'.__('OK').'" /></p>'.
 	form::hidden('post_type','').
 	form::hidden('redir',$p_url.'&amp;m=tag_posts&amp;tag='.
Index: plugins/userPref/index.php
===================================================================
--- plugins/userPref/index.php	(revision 1358)
+++ plugins/userPref/index.php	(revision 1474)
@@ -82,5 +82,5 @@
 	return
 	'<tr class="line">'.
-	'<td scope="raw"><label for="s_'.$id.'">'.sprintf($slabel,html::escapeHTML($id)).'</label></td>'.
+	'<td scope="row"><label for="s_'.$id.'">'.sprintf($slabel,html::escapeHTML($id)).'</label></td>'.
 	'<td>'.$field.'</td>'.
 	'<td>'.$s['type'].'</td>'.
Index: plugins/widgets/class.widgets.php
===================================================================
--- plugins/widgets/class.widgets.php	(revision 1454)
+++ plugins/widgets/class.widgets.php	(revision 1474)
@@ -246,5 +246,5 @@
 					'<p><label for="'.$wfid.'">'.$s['title'].'</label> '.
 					form::textarea(array($iname,$wfid),30,5,html::escapeHTML($s['value']),'maximal').
-					'</label></p>';
+					'</p>';
 					break;
 				case 'check':
Index: plugins/widgets/index.php
===================================================================
--- plugins/widgets/index.php	(revision 1454)
+++ plugins/widgets/index.php	(revision 1483)
@@ -197,5 +197,6 @@
 echo
 '<form id="listWidgets" action="'.$p_url.'" method="post"  class="widgets">'.
-'<fieldset><legend>'.__('Available widgets').'</legend>'.
+'<h3>'.__('Available widgets').'</h3>'.
+__('Move widgets from this list to one of the sidebars.').
 '<div id="widgets">';
 
@@ -205,5 +206,5 @@
 	'<div>'.form::hidden(array('w[void][0][id]'),html::escapeHTML($w->id())).
 	'<p class="widget-name">'.form::field(array('w[void][0][order]'),2,3,0,'hideControl').' '.
-	$w->name().($w->desc() != '' ? ' <span class="form-note">('.__($w->desc()).')</span>' : '').'</p>'.
+	$w->name().($w->desc() != '' ? ' <span class="form-note">'.__($w->desc()).'</span>' : '').'</p>'.
 	'<p class="js-remove"><label class="classic">'.__('Append to:').'</label> '.
 	form::combo(array('addw['.$w->id().']'),$append_combo).'</p>'.
@@ -215,5 +216,4 @@
 echo
 '</div>'.
-'</fieldset>'.
 '<p><input type="submit" class="js-remove" name="append" value="'.__('Add widgets to sidebars').'" />'.
 $core->formNonce().'</p>'.
@@ -223,5 +223,5 @@
 # Nav sidebar
 echo
-'<div id="sidebarNav" class="widgets">'.
+'<div id="sidebarNav" class="widgets fieldset">'.
 sidebarWidgets('dndnav',__('Navigation sidebar'),$widgets_nav,'nav',$__default_widgets['nav'],$j).
 '</div>';
@@ -229,5 +229,5 @@
 # Extra sidebar
 echo
-'<div id="sidebarExtra" class="widgets">'.
+'<div id="sidebarExtra" class="widgets fieldset">'.
 sidebarWidgets('dndextra',__('Extra sidebar'),$widgets_extra,'extra',$__default_widgets['extra'],$j).
 '</div>';
@@ -235,5 +235,5 @@
 # Custom sidebar
 echo
-'<div id="sidebarCustom" class="widgets">'.
+'<div id="sidebarCustom" class="widgets fieldset">'.
 sidebarWidgets('dndcustom',__('Custom sidebar'),$widgets_custom,'custom',$__default_widgets['custom'],$j).
 '</div>';
@@ -316,5 +316,5 @@
 function sidebarWidgets($id,$title,$widgets,$pr,$default_widgets,&$j)
 {
-	$res = '<fieldset><legend>'.$title.'</legend><div id="'.$id.'">';
+	$res = '<h3>'.$title.'</h3><div id="'.$id.'">';
 	
 	if (!($widgets instanceof dcWidgets))
@@ -335,5 +335,5 @@
 		'<div>'.form::hidden(array($iname.'[id]'),html::escapeHTML($w->id())).
 		'<p class="widget-name">'.form::field(array($iname.'[order]'),2,3,(string) $i,'js-hide','',0,'title="'.__('order').'"').' '.
-		$w->name().($w->desc() != '' ? ' <span class="form-note">('.__($w->desc()).')</span>' : '').'</p>'.
+		$w->name().($w->desc() != '' ? ' <!-- <span class="form-note">'.__($w->desc()).'</span> -->' : '').'</p>'.
 		'<p class="removeWidget js-remove"><label class="classic">'.
 		form::checkbox(array($iname.'[_rem]'),'1',0).' '.__('Remove widget').
@@ -346,5 +346,5 @@
 	}
 	
-	$res .= '</div></fieldset>';
+	$res .= '</div>';
 	
 	return $res;
Index: plugins/widgets/style.css
===================================================================
--- plugins/widgets/style.css	(revision 1301)
+++ plugins/widgets/style.css	(revision 1483)
@@ -1,53 +1,51 @@
 #listWidgets {
 	float: left;
-	width: 33%;
+	width: 45%;
+	background: #eee;
+	padding: 1.5em 1%; 
+	border: 1px solid #ccc;
+	margin-left: 1.5em;
+}
+#widgets .widget-name {
+	background: #fff;
+	min-height: 3em;
+}
+#listWidgets h3 {
+	color: #333;
 }
 
 #sidebarsWidgets {
 	float: left;
-	width: 65%;
-	margin-left: 1%;
+	width: 45%;
+	margin-left: 3%;
+	padding: 0 1%;
 }
-#sidebarNav {
-	float: left;
-	width: 50%;
-	margin-left: 0%;
-}
-#sidebarExtra {
-	float: left;
-	width: 49%;
-	margin-left: 1%;
-}
-#sidebarCustom {
-	float: left;
-	width: 100%;
-}
-
 #sidebarsControl {
 	clear: left;
 }
+.widgets.fieldset {
+	margin-bottom: 2em;
+}
 
-#widgets, #dndnav, #dndextra {
+#widgets, #dndnav, #dndextra, #dndcustom {
 	padding: 1em 0;
 }
 
-.widgets fieldset {
-	border: 1px solid #999;
-}
-.widgets legend {
-	border: 1px solid #999;
-}
-
-.widgets p.widget-name {
-	background: #F0EFEA;
+.widget-name {
+	background: #eef;
 	color: #000;
-	padding: 4px;
+	padding: 4px 6px;
 	margin: 0.5em 0 0 0;
 	border-width: 1px 1px 1px 1px;
 	border-style: solid;
-	border-color: #bbb;
+	border-color: #999;
 	font-weight: bold;
 }
-.widgets p.widget-name img {
+.widget-name span {
+	display: block;
+	font-style: normal;
+	font-size: 1.1rem;
+}
+.widget-name img {
 	cursor: pointer;
 	margin-bottom: -1px;
@@ -58,6 +56,6 @@
 	border-style: solid;
 	border-color: #666;
-	padding: 4px;
-	background: #E5E3DA;
+	padding: 4px 6px;
+	background: #f5f5f5;
 }
 
