Index: admin/blog_pref.php
===================================================================
--- admin/blog_pref.php	(revision 2189)
+++ admin/blog_pref.php	(revision 2198)
@@ -235,4 +235,5 @@
 		$blog_settings->system->put('nb_post_per_page',$nb_post_per_page);
 		$blog_settings->system->put('use_smilies',!empty($_POST['use_smilies']));
+		$blog_settings->system->put('inc_subcats',!empty($_POST['inc_subcats']));
 		$blog_settings->system->put('media_img_t_size',$media_img_t_size);
 		$blog_settings->system->put('media_img_s_size',$media_img_s_size);
@@ -528,4 +529,8 @@
 	form::checkbox('short_feed_items','1',$blog_settings->system->short_feed_items).
 	__('Truncate feeds').'</label></p>'.
+	
+	'<p><label for="inc_subcats" class="classic">'.
+	form::checkbox('inc_subcats','1',$blog_settings->system->inc_subcats).
+	__('Include sub-categories in category page and category posts feed').'</label></p>'.
 	'</div>'.
     '</div>'.
Index: admin/js/_media.js
===================================================================
--- admin/js/_media.js	(revision 1952)
+++ admin/js/_media.js	(revision 2202)
@@ -69,4 +69,5 @@
 				if (data.result.files[0].html !==undefined) {
 					$('.media-list .files-group').append(data.result.files[0].html);
+					$('#form-medias .hide').removeClass('hide');
 				}
 				$('.button.clean',me).show();
@@ -130,4 +131,18 @@
 	$('#fileupload').enhancedUploader();
 
+	$('.checkboxes-helpers').each(function() {
+		dotclear.checkboxesHelpers(this);
+	});
+
+	$('#form-medias').submit(function() {
+		var count_checked = $('input[name="medias[]"]:checked', $(this)).length;
+		console.log('count: ', count_checked);
+		if (count_checked==0) {
+			return false;
+		}
+
+		return window.confirm(dotclear.msg.confirm_delete_medias.replace('%d',count_checked));
+	});
+
 	// Replace remove links by a POST on hidden form
 	fileRemoveAct();
@@ -135,5 +150,5 @@
 	function fileRemoveAct() {
 		$('body').on('click','a.media-remove',function() {
-			var m_name = $(this).parents('ul').find('li:first>a').text();
+			var m_name = $(this).parents('.media-item').find('a.media-link').text();
 			if (window.confirm(dotclear.msg.confirm_delete_media.replace('%s',m_name))) {
 				var f = $('#media-remove-hide').get(0);
Index: admin/js/common.js
===================================================================
--- admin/js/common.js	(revision 2187)
+++ admin/js/common.js	(revision 2201)
@@ -280,36 +280,35 @@
 		$(e).append(document.createTextNode(' '));
 
-		target = target || $(e).parents('form').find('input[type="checkbox"]');
-		
-		var a = document.createElement('a');
-		a.href='#';
-		$(a).append(document.createTextNode(dotclear.msg.select_all));
-		a.onclick = function() {
-			target.check();
+		$('<a href="#">'+dotclear.msg.select_all+'</a>').click(function() {
+			if (target !== undefined) {
+				target.check();
+			} else {
+				$(e).parents('form').find('input[type="checkbox"]').check();
+			}
+
 			return false;
-		};
-		$(e).append(a);
-
+		}).appendTo($(e));
 		$(e).append(document.createTextNode(' | '));
 
-		a = document.createElement('a');
-		a.href='#';
-		$(a).append(document.createTextNode(dotclear.msg.no_selection));
-		a.onclick = function() {
-			target.unCheck();
+		$('<a href="#">'+dotclear.msg.no_selection+'</a>').click(function() {
+			if (target !== undefined) {
+				target.unCheck();
+			} else {
+				$(e).parents('form').find('input[type="checkbox"]').unCheck();
+			}
+
 			return false;
-		};
-		$(e).append(a);
-
+		}).appendTo($(e));
 		$(e).append(document.createTextNode(' - '));
 
-		a = document.createElement('a');
-		a.href='#';
-		$(a).append(document.createTextNode(dotclear.msg.invert_sel));
-		a.onclick = function() {
-			target.toggleCheck();
+		$('<a href="#">'+dotclear.msg.invert_sel+'</a>').click(function() {
+			if (target !== undefined) {
+				target.toggleCheck();
+			} else {
+				$(e).parents('form').find('input[type="checkbox"]').toggleCheck();
+			}
+
 			return false;
-		};
-		$(e).append(a);
+		}).appendTo($(e));
 	},
 
Index: admin/media.php
===================================================================
--- admin/media.php	(revision 2167)
+++ admin/media.php	(revision 2206)
@@ -180,5 +180,25 @@
 }
 
-# Removing item
+# Removing items
+if ($dir && !empty($_POST['medias']) && !empty($_POST['delete_medias'])) {
+	try {
+		foreach ($_POST['medias'] as $media) {
+			$core->media->removeItem(rawurldecode($media));
+		}
+		dcPage::addSuccessNotice(
+			sprintf(__('Successfully delete one media.',
+					   'Successfully delete %d medias.',
+					   count($_POST['medias'])
+					   ),
+					   count($_POST['medias'])
+			)
+		);
+		http::redirect($page_url.'&d='.rawurlencode($d));
+	} catch (Exception $e) {
+		$core->error->add($e->getMessage());
+	}
+}
+
+# Removing item from popup only
 if ($dir && !empty($_POST['rmyes']) && !empty($_POST['remove']))
 {
@@ -322,4 +342,19 @@
 
 $items = array_values(array_merge($dir['dirs'],$dir['files']));
+
+$fmt_form_media = '<form action="media.php" method="post" id="form-medias">'.
+	'<div class="files-group">%s</div>'.
+	'<p>'.$core->formNonce() . form::hidden(array('d'),$d).'</p>';
+
+if (!$popup) {
+	$fmt_form_media .=
+	'<div class="two-cols%s">'.
+	'<p class="col checkboxes-helpers"></p>'.
+	'<p class="col right"><input type="submit" class="delete" name="delete_medias" value="'.__('Remove selected medias').'"/></p>'.
+	'</div>';
+}
+$fmt_form_media .=
+	'</form>';
+
 echo '<div class="media-list">';
 if (count($items) == 0)
@@ -327,5 +362,5 @@
 	echo 
 	'<p>'.__('No file.').'</p>'.
-	'<div class="files-group"></div>'; // need for jsUpload to append new media 
+	sprintf($fmt_form_media,'',' hide'); // need for jsUpload to append new media
 }
 else
@@ -337,5 +372,5 @@
 	'<p><label for="file_sort" class="classic">'.__('Sort files:').'</label> '.
 	form::combo('file_sort',$sort_combo,$file_sort).' - '.
-	'<label for="nb_per_page" class="classic">'.__('Number of media displayed per page:').'</label> '.
+	'<label for="nb_per_page" class="classic">'.__('Number of elements displayed per page:').'</label> '.
 	form::field('nb_per_page',5,3,(integer) $nb_per_page).' '.
 	'<input type="submit" value="'.__('OK').'" />'.
@@ -356,7 +391,8 @@
 		}
 	}
+	
 	echo 
-		($dgroup != '' ? '<div class="folders-group">'.$dgroup.'</div>' : '').
-		'<div class="files-group">'.$fgroup.'</div>';
+	($dgroup != '' ? '<div class="folders-group">'.$dgroup.'</div>' : '').
+	sprintf($fmt_form_media,$fgroup,'');
 	
 	echo $pager->getLinks();
@@ -551,8 +587,12 @@
 	
 	if ($f->del) {
-		$act .= '<a class="media-remove" '.
-		'href="'.html::escapeURL($page_url).'&amp;d='.
-		rawurlencode($GLOBALS['d']).'&amp;remove='.rawurlencode($f->basename).'">'.
-		'<img src="images/trash.png" alt="'.__('Delete').'" title="'.__('delete').'" /></a>';
+		if (!$popup && !$f->d) {
+			$act .= form::checkbox(array('medias[]', 'media_'.rawurlencode($f->basename)),rawurlencode($f->basename));
+		} else {
+			$act .= '<a class="media-remove" '.
+			'href="'.html::escapeURL($page_url).'&amp;d='.
+			rawurlencode($GLOBALS['d']).'&amp;remove='.rawurlencode($f->basename).'">'.
+			'<img src="images/trash.png" alt="'.__('Delete').'" title="'.__('delete').'" /></a>';
+		}
 	}
 	
Index: admin/media_item.php
===================================================================
--- admin/media_item.php	(revision 2167)
+++ admin/media_item.php	(revision 2211)
@@ -166,7 +166,11 @@
 	foreach ($pattern as $v) {
 		if ($v == 'Title') {
-			$res[] = $file->media_title;
+			if ($file->media_title != '') {
+				$res[] = $file->media_title;
+			}
 		} elseif ($file->media_meta->{$v}) {
-			$res[] = (string) $file->media_meta->{$v};
+			if ((string) $file->media_meta->{$v} != '') {
+				$res[] = (string) $file->media_meta->{$v};
+			}
 		} elseif (preg_match('/^Date\((.+?)\)$/u',$v,$m)) {
 			if ($dto_first && ($file->media_meta->DateTimeOriginal != 0)) {
@@ -204,5 +208,5 @@
 		array(
 			html::escapeHTML($core->blog->name) => '',
-			__('Media manager') => html::escapeURL($media_page_url),
+			__('Media manager') => html::escapeURL($media_page_url).'&amp;d=',
 			$core->media->breadCrumb(html::escapeURL($media_page_url).'&amp;d=%s').'<span class="page-title">'.$file->basename.'</span>' => ''
 		),
Index: admin/preferences.php
===================================================================
--- admin/preferences.php	(revision 2166)
+++ admin/preferences.php	(revision 2206)
@@ -490,5 +490,5 @@
 
 echo
-'<p><label for="user_ui_media_by_page" class="classic">'.__('Number of media displayed per page:').'</label> '.
+'<p><label for="user_ui_media_by_page" class="classic">'.__('Number of elements displayed per page in media manager:').'</label> '.
 form::field('user_ui_media_by_page',5,3,(integer) $user_ui_media_by_page).'</p>';
 
Index: admin/search.php
===================================================================
--- admin/search.php	(revision 2166)
+++ admin/search.php	(revision 2210)
@@ -15,6 +15,6 @@
 dcPage::check('usage,contentadmin');
 
-$q = !empty($_GET['q']) ? $_GET['q'] : (!empty($_GET['qx']) ? $_GET['qx'] : null);
-$qtype = !empty($_GET['qtype']) ? $_GET['qtype'] : 'p';
+$q = !empty($_REQUEST['q']) ? $_REQUEST['q'] : (!empty($_REQUEST['qx']) ? $_REQUEST['qx'] : null);
+$qtype = !empty($_REQUEST['qtype']) ? $_REQUEST['qtype'] : 'p';
 if ($qtype != 'c' && $qtype != 'p') {
 	$qtype = 'p';
@@ -69,4 +69,17 @@
 }
 
+if ($qtype == 'p') {
+	$posts_actions_page = new dcPostsActionsPage($core,'search.php',array('q'=>$q,'qtype'=>$qtype));
+
+	if ($posts_actions_page->process()) {
+		return;
+	}
+} else {
+	$comments_actions_page = new dcCommentsActionsPage($core,'search.php',array('q'=>$q,'qtype'=>$qtype));
+
+	if ($comments_actions_page->process()) {
+		return;
+	}
+}
 
 dcPage::open(__('Search'),$starting_scripts,
@@ -95,25 +108,5 @@
 	if ($qtype == 'p')
 	{
-		# Actions combo box
-		$combo_action = array();
-		if ($core->auth->check('publish,contentadmin',$core->blog->id))
-		{
-			$combo_action[__('publish')] = 'publish';
-			$combo_action[__('unpublish')] = 'unpublish';
-			$combo_action[__('schedule')] = 'schedule';
-			$combo_action[__('mark as pending')] = 'pending';
-		}
-		$combo_action[__('change category')] = 'category';
-		if ($core->auth->check('admin',$core->blog->id)) {
-			$combo_action[__('change author')] = 'author';
-		}
-		if ($core->auth->check('delete,contentadmin',$core->blog->id))
-		{
-			$combo_action[__('Delete')] = 'delete';
-		}
-		
-		# --BEHAVIOR-- adminPostsActionsCombo
-		$core->callBehavior('adminPostsActionsCombo',array(&$combo_action));
-		
+	
 		if ($counter->f(0) > 0) {
 			printf('<h3>'.
@@ -123,5 +116,5 @@
 		
 		$post_list->display($page,$nb_per_page,
-		'<form action="posts_actions.php" method="post" id="form-entries">'.
+		'<form action="search.php" method="post" id="form-entries">'.
 		
 		'%s'.
@@ -131,8 +124,8 @@
 		
 		'<p class="col right"><label for="action1" class="classic">'.__('Selected entries action:').'</label> '.
-		form::combo(array('action','action1'),$combo_action).
+		form::combo(array('action','action1'),$posts_actions_page->getCombo()).
 		'<input type="submit" value="'.__('ok').'" /></p>'.
-		form::hidden('redir',preg_replace('/%/','%%',$redir)).
 		$core->formNonce().
+		$posts_actions_page->getHiddenFields().
 		'</div>'.
 		'</form>'
@@ -143,16 +136,4 @@
 	{
 		# Actions combo box
-		$combo_action = array();
-		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';
-		}
-		if ($core->auth->check('delete,contentadmin',$core->blog->id))
-		{
-			$combo_action[__('Delete')] = 'delete';
-		}
 		
 		if ($counter->f(0) > 0) {
@@ -163,5 +144,5 @@
 		
 		$comment_list->display($page,$nb_per_page,
-		'<form action="comments_actions.php" method="post" id="form-comments">'.
+		'<form action="search.php" method="post" id="form-comments">'.
 		
 		'%s'.
@@ -171,8 +152,8 @@
 		
 		'<p class="col right"><label for="action2" class="classic">'.__('Selected comments action:').'</label> '.
-		form::combo(array('action','action2'),$combo_action).
+		form::combo(array('action','action2'),$comments_actions_page->getCombo()).
 		'<input type="submit" value="'.__('ok').'" /></p>'.
-		form::hidden('redir',preg_replace('/%/','%%',$redir)).
 		$core->formNonce().
+		$comments_actions_page->getHiddenFields().
 		'</div>'.
 		'</form>'
Index: admin/users_actions.php
===================================================================
--- admin/users_actions.php	(revision 2166)
+++ admin/users_actions.php	(revision 2212)
@@ -268,5 +268,5 @@
 		echo '<h3>'.('Blog:').' <a href="blog.php?id='.html::escapeHTML($b).'">'.html::escapeHTML($b).'</a>'.
 		form::hidden(array('blogs[]'),$b).'</h3>';
-		
+		$unknown_perms = $user_perm;
 		foreach ($core->auth->getPermissionsTypes() as $perm_id => $perm)
 		{
@@ -275,4 +275,7 @@
 			if (count($users) == 1) {
 				$checked = isset($user_perm[$b]['p'][$perm_id]) && $user_perm[$b]['p'][$perm_id];
+			}
+			if (isset($unknown_perms[$b]['p'][$perm_id])) {
+				unset ($unknown_perms[$b]['p'][$perm_id]);
 			}
 			
@@ -282,4 +285,17 @@
 			1,$checked).' '.
 			__($perm).'</label></p>';
+		}
+		if (isset($unknown_perms[$b])) {
+		
+			foreach ($unknown_perms[$b]['p'] as $perm_id => $v) {
+				$checked = isset($user_perm[$b]['p'][$perm_id]) && $user_perm[$b]['p'][$perm_id];
+				echo
+				'<p><label for="perm'.html::escapeHTML($b).html::escapeHTML($perm_id).'" class="classic">'.
+				form::checkbox(
+					array('perm['.html::escapeHTML($b).']['.html::escapeHTML($perm_id).']',
+						'perm'.html::escapeHTML($b).html::escapeHTML($perm_id)),
+					1,$checked).' '.
+				sprintf(__('[%s] (unreferenced permission)'),$perm_id).'</label></p>';
+			}
 		}
 	}
Index: inc/admin/lib.dc.page.php
===================================================================
--- inc/admin/lib.dc.page.php	(revision 2196)
+++ inc/admin/lib.dc.page.php	(revision 2217)
@@ -108,7 +108,7 @@
 		$user_ui_hide_std_favicon = $core->auth->user_prefs->interface->hide_std_favicon;
 		if (!$user_ui_hide_std_favicon) {
-  			echo 
-  			'<link rel="icon" type="image/png" href="images/favicon96-login.png" />'.
-  			'<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />';
+			echo 
+			'<link rel="icon" type="image/png" href="images/favicon96-login.png" />'.
+			'<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />';
 		}
 		echo
@@ -176,4 +176,12 @@
 		}
 
+		// Display notices
+		echo self::notices();
+	}
+
+	public static function notices()
+	{
+		// return notices if any
+		$res = '';
 		if (isset($_SESSION['notifications'])) {
 			$types = array("success" => "success", "warning" => "warning-msg", "error" => "error");
@@ -182,5 +190,5 @@
 				if (isset($notifications[$type])) {
 					foreach ($notifications[$type] as $n) {
-						echo self::getNotification($n,$class);
+						$res .= self::getNotification($n,$class);
 					}
 				}
@@ -188,7 +196,8 @@
 			unset($_SESSION['notifications']);
 		}
-	}
-
-	public static function AddNotice($type,$message)
+		return $res;
+	}
+
+	public static function addNotice($type,$message)
 	{
 		$notification = isset($_SESSION['notifications']) ? $_SESSION['notifications'] : array();
@@ -263,5 +272,5 @@
 		'<div id="footer">'.
 		'<a href="http://dotclear.org/" title="'.$text.'"><img src="style/dc_logos/w-dotclear90.png" alt="'.$text.'" /></a></div>'."\n".
-		'<!-- '."\n".
+ 		'<!-- '."\n".
 '                  .'."\n".
 '               ,;:\'`\'::'."\n".
@@ -301,8 +310,8 @@
 
 		self::jsLoadIE7().
-		'  	<link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />'."\n";
+		'	<link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />'."\n";
 		if (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl') {
 			echo
-			'  	<link rel="stylesheet" href="style/default-rtl.css" type="text/css" media="screen" />'."\n";
+			'	<link rel="stylesheet" href="style/default-rtl.css" type="text/css" media="screen" />'."\n";
 		}
 
@@ -605,4 +614,6 @@
 		self::jsVar('dotclear.msg.confirm_delete_posts',
 			__("Are you sure you want to delete selected entries (%s)?")).
+		self::jsVar('dotclear.msg.confirm_delete_medias',
+			__("Are you sure you want to delete selected medias (%d)?")).
 		self::jsVar('dotclear.msg.confirm_delete_categories',
 			__("Are you sure you want to delete selected categories (%s)?")).
@@ -732,215 +743,215 @@
 	}
 
-public static function jsModal()
-{
-	return
-	'<link rel="stylesheet" type="text/css" href="style/modal/modal.css" />'."\n".
-	self::jsLoad('js/jquery/jquery.modal.js').
-	'<script type="text/javascript">'."\n".
-	"//<![CDATA[\n".
-	self::jsVar('$.modal.prototype.params.loader_img','style/modal/loader.gif').
-	self::jsVar('$.modal.prototype.params.close_img','style/modal/close.png').
-	"\n//]]>\n".
-	"</script>\n";
-}
-
-public static function jsColorPicker()
-{
-	return
-	'<link rel="stylesheet" type="text/css" href="style/farbtastic/farbtastic.css" />'."\n".
-	self::jsLoad('js/jquery/jquery.farbtastic.js').
-	self::jsLoad('js/color-picker.js');
-}
-
-public static function jsDatePicker()
-{
-	return
-	'<link rel="stylesheet" type="text/css" href="style/date-picker.css" />'."\n".
-	self::jsLoad('js/date-picker.js').
-	'<script type="text/javascript">'."\n".
-	"//<![CDATA[\n".
-
-	"datePicker.prototype.months[0] = '".html::escapeJS(__('January'))."'; ".
-	"datePicker.prototype.months[1] = '".html::escapeJS(__('February'))."'; ".
-	"datePicker.prototype.months[2] = '".html::escapeJS(__('March'))."'; ".
-	"datePicker.prototype.months[3] = '".html::escapeJS(__('April'))."'; ".
-	"datePicker.prototype.months[4] = '".html::escapeJS(__('May'))."'; ".
-	"datePicker.prototype.months[5] = '".html::escapeJS(__('June'))."'; ".
-	"datePicker.prototype.months[6] = '".html::escapeJS(__('July'))."'; ".
-	"datePicker.prototype.months[7] = '".html::escapeJS(__('August'))."'; ".
-	"datePicker.prototype.months[8] = '".html::escapeJS(__('September'))."'; ".
-	"datePicker.prototype.months[9] = '".html::escapeJS(__('October'))."'; ".
-	"datePicker.prototype.months[10] = '".html::escapeJS(__('November'))."'; ".
-	"datePicker.prototype.months[11] = '".html::escapeJS(__('December'))."'; ".
-
-	"datePicker.prototype.days[0] = '".html::escapeJS(__('Monday'))."'; ".
-	"datePicker.prototype.days[1] = '".html::escapeJS(__('Tuesday'))."'; ".
-	"datePicker.prototype.days[2] = '".html::escapeJS(__('Wednesday'))."'; ".
-	"datePicker.prototype.days[3] = '".html::escapeJS(__('Thursday'))."'; ".
-	"datePicker.prototype.days[4] = '".html::escapeJS(__('Friday'))."'; ".
-	"datePicker.prototype.days[5] = '".html::escapeJS(__('Saturday'))."'; ".
-	"datePicker.prototype.days[6] = '".html::escapeJS(__('Sunday'))."'; ".
-
-	"datePicker.prototype.img_src = 'images/date-picker.png'; ".
-
-	"datePicker.prototype.close_msg = '".html::escapeJS(__('close'))."'; ".
-	"datePicker.prototype.now_msg = '".html::escapeJS(__('now'))."'; ".
-
-	"\n//]]>\n".
-	"</script>\n";
-}
-
-public static function jsToolBar()
-{
-	$res =
-	'<link rel="stylesheet" type="text/css" href="style/jsToolBar/jsToolBar.css" />'.
-	'<script type="text/javascript" src="js/jsToolBar/jsToolBar.js"></script>';
-
-	if (isset($GLOBALS['core']->auth) && $GLOBALS['core']->auth->getOption('enable_wysiwyg')) {
-		$res .= '<script type="text/javascript" src="js/jsToolBar/jsToolBar.wysiwyg.js"></script>';
-	}
-
-	$res .=
-	'<script type="text/javascript" src="js/jsToolBar/jsToolBar.dotclear.js"></script>'.
-	'<script type="text/javascript">'."\n".
-	"//<![CDATA[\n".
-	"jsToolBar.prototype.dialog_url = 'popup.php'; ".
-	"jsToolBar.prototype.iframe_css = '".
-	'body{'.
-	'font: 12px "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif;'.
-	'color : #000;'.
-	'background: #f9f9f9;'.
-	'margin: 0;'.
-	'padding : 2px;'.
-	'border: none;'.
-	(l10n::getTextDirection($GLOBALS['_lang']) == 'rtl' ? 'direction:rtl;' : '').
-	'}'.
-	'pre, code, kbd, samp {'.
-	'font-family:"Courier New",Courier,monospace;'.
-	'font-size : 1.1em;'.
-	'}'.
-	'code {'.
-	'color : #666;'.
-	'font-weight : bold;'.
-	'}'.
-	'body > p:first-child {'.
-	'margin-top: 0;'.
-	'}'.
-	"'; ".
-	"jsToolBar.prototype.base_url = '".html::escapeJS($GLOBALS['core']->blog->host)."'; ".
-	"jsToolBar.prototype.switcher_visual_title = '".html::escapeJS(__('visual'))."'; ".
-	"jsToolBar.prototype.switcher_source_title = '".html::escapeJS(__('source'))."'; ".
-	"jsToolBar.prototype.legend_msg = '".
-	html::escapeJS(__('You can use the following shortcuts to format your text.'))."'; ".
-	"jsToolBar.prototype.elements.blocks.options.none = '".html::escapeJS(__('-- none --'))."'; ".
-	"jsToolBar.prototype.elements.blocks.options.nonebis = '".html::escapeJS(__('-- block format --'))."'; ".
-	"jsToolBar.prototype.elements.blocks.options.p = '".html::escapeJS(__('Paragraph'))."'; ".
-	"jsToolBar.prototype.elements.blocks.options.h1 = '".html::escapeJS(__('Level 1 header'))."'; ".
-	"jsToolBar.prototype.elements.blocks.options.h2 = '".html::escapeJS(__('Level 2 header'))."'; ".
-	"jsToolBar.prototype.elements.blocks.options.h3 = '".html::escapeJS(__('Level 3 header'))."'; ".
-	"jsToolBar.prototype.elements.blocks.options.h4 = '".html::escapeJS(__('Level 4 header'))."'; ".
-	"jsToolBar.prototype.elements.blocks.options.h5 = '".html::escapeJS(__('Level 5 header'))."'; ".
-	"jsToolBar.prototype.elements.blocks.options.h6 = '".html::escapeJS(__('Level 6 header'))."'; ".
-	"jsToolBar.prototype.elements.strong.title = '".html::escapeJS(__('Strong emphasis'))."'; ".
-	"jsToolBar.prototype.elements.em.title = '".html::escapeJS(__('Emphasis'))."'; ".
-	"jsToolBar.prototype.elements.ins.title = '".html::escapeJS(__('Inserted'))."'; ".
-	"jsToolBar.prototype.elements.del.title = '".html::escapeJS(__('Deleted'))."'; ".
-	"jsToolBar.prototype.elements.quote.title = '".html::escapeJS(__('Inline quote'))."'; ".
-	"jsToolBar.prototype.elements.code.title = '".html::escapeJS(__('Code'))."'; ".
-	"jsToolBar.prototype.elements.br.title = '".html::escapeJS(__('Line break'))."'; ".
-	"jsToolBar.prototype.elements.blockquote.title = '".html::escapeJS(__('Blockquote'))."'; ".
-	"jsToolBar.prototype.elements.pre.title = '".html::escapeJS(__('Preformated text'))."'; ".
-	"jsToolBar.prototype.elements.ul.title = '".html::escapeJS(__('Unordered list'))."'; ".
-	"jsToolBar.prototype.elements.ol.title = '".html::escapeJS(__('Ordered list'))."'; ".
-
-	"jsToolBar.prototype.elements.link.title = '".html::escapeJS(__('Link'))."'; ".
-	"jsToolBar.prototype.elements.link.href_prompt = '".html::escapeJS(__('URL?'))."'; ".
-	"jsToolBar.prototype.elements.link.hreflang_prompt = '".html::escapeJS(__('Language?'))."'; ".
-
-	"jsToolBar.prototype.elements.img.title = '".html::escapeJS(__('External image'))."'; ".
-	"jsToolBar.prototype.elements.img.src_prompt = '".html::escapeJS(__('URL?'))."'; ".
-
-	"jsToolBar.prototype.elements.img_select.title = '".html::escapeJS(__('Media chooser'))."'; ".
-	"jsToolBar.prototype.elements.post_link.title = '".html::escapeJS(__('Link to an entry'))."'; ";
-
-	if (!$GLOBALS['core']->auth->check('media,media_admin',$GLOBALS['core']->blog->id)) {
-		$res .= "jsToolBar.prototype.elements.img_select.disabled = true;\n";
-	}
-
-	$res .=
-	"\n//]]>\n".
-	"</script>\n";
-
-	return $res;
-}
-
-public static function jsUpload($params=array(),$base_url=null)
-{
-	if (!$base_url) {
-		$base_url = path::clean(dirname(preg_replace('/(\?.*$)?/','',$_SERVER['REQUEST_URI']))).'/';
-	}
-
-	$params = array_merge($params,array(
-		'sess_id='.session_id(),
-		'sess_uid='.$_SESSION['sess_browser_uid'],
-		'xd_check='.$GLOBALS['core']->getNonce()
+	public static function jsModal()
+	{
+		return
+		'<link rel="stylesheet" type="text/css" href="style/modal/modal.css" />'."\n".
+		self::jsLoad('js/jquery/jquery.modal.js').
+		'<script type="text/javascript">'."\n".
+		"//<![CDATA[\n".
+		self::jsVar('$.modal.prototype.params.loader_img','style/modal/loader.gif').
+		self::jsVar('$.modal.prototype.params.close_img','style/modal/close.png').
+		"\n//]]>\n".
+		"</script>\n";
+	}
+
+	public static function jsColorPicker()
+	{
+		return
+		'<link rel="stylesheet" type="text/css" href="style/farbtastic/farbtastic.css" />'."\n".
+		self::jsLoad('js/jquery/jquery.farbtastic.js').
+		self::jsLoad('js/color-picker.js');
+	}
+
+	public static function jsDatePicker()
+	{
+		return
+		'<link rel="stylesheet" type="text/css" href="style/date-picker.css" />'."\n".
+		self::jsLoad('js/date-picker.js').
+		'<script type="text/javascript">'."\n".
+		"//<![CDATA[\n".
+
+		"datePicker.prototype.months[0] = '".html::escapeJS(__('January'))."'; ".
+		"datePicker.prototype.months[1] = '".html::escapeJS(__('February'))."'; ".
+		"datePicker.prototype.months[2] = '".html::escapeJS(__('March'))."'; ".
+		"datePicker.prototype.months[3] = '".html::escapeJS(__('April'))."'; ".
+		"datePicker.prototype.months[4] = '".html::escapeJS(__('May'))."'; ".
+		"datePicker.prototype.months[5] = '".html::escapeJS(__('June'))."'; ".
+		"datePicker.prototype.months[6] = '".html::escapeJS(__('July'))."'; ".
+		"datePicker.prototype.months[7] = '".html::escapeJS(__('August'))."'; ".
+		"datePicker.prototype.months[8] = '".html::escapeJS(__('September'))."'; ".
+		"datePicker.prototype.months[9] = '".html::escapeJS(__('October'))."'; ".
+		"datePicker.prototype.months[10] = '".html::escapeJS(__('November'))."'; ".
+		"datePicker.prototype.months[11] = '".html::escapeJS(__('December'))."'; ".
+
+		"datePicker.prototype.days[0] = '".html::escapeJS(__('Monday'))."'; ".
+		"datePicker.prototype.days[1] = '".html::escapeJS(__('Tuesday'))."'; ".
+		"datePicker.prototype.days[2] = '".html::escapeJS(__('Wednesday'))."'; ".
+		"datePicker.prototype.days[3] = '".html::escapeJS(__('Thursday'))."'; ".
+		"datePicker.prototype.days[4] = '".html::escapeJS(__('Friday'))."'; ".
+		"datePicker.prototype.days[5] = '".html::escapeJS(__('Saturday'))."'; ".
+		"datePicker.prototype.days[6] = '".html::escapeJS(__('Sunday'))."'; ".
+
+		"datePicker.prototype.img_src = 'images/date-picker.png'; ".
+
+		"datePicker.prototype.close_msg = '".html::escapeJS(__('close'))."'; ".
+		"datePicker.prototype.now_msg = '".html::escapeJS(__('now'))."'; ".
+
+		"\n//]]>\n".
+		"</script>\n";
+	}
+
+	public static function jsToolBar()
+	{
+		$res =
+		'<link rel="stylesheet" type="text/css" href="style/jsToolBar/jsToolBar.css" />'.
+		'<script type="text/javascript" src="js/jsToolBar/jsToolBar.js"></script>';
+
+		if (isset($GLOBALS['core']->auth) && $GLOBALS['core']->auth->getOption('enable_wysiwyg')) {
+			$res .= '<script type="text/javascript" src="js/jsToolBar/jsToolBar.wysiwyg.js"></script>';
+		}
+
+		$res .=
+		'<script type="text/javascript" src="js/jsToolBar/jsToolBar.dotclear.js"></script>'.
+		'<script type="text/javascript">'."\n".
+		"//<![CDATA[\n".
+		"jsToolBar.prototype.dialog_url = 'popup.php'; ".
+		"jsToolBar.prototype.iframe_css = '".
+		'body{'.
+		'font: 12px "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif;'.
+		'color : #000;'.
+		'background: #f9f9f9;'.
+		'margin: 0;'.
+		'padding : 2px;'.
+		'border: none;'.
+		(l10n::getTextDirection($GLOBALS['_lang']) == 'rtl' ? 'direction:rtl;' : '').
+		'}'.
+		'pre, code, kbd, samp {'.
+		'font-family:"Courier New",Courier,monospace;'.
+		'font-size : 1.1em;'.
+		'}'.
+		'code {'.
+		'color : #666;'.
+		'font-weight : bold;'.
+		'}'.
+		'body > p:first-child {'.
+		'margin-top: 0;'.
+		'}'.
+		"'; ".
+		"jsToolBar.prototype.base_url = '".html::escapeJS($GLOBALS['core']->blog->host)."'; ".
+		"jsToolBar.prototype.switcher_visual_title = '".html::escapeJS(__('visual'))."'; ".
+		"jsToolBar.prototype.switcher_source_title = '".html::escapeJS(__('source'))."'; ".
+		"jsToolBar.prototype.legend_msg = '".
+		html::escapeJS(__('You can use the following shortcuts to format your text.'))."'; ".
+		"jsToolBar.prototype.elements.blocks.options.none = '".html::escapeJS(__('-- none --'))."'; ".
+		"jsToolBar.prototype.elements.blocks.options.nonebis = '".html::escapeJS(__('-- block format --'))."'; ".
+		"jsToolBar.prototype.elements.blocks.options.p = '".html::escapeJS(__('Paragraph'))."'; ".
+		"jsToolBar.prototype.elements.blocks.options.h1 = '".html::escapeJS(__('Level 1 header'))."'; ".
+		"jsToolBar.prototype.elements.blocks.options.h2 = '".html::escapeJS(__('Level 2 header'))."'; ".
+		"jsToolBar.prototype.elements.blocks.options.h3 = '".html::escapeJS(__('Level 3 header'))."'; ".
+		"jsToolBar.prototype.elements.blocks.options.h4 = '".html::escapeJS(__('Level 4 header'))."'; ".
+		"jsToolBar.prototype.elements.blocks.options.h5 = '".html::escapeJS(__('Level 5 header'))."'; ".
+		"jsToolBar.prototype.elements.blocks.options.h6 = '".html::escapeJS(__('Level 6 header'))."'; ".
+		"jsToolBar.prototype.elements.strong.title = '".html::escapeJS(__('Strong emphasis'))."'; ".
+		"jsToolBar.prototype.elements.em.title = '".html::escapeJS(__('Emphasis'))."'; ".
+		"jsToolBar.prototype.elements.ins.title = '".html::escapeJS(__('Inserted'))."'; ".
+		"jsToolBar.prototype.elements.del.title = '".html::escapeJS(__('Deleted'))."'; ".
+		"jsToolBar.prototype.elements.quote.title = '".html::escapeJS(__('Inline quote'))."'; ".
+		"jsToolBar.prototype.elements.code.title = '".html::escapeJS(__('Code'))."'; ".
+		"jsToolBar.prototype.elements.br.title = '".html::escapeJS(__('Line break'))."'; ".
+		"jsToolBar.prototype.elements.blockquote.title = '".html::escapeJS(__('Blockquote'))."'; ".
+		"jsToolBar.prototype.elements.pre.title = '".html::escapeJS(__('Preformated text'))."'; ".
+		"jsToolBar.prototype.elements.ul.title = '".html::escapeJS(__('Unordered list'))."'; ".
+		"jsToolBar.prototype.elements.ol.title = '".html::escapeJS(__('Ordered list'))."'; ".
+
+		"jsToolBar.prototype.elements.link.title = '".html::escapeJS(__('Link'))."'; ".
+		"jsToolBar.prototype.elements.link.href_prompt = '".html::escapeJS(__('URL?'))."'; ".
+		"jsToolBar.prototype.elements.link.hreflang_prompt = '".html::escapeJS(__('Language?'))."'; ".
+
+		"jsToolBar.prototype.elements.img.title = '".html::escapeJS(__('External image'))."'; ".
+		"jsToolBar.prototype.elements.img.src_prompt = '".html::escapeJS(__('URL?'))."'; ".
+
+		"jsToolBar.prototype.elements.img_select.title = '".html::escapeJS(__('Media chooser'))."'; ".
+		"jsToolBar.prototype.elements.post_link.title = '".html::escapeJS(__('Link to an entry'))."'; ";
+
+		if (!$GLOBALS['core']->auth->check('media,media_admin',$GLOBALS['core']->blog->id)) {
+			$res .= "jsToolBar.prototype.elements.img_select.disabled = true;\n";
+		}
+
+		$res .=
+		"\n//]]>\n".
+		"</script>\n";
+
+		return $res;
+	}
+
+	public static function jsUpload($params=array(),$base_url=null)
+	{
+		if (!$base_url) {
+			$base_url = path::clean(dirname(preg_replace('/(\?.*$)?/','',$_SERVER['REQUEST_URI']))).'/';
+		}
+
+		$params = array_merge($params,array(
+			'sess_id='.session_id(),
+			'sess_uid='.$_SESSION['sess_browser_uid'],
+			'xd_check='.$GLOBALS['core']->getNonce()
 		));
 
-	return
-	'<script type="text/javascript">'."\n".
-	"//<![CDATA[\n".
-	"dotclear.jsUpload = {};\n".
-	"dotclear.jsUpload.msg = {};\n".
-	self::jsVar('dotclear.msg.enhanced_uploader_activate',__('Temporarily activate enhanced uploader')).
-	self::jsVar('dotclear.msg.enhanced_uploader_disable',__('Temporarily disable enhanced uploader')).
-	self::jsVar('dotclear.jsUpload.msg.limit_exceeded',__('Limit exceeded.')).
-	self::jsVar('dotclear.jsUpload.msg.size_limit_exceeded',__('File size exceeds allowed limit.')).
-	self::jsVar('dotclear.jsUpload.msg.canceled',__('Canceled.')).
-	self::jsVar('dotclear.jsUpload.msg.http_error',__('HTTP Error:')).
-	self::jsVar('dotclear.jsUpload.msg.error',__('Error:')).
-	self::jsVar('dotclear.jsUpload.msg.choose_file',__('Choose file')).
-	self::jsVar('dotclear.jsUpload.msg.choose_files',__('Choose files')).
-	self::jsVar('dotclear.jsUpload.msg.cancel',__('Cancel')).
-	self::jsVar('dotclear.jsUpload.msg.clean',__('Clean')).
-	self::jsVar('dotclear.jsUpload.msg.upload',__('Upload')).
-	self::jsVar('dotclear.jsUpload.msg.send',__('Send')).
-	self::jsVar('dotclear.jsUpload.msg.file_successfully_uploaded',__('File successfully uploaded.')).
-	self::jsVar('dotclear.jsUpload.msg.no_file_in_queue',__('No file in queue.')).
-	self::jsVar('dotclear.jsUpload.msg.file_in_queue',__('1 file in queue.')).
-	self::jsVar('dotclear.jsUpload.msg.files_in_queue',__('%d files in queue.')).
-	self::jsVar('dotclear.jsUpload.msg.queue_error',__('Queue error:')).
-	self::jsVar('dotclear.jsUpload.base_url',$base_url).
-	"\n//]]>\n".
-	"</script>\n".
-
-	self::jsLoad('js/jsUpload/vendor/jquery.ui.widget.js').
-	self::jsLoad('js/jsUpload/tmpl.js').
-	self::jsLoad('js/jsUpload/template-upload.js').
-	self::jsLoad('js/jsUpload/template-download.js').
-	self::jsLoad('js/jsUpload/load-image.js').
-	self::jsLoad('js/jsUpload/jquery.iframe-transport.js').
-	self::jsLoad('js/jsUpload/jquery.fileupload.js').
-	self::jsLoad('js/jsUpload/jquery.fileupload-process.js').
-	self::jsLoad('js/jsUpload/jquery.fileupload-resize.js').
-	self::jsLoad('js/jsUpload/jquery.fileupload-ui.js');
-}
-
-public static function jsToolMan()
-{
-	return
-	'<script type="text/javascript" src="js/tool-man/core.js"></script>'.
-	'<script type="text/javascript" src="js/tool-man/events.js"></script>'.
-	'<script type="text/javascript" src="js/tool-man/css.js"></script>'.
-	'<script type="text/javascript" src="js/tool-man/coordinates.js"></script>'.
-	'<script type="text/javascript" src="js/tool-man/drag.js"></script>'.
-	'<script type="text/javascript" src="js/tool-man/dragsort.js"></script>'.
-	'<script type="text/javascript" src="js/dragsort-tablerows.js"></script>';
-}
-
-public static function jsMetaEditor()
-{
-	return
-	'<script type="text/javascript" src="js/meta-editor.js"></script>';
-}
+		return
+		'<script type="text/javascript">'."\n".
+		"//<![CDATA[\n".
+		"dotclear.jsUpload = {};\n".
+		"dotclear.jsUpload.msg = {};\n".
+		self::jsVar('dotclear.msg.enhanced_uploader_activate',__('Temporarily activate enhanced uploader')).
+		self::jsVar('dotclear.msg.enhanced_uploader_disable',__('Temporarily disable enhanced uploader')).
+		self::jsVar('dotclear.jsUpload.msg.limit_exceeded',__('Limit exceeded.')).
+		self::jsVar('dotclear.jsUpload.msg.size_limit_exceeded',__('File size exceeds allowed limit.')).
+		self::jsVar('dotclear.jsUpload.msg.canceled',__('Canceled.')).
+		self::jsVar('dotclear.jsUpload.msg.http_error',__('HTTP Error:')).
+		self::jsVar('dotclear.jsUpload.msg.error',__('Error:')).
+		self::jsVar('dotclear.jsUpload.msg.choose_file',__('Choose file')).
+		self::jsVar('dotclear.jsUpload.msg.choose_files',__('Choose files')).
+		self::jsVar('dotclear.jsUpload.msg.cancel',__('Cancel')).
+		self::jsVar('dotclear.jsUpload.msg.clean',__('Clean')).
+		self::jsVar('dotclear.jsUpload.msg.upload',__('Upload')).
+		self::jsVar('dotclear.jsUpload.msg.send',__('Send')).
+		self::jsVar('dotclear.jsUpload.msg.file_successfully_uploaded',__('File successfully uploaded.')).
+		self::jsVar('dotclear.jsUpload.msg.no_file_in_queue',__('No file in queue.')).
+		self::jsVar('dotclear.jsUpload.msg.file_in_queue',__('1 file in queue.')).
+		self::jsVar('dotclear.jsUpload.msg.files_in_queue',__('%d files in queue.')).
+		self::jsVar('dotclear.jsUpload.msg.queue_error',__('Queue error:')).
+		self::jsVar('dotclear.jsUpload.base_url',$base_url).
+		"\n//]]>\n".
+		"</script>\n".
+
+		self::jsLoad('js/jsUpload/vendor/jquery.ui.widget.js').
+		self::jsLoad('js/jsUpload/tmpl.js').
+		self::jsLoad('js/jsUpload/template-upload.js').
+		self::jsLoad('js/jsUpload/template-download.js').
+		self::jsLoad('js/jsUpload/load-image.js').
+		self::jsLoad('js/jsUpload/jquery.iframe-transport.js').
+		self::jsLoad('js/jsUpload/jquery.fileupload.js').
+		self::jsLoad('js/jsUpload/jquery.fileupload-process.js').
+		self::jsLoad('js/jsUpload/jquery.fileupload-resize.js').
+		self::jsLoad('js/jsUpload/jquery.fileupload-ui.js');
+	}
+
+	public static function jsToolMan()
+	{
+		return
+		'<script type="text/javascript" src="js/tool-man/core.js"></script>'.
+		'<script type="text/javascript" src="js/tool-man/events.js"></script>'.
+		'<script type="text/javascript" src="js/tool-man/css.js"></script>'.
+		'<script type="text/javascript" src="js/tool-man/coordinates.js"></script>'.
+		'<script type="text/javascript" src="js/tool-man/drag.js"></script>'.
+		'<script type="text/javascript" src="js/tool-man/dragsort.js"></script>'.
+		'<script type="text/javascript" src="js/dragsort-tablerows.js"></script>';
+	}
+
+	public static function jsMetaEditor()
+	{
+		return
+		'<script type="text/javascript" src="js/meta-editor.js"></script>';
+	}
 }
 ?>
Index: inc/core/class.dc.core.php
===================================================================
--- inc/core/class.dc.core.php	(revision 1743)
+++ inc/core/class.dc.core.php	(revision 2198)
@@ -1342,4 +1342,6 @@
 				array('use_smilies','boolean',false,
 				'Show smilies on entries and comments'),
+				array('inc_subcats','boolean',false,
+				'Include sub-categories in category page and category posts feed'),
 				array('wiki_comments','boolean',false,
 				'Allow commenters to use a subset of wiki syntax')
Index: inc/public/class.dc.template.php
===================================================================
--- inc/public/class.dc.template.php	(revision 1674)
+++ inc/public/class.dc.template.php	(revision 2198)
@@ -1211,5 +1211,5 @@
 				$p .=
 				'if ($_ctx->exists("categories")) { '.
-					"\$params['cat_id'] = \$_ctx->categories->cat_id; ".
+					"\$params['cat_id'] = \$_ctx->categories->cat_id.(\$core->blog->settings->system->inc_subcats?' ?sub':'');".
 				"}\n";
 			}
Index: locales/fr/help/index.html
===================================================================
--- locales/fr/help/index.html	(revision 2116)
+++ locales/fr/help/index.html	(revision 2203)
@@ -201,5 +201,5 @@
 				<h4 class="smart-title">Lectures complémentaires</h4>
 				<ul>
-					<li><a href="http://tips.dotaddict.org">Tips</a>, des tutoriels pour vous aider à développer.</li>
+					<li><a href="http://tips.dotaddict.org/meta/skills/php_skills">Tips</a>, des tutoriels pour vous aider à développer.</li>
 				</ul>
 
Index: locales/fr/main.po
===================================================================
--- locales/fr/main.po	(revision 2145)
+++ locales/fr/main.po	(revision 2202)
@@ -1551,4 +1551,8 @@
 msgstr "Êtes-vous sûr de vouloir supprimer ce média ?"
 
+#, php-format
+msgid "Are you sure you want to delete selected medias (%d)?"
+msgstr "Êtes-vous sûr de vouloir supprimer les médias sélectionnés (%d) ?"
+
 msgid "File has been successfully updated."
 msgstr "Fichier mis à jour avec succès."
@@ -1604,4 +1608,12 @@
 msgid "Media details"
 msgstr "Détails du média"
+
+msgid "Remove selected medias"
+msgstr "Suppression des médias sélectionnés"
+
+msgid "Successfully delete one media."
+msgid_plural "Successfully delete %d medias."
+msgstr[0] "Suppression d'un média avec succès."
+msgstr[1] "Suppression de %d médias avec succès."
 
 msgid "Available sizes:"
Index: plugins/akismet/class.dc.filter.akismet.php
===================================================================
--- plugins/akismet/class.dc.filter.akismet.php	(revision 1995)
+++ plugins/akismet/class.dc.filter.akismet.php	(revision 2205)
@@ -117,5 +117,6 @@
 				$blog->settings->akismet->put('ak_key',$ak_key,'string');
 				
-				http::redirect($url.'&upd=1');
+				dcPage::addSuccessNotice(__('Filter configuration have been successfully saved.'));
+				http::redirect($url);
 			}
 			catch (Exception $e)
@@ -135,8 +136,5 @@
 		}
 
-		$res = '';
-		if (!empty($_GET['upd'])) {
-			$res .= dcPage::success(__('Filter configuration have been successfully saved.'),true,false,false);
-		}
+		$res = dcPage::notices();
 		
 		$res .=
Index: plugins/antispam/antispam.js
===================================================================
--- plugins/antispam/antispam.js	(revision 1423)
+++ plugins/antispam/antispam.js	(revision 2207)
@@ -16,3 +16,7 @@
 	$("#filters-list tr td input.position").hide();
 	$("#filters-list tr td.handle").addClass('handler');
+
+	$('form input[type=submit][name=delete_all]').click(function(){
+		return window.confirm(dotclear.msg.confirm_spam_delete);
+	});
 });
Index: plugins/antispam/filters/class.dc.filter.ip.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.ip.php	(revision 1553)
+++ plugins/antispam/filters/class.dc.filter.ip.php	(revision 2205)
@@ -75,5 +75,6 @@
 
 				$this->addIP($ip_type,$_POST['addip'],$global);
-				http::redirect($url.'&added=1&ip_type='.$ip_type);
+				dcPage::addSuccessNotice(__('IP address has been successfully added.'));
+				http::redirect($url.'&ip_type='.$ip_type);
 			}
 			catch (Exception $e)
@@ -88,5 +89,6 @@
 			try {
 				$this->removeRule($_POST['delip']);
-				http::redirect($url.'&removed=1&ip_type='.$ip_type);
+				dcPage::addSuccessNotice(__('IP addresses have been successfully removed.'));
+				http::redirect($url.'&ip_type='.$ip_type);
 			} catch (Exception $e) {
 				$core->error->add($e->getMessage());
@@ -96,12 +98,5 @@
 		/* DISPLAY
 		---------------------------------------------- */
-		$res = '';
-
-		if (!empty($_GET['added'])) {
-			$res .= dcPage::success(__('IP address has been successfully added.'),true,false,false);
-		}
-		if (!empty($_GET['removed'])) {
-			$res .= dcPage::success(__('IP addresses have been successfully removed.'),true,false,false);
-		}
+		$res = dcPage::notices();
 
 		$res .=
Index: plugins/antispam/filters/class.dc.filter.iplookup.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.iplookup.php	(revision 2122)
+++ plugins/antispam/filters/class.dc.filter.iplookup.php	(revision 2205)
@@ -65,5 +65,6 @@
 				$this->core->blog->settings->addNamespace('antispam');
 				$this->core->blog->settings->antispam->put('antispam_dnsbls',$_POST['bls'],'string','Antispam DNSBL servers',true,false);
-				http::redirect($url.'&upd=1');
+				dcPage::addSuccessNotice(__('The list of DNSBL servers has been succesfully updated.'));
+				http::redirect($url);
 			} catch (Exception $e) {
 				$core->error->add($e->getMessage());
@@ -73,5 +74,5 @@
 		/* DISPLAY
 		---------------------------------------------- */
-		$res = '';
+		$res = dcPage::notices();
 
 		$res .=
Index: plugins/antispam/filters/class.dc.filter.words.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.words.php	(revision 1512)
+++ plugins/antispam/filters/class.dc.filter.words.php	(revision 2205)
@@ -70,5 +70,6 @@
 			try {
 				$this->defaultWordsList();
-				http::redirect($url.'&list=1');
+				dcPage::addSuccessNotice(__('Words have been successfully added.'));
+				http::redirect($url);
 			} catch (Exception $e) {
 				$core->error->add($e->getMessage());
@@ -83,5 +84,6 @@
 			try {
 				$this->addRule($_POST['swa'],$globalsw);
-				http::redirect($url.'&added=1');
+				dcPage::addSuccessNotice(__('Word has been successfully added.'));
+				http::redirect($url);
 			} catch (Exception $e) {
 				$core->error->add($e->getMessage());
@@ -94,5 +96,6 @@
 			try {
 				$this->removeRule($_POST['swd']);
-				http::redirect($url.'&removed=1');
+				dcPage::addSuccessNotice(__('Words have been successfully removed.'));
+				http::redirect($url);
 			} catch (Exception $e) {
 				$core->error->add($e->getMessage());
@@ -102,15 +105,5 @@
 		/* DISPLAY
 		---------------------------------------------- */
-		$res = '';
-
-		if (!empty($_GET['list'])) {
-			$res .= dcPage::message(__('Words have been successfully added.'),true,false,false);
-		}
-		if (!empty($_GET['added'])) {
-			$res .= dcPage::message(__('Word has been successfully added.'),true,false,false);
-		}
-		if (!empty($_GET['removed'])) {
-			$res .= dcPage::message(__('Words have been successfully removed.'),true,false,false);
-		}
+		$res = dcPage::notices();
 
 		$res .=
Index: plugins/blogroll/index.php
===================================================================
--- plugins/blogroll/index.php	(revision 2166)
+++ plugins/blogroll/index.php	(revision 2208)
@@ -207,5 +207,5 @@
 ?>
 
-<div class="multi-part" id="links-list" title="<?php echo __('Blogroll'); ?>">
+<div class="multi-part" id="main-list" title="<?php echo __('Blogroll'); ?>">
 
 <?php if (!$rs->isEmpty()) { ?>
Index: plugins/widgets/_default_widgets.php
===================================================================
--- plugins/widgets/_default_widgets.php	(revision 1610)
+++ plugins/widgets/_default_widgets.php	(revision 2198)
@@ -50,4 +50,5 @@
 $__widgets->categories->setting('title',__('Title:'),__('Categories'));
 $__widgets->categories->setting('postcount',__('With entries counts'),0,'check');
+$__widgets->categories->setting('subcatscount', __('Include sub cats in count'), false, 'check');
 $__widgets->categories->setting('with_empty',__('Include empty categories'),0,'check');
 $__widgets->categories->setting('homeonly',__('Display on:'),0,'combo',
Index: plugins/widgets/_widgets_functions.php
===================================================================
--- plugins/widgets/_widgets_functions.php	(revision 1610)
+++ plugins/widgets/_widgets_functions.php	(revision 2198)
@@ -108,5 +108,5 @@
 			'<a href="'.$core->blog->url.$core->url->getURLFor('category', $rs->cat_url).'">'.
 			html::escapeHTML($rs->cat_title).'</a>'.
-			($w->postcount ? ' <span>('.$rs->nb_post.')</span>' : '');
+			($w->postcount ? ' <span>('.($w->subcatscount ? $rs->nb_total : $rs->nb_post).')</span>' : '');
 			
 			
Index: tests/functional/fixtures/entries_list.html
===================================================================
--- tests/functional/fixtures/entries_list.html	(revision 2200)
+++ tests/functional/fixtures/entries_list.html	(revision 2200)
@@ -0,0 +1,21 @@
+<form action="#" method="post" id="form-entries">
+  <ul>
+    <li>
+      <input type="checkbox" name="entries[]" value="1"/>
+      <p>title 1</p>
+    </li>
+    <li>
+      <input type="checkbox" name="entries[]" value="2"/>
+      <p>title 2</p>
+    </li>
+    <li>
+      <input type="checkbox" name="entries[]" value="3"/>
+      <p>title 3</p>
+    </li>
+    <li>
+      <input type="checkbox" name="entries[]" value="4"/>
+      <p>title 4</p>
+    </li>
+  </ul>
+  <p class="col checkboxes-helpers"></p>
+</form>
Index: tests/functional/js/fix_include.js
===================================================================
--- tests/functional/js/fix_include.js	(revision 1724)
+++ tests/functional/js/fix_include.js	(revision 2200)
@@ -20,2 +20,6 @@
 dotclear.msg.enhanced_uploader_disable = 'Temporarily disable enhanced uploader';
 
+dotclear.msg.to_select = 'Select:';
+dotclear.msg.select_all = 'select all';
+dotclear.msg.no_selection = 'no selection';
+dotclear.msg.invert_sel = 'invert selection';
Index: tests/functional/spec/common.js
===================================================================
--- tests/functional/spec/common.js	(revision 1724)
+++ tests/functional/spec/common.js	(revision 2200)
@@ -81,3 +81,56 @@
 		});
 	});
+
+	describe("checkboxesHelpers", function() {
+		it("Must add links to select all,none or invert selection", function() {
+			loadFixtures('entries_list.html');
+			dotclear.checkboxesHelpers($('.checkboxes-helpers', '#form-entries'));
+
+			expect($('.checkboxes-helpers a', '#form-entries').length).toBe(3);
+			expect($('.checkboxes-helpers a:eq(0)', '#form-entries').text()).toBe(dotclear.msg.select_all);
+			expect($('.checkboxes-helpers a:eq(1)', '#form-entries').text()).toBe(dotclear.msg.no_selection);
+			expect($('.checkboxes-helpers a:eq(2)', '#form-entries').text()).toBe(dotclear.msg.invert_sel);
+		});
+
+		it("Click all must select all checkboxes", function() {
+			loadFixtures('entries_list.html');
+			dotclear.checkboxesHelpers($('.checkboxes-helpers', '#form-entries'));
+			
+			$('.checkboxes-helpers a:eq(0)').click();
+			expect($('#form-entries input[name="entries[]"]:checked').length).toBe(4);
+		});
+
+		it("Click 'no selection'  must uncheck all checkboxes", function() {
+			loadFixtures('entries_list.html');
+			dotclear.checkboxesHelpers($('.checkboxes-helpers', '#form-entries'));
+
+			$('input[name="entries[]"]:eq(1)').click();
+			$('input[name="entries[]"]:eq(3)').click();
+			$('.checkboxes-helpers a:eq(1)').click();
+			expect($('#form-entries input[name="entries[]"]:checked').length).toBe(0);
+		});
+
+		it("Click invert must select all uncheck checkboxes", function() {
+			loadFixtures('entries_list.html');
+			dotclear.checkboxesHelpers($('.checkboxes-helpers', '#form-entries'));
+			
+			$('input[name="entries[]"]:eq(1)').click();
+			$('.checkboxes-helpers a:eq(2)').click();
+			expect($('#form-entries input[name="entries[]"]:checked').length).toBe(3);
+			expect($('input[name="entries[]"]:eq(0)')).toBeChecked();
+			expect($('input[name="entries[]"]:eq(1)')).not.toBeChecked();
+			expect($('input[name="entries[]"]:eq(2)')).toBeChecked();
+			expect($('input[name="entries[]"]:eq(3)')).toBeChecked();
+		});
+
+		it("Must take in consideration checkbox added dynamically", function() {
+			loadFixtures('entries_list.html');
+			dotclear.checkboxesHelpers($('.checkboxes-helpers', '#form-entries'));
+
+			$('<li><input type="checkbox" name="entries[]" value="5"/><p>title 5</p></li>').appendTo('#form-entries ul');
+
+			$('.checkboxes-helpers a:eq(0)').click();
+			expect($('#form-entries input[name="entries[]"]:checked').length).toBe(5);
+		});
+	});
 });
