Index: admin/index.php
===================================================================
--- admin/index.php	(revision 3)
+++ admin/index.php	(revision 13)
@@ -43,4 +43,25 @@
 $plugins_install = $core->plugins->installModules();
 
+# Check dashboard module prefs
+$core->auth->user_prefs->addWorkspace('dashboard');
+if (!$core->auth->user_prefs->dashboard->prefExists('doclinks')) {
+	if (!$core->auth->user_prefs->dashboard->prefExists('doclinks',true)) {
+		$core->auth->user_prefs->dashboard->put('doclinks',true,'boolean','',null,true);
+	}
+	$core->auth->user_prefs->dashboard->put('doclinks',true,'boolean');
+}
+if (!$core->auth->user_prefs->dashboard->prefExists('dcnews')) {
+	if (!$core->auth->user_prefs->dashboard->prefExists('dcnews',true)) {
+		$core->auth->user_prefs->dashboard->put('dcnews',true,'boolean','',null,true);
+	}
+	$core->auth->user_prefs->dashboard->put('dcnews',true,'boolean');
+}
+if (!$core->auth->user_prefs->dashboard->prefExists('quickentry')) {
+	if (!$core->auth->user_prefs->dashboard->prefExists('quickentry',true)) {
+		$core->auth->user_prefs->dashboard->put('quickentry',true,'boolean','',null,true);
+	}
+	$core->auth->user_prefs->dashboard->put('quickentry',true,'boolean');
+}
+
 # Dashboard icons
 $__dashboard_icons = new ArrayObject();
@@ -91,53 +112,60 @@
 
 # Documentation links
-if (!empty($__resources['doc']))
-{
-	$doc_links = '<h3>'.__('Documentation').'</h3><ul>';
-	
-	foreach ($__resources['doc'] as $k => $v) {
-		$doc_links .= '<li><a href="'.$v.'">'.$k.'</a></li>';
-	}
-	
-	$doc_links .= '</ul>';
-	$__dashboard_items[0][] = $doc_links;
-}
-
-try
-{
-	if (empty($__resources['rss_news'])) {
-		throw new Exception();
-	}
-	
-	$feed_reader = new feedReader;
-	$feed_reader->setCacheDir(DC_TPL_CACHE);
-	$feed_reader->setTimeout(2);
-	$feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/');
-	$feed = $feed_reader->parse($__resources['rss_news']);
-	if ($feed)
+$dashboardItem = 0;
+if ($core->auth->user_prefs->dashboard->doclinks) {
+	if (!empty($__resources['doc']))
 	{
-		$latest_news = '<h3>'.__('Latest news').'</h3><dl id="news">';
-		$i = 1;
-		foreach ($feed->items as $item)
+		$doc_links = '<h3>'.__('Documentation').'</h3><ul>';
+	
+		foreach ($__resources['doc'] as $k => $v) {
+			$doc_links .= '<li><a href="'.$v.'">'.$k.'</a></li>';
+		}
+	
+		$doc_links .= '</ul>';
+		$__dashboard_items[$dashboardItem][] = $doc_links;
+		$dashboardItem++;
+	}
+}
+
+if ($core->auth->user_prefs->dashboard->dcnews) {
+	try
+	{
+		if (empty($__resources['rss_news'])) {
+			throw new Exception();
+		}
+	
+		$feed_reader = new feedReader;
+		$feed_reader->setCacheDir(DC_TPL_CACHE);
+		$feed_reader->setTimeout(2);
+		$feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/');
+		$feed = $feed_reader->parse($__resources['rss_news']);
+		if ($feed)
 		{
-			$dt = isset($item->link) ? '<a href="'.$item->link.'">'.$item->title.'</a>' : $item->title;
+			$latest_news = '<h3>'.__('Latest news').'</h3><dl id="news">';
+			$i = 1;
+			foreach ($feed->items as $item)
+			{
+				$dt = isset($item->link) ? '<a href="'.$item->link.'">'.$item->title.'</a>' : $item->title;
 			
-			if ($i < 3) {
-				$latest_news .=
-				'<dt>'.$dt.'</dt>'.
-				'<dd><p><strong>'.dt::dt2str('%d %B %Y',$item->pubdate,'Europe/Paris').'</strong>: '.
-				'<em>'.text::cutString(html::clean($item->content),120).'...</em></p></dd>';
-			} else {
-				$latest_news .=
-				'<dt>'.$dt.'</dt>'.
-				'<dd>'.dt::dt2str('%d %B %Y',$item->pubdate,'Europe/Paris').'</dd>';
+				if ($i < 3) {
+					$latest_news .=
+					'<dt>'.$dt.'</dt>'.
+					'<dd><p><strong>'.dt::dt2str('%d %B %Y',$item->pubdate,'Europe/Paris').'</strong>: '.
+					'<em>'.text::cutString(html::clean($item->content),120).'...</em></p></dd>';
+				} else {
+					$latest_news .=
+					'<dt>'.$dt.'</dt>'.
+					'<dd>'.dt::dt2str('%d %B %Y',$item->pubdate,'Europe/Paris').'</dd>';
+				}
+				$i++;
+				if ($i > 3) { break; }
 			}
-			$i++;
-			if ($i > 3) { break; }
-		}
-		$latest_news .= '</dl>';
-		$__dashboard_items[1][] = $latest_news;
-	}
-}
-catch (Exception $e) {}
+			$latest_news .= '</dl>';
+			$__dashboard_items[$dashboardItem][] = $latest_news;
+			$dashboardItem++;
+		}
+	}
+	catch (Exception $e) {}
+}
 
 $core->callBehavior('adminDashboardItems', $core, $__dashboard_items);
@@ -202,45 +230,47 @@
 echo '</div>';
 
-if ($core->auth->check('usage,contentadmin',$core->blog->id))
-{
-	$categories_combo = array('&nbsp;' => '');
-	try {
-		$categories = $core->blog->getCategories(array('post_type'=>'post'));
-		while ($categories->fetch()) {
-			$categories_combo[] = new formSelectOption(
-				str_repeat('&nbsp;&nbsp;',$categories->level-1).'&bull; '.html::escapeHTML($categories->cat_title),
-				$categories->cat_id
-			);
-		}
-	} catch (Exception $e) { }
-	
-	echo
-	'<div id="quick">'.
-	'<h3>'.__('Quick entry').'</h3>'.
-	'<form id="quick-entry" action="post.php" method="post">'.
-	'<fieldset>'.
-	'<p class="col"><label class="required" title="'.__('Required field').'">'.__('Title:').
-	form::field('post_title',20,255,'','maximal',2).
-	'</label></p>'.
-	'<p class="area"><label class="required" title="'.__('Required field').'" '.
-	'for="post_content">'.__('Content:').'</label> '.
-	form::textarea('post_content',50,7,'','',2).
-	'</p>'.
-	'<p><label class="classic">'.__('Category:').' '.
-	form::combo('cat_id',$categories_combo,'','',2).'</label></p>'.
-	'<p><input type="submit" value="'.__('save').'" name="save" tabindex="3" /> '.
-	($core->auth->check('publish',$core->blog->id)
-		? '<input type="hidden" value="'.__('save and publish').'" name="save-publish" />'
-		: '').
-	$core->formNonce().
-	form::hidden('post_status',-2).
-	form::hidden('post_format',$core->auth->getOption('post_format')).
-	form::hidden('post_excerpt','').
-	form::hidden('post_lang',$core->auth->getInfo('user_lang')).
-	form::hidden('post_notes','').
-	'</p>'.
-	'</fieldset>'.
-	'</form>'.
-	'</div>';
+if ($core->auth->user_prefs->dashboard->quickentry) {
+	if ($core->auth->check('usage,contentadmin',$core->blog->id))
+	{
+		$categories_combo = array('&nbsp;' => '');
+		try {
+			$categories = $core->blog->getCategories(array('post_type'=>'post'));
+			while ($categories->fetch()) {
+				$categories_combo[] = new formSelectOption(
+					str_repeat('&nbsp;&nbsp;',$categories->level-1).'&bull; '.html::escapeHTML($categories->cat_title),
+					$categories->cat_id
+				);
+			}
+		} catch (Exception $e) { }
+	
+		echo
+		'<div id="quick">'.
+		'<h3>'.__('Quick entry').'</h3>'.
+		'<form id="quick-entry" action="post.php" method="post">'.
+		'<fieldset>'.
+		'<p class="col"><label class="required" title="'.__('Required field').'">'.__('Title:').
+		form::field('post_title',20,255,'','maximal',2).
+		'</label></p>'.
+		'<p class="area"><label class="required" title="'.__('Required field').'" '.
+		'for="post_content">'.__('Content:').'</label> '.
+		form::textarea('post_content',50,7,'','',2).
+		'</p>'.
+		'<p><label class="classic">'.__('Category:').' '.
+		form::combo('cat_id',$categories_combo,'','',2).'</label></p>'.
+		'<p><input type="submit" value="'.__('save').'" name="save" tabindex="3" /> '.
+		($core->auth->check('publish',$core->blog->id)
+			? '<input type="hidden" value="'.__('save and publish').'" name="save-publish" />'
+			: '').
+		$core->formNonce().
+		form::hidden('post_status',-2).
+		form::hidden('post_format',$core->auth->getOption('post_format')).
+		form::hidden('post_excerpt','').
+		form::hidden('post_lang',$core->auth->getInfo('user_lang')).
+		form::hidden('post_notes','').
+		'</p>'.
+		'</fieldset>'.
+		'</form>'.
+		'</div>';
+	}
 }
 
Index: admin/install/index.php
===================================================================
--- admin/install/index.php	(revision 3)
+++ admin/install/index.php	(revision 13)
@@ -185,4 +185,10 @@
 		$core->plugins->loadModules(DC_PLUGINS_ROOT);
 		$plugins_install = $core->plugins->installModules();
+		
+		# Add dashboard module options
+		$core->auth->user_prefs->addWorkspace('dashboard');
+		$core->auth->user_prefs->dashboard->put('doclinks',true,'boolean','',null,true);
+		$core->auth->user_prefs->dashboard->put('dcnews',true,'boolean','',null,true);
+		$core->auth->user_prefs->dashboard->put('quickentry',true,'boolean','',null,true);
 		
 		# Add default favorites
Index: admin/preferences.php
===================================================================
--- admin/preferences.php	(revision 11)
+++ admin/preferences.php	(revision 13)
@@ -28,8 +28,15 @@
 $user_options = $core->auth->getOptions();
 
+$core->auth->user_prefs->addWorkspace('dashboard');
+$user_dm_doclinks = $core->auth->user_prefs->dashboard->doclinks;
+$user_dm_dcnews = $core->auth->user_prefs->dashboard->dcnews;
+$user_dm_quickentry = $core->auth->user_prefs->dashboard->quickentry;
+
 $default_tab = 'user-profile';
 
 if (!empty($_GET['append']) || !empty($_GET['removed']) || !empty($_GET['neworder'])) {
 	$default_tab = 'user-favorites';
+} elseif (!empty($_GET['updated'])) {
+	$default_tab = 'user-options';
 }
 
@@ -69,13 +76,5 @@
 		$cur->user_lang = $user_lang = $_POST['user_lang'];
 		$cur->user_tz = $user_tz = $_POST['user_tz'];
-		$cur->user_post_status = $user_post_status = $_POST['user_post_status'];
-		
-		$user_options['edit_size'] = (integer) $_POST['user_edit_size'];
-		if ($user_options['edit_size'] < 1) {
-			$user_options['edit_size'] = 10;
-		}
-		$user_options['post_format'] = $_POST['user_post_format'];
-		$user_options['enable_wysiwyg'] = !empty($_POST['user_wysiwyg']);
-		
+
 		$cur->user_options = new ArrayObject($user_options);
 		
@@ -94,5 +93,5 @@
 		
 		# --BEHAVIOR-- adminBeforeUserUpdate
-		$core->callBehavior('adminBeforeUserUpdate',$cur,$core->auth->userID());
+		$core->callBehavior('adminBeforeUserProfileUpdate',$cur,$core->auth->userID());
 		
 		# Udate user
@@ -100,7 +99,54 @@
 		
 		# --BEHAVIOR-- adminAfterUserUpdate
+		$core->callBehavior('adminAfterUserProfileUpdate',$cur,$core->auth->userID());
+		
+		http::redirect('preferences.php?upd=1');
+	}
+	catch (Exception $e)
+	{
+		$core->error->add($e->getMessage());
+	}
+}
+
+# Update user options
+if (isset($_POST['user_post_format'])) {
+	try
+	{
+		$cur = $core->con->openCursor($core->prefix.'user');
+		
+		$cur->user_name = $user_name;
+		$cur->user_firstname = $user_firstname;
+		$cur->user_displayname = $user_displayname;
+		$cur->user_email = $user_email;
+		$cur->user_url = $user_url;
+		$cur->user_lang = $user_lang;
+		$cur->user_tz = $user_tz;
+
+		$cur->user_post_status = $user_post_status = $_POST['user_post_status'];
+		
+		$user_options['edit_size'] = (integer) $_POST['user_edit_size'];
+		if ($user_options['edit_size'] < 1) {
+			$user_options['edit_size'] = 10;
+		}
+		$user_options['post_format'] = $_POST['user_post_format'];
+		$user_options['enable_wysiwyg'] = !empty($_POST['user_wysiwyg']);
+		
+		$cur->user_options = new ArrayObject($user_options);
+		
+		# --BEHAVIOR-- adminBeforeUserUpdate
+		$core->callBehavior('adminBeforeUserUpdate',$cur,$core->auth->userID());
+		
+		# Update user prefs
+		$core->auth->user_prefs->dashboard->put('doclinks',!empty($_POST['user_dm_doclinks']),'boolean');
+		$core->auth->user_prefs->dashboard->put('dcnews',!empty($_POST['user_dm_dcnews']),'boolean');
+		$core->auth->user_prefs->dashboard->put('quickentry',!empty($_POST['user_dm_quickentry']),'boolean');
+		
+		# Udate user
+		$core->updUser($core->auth->userID(),$cur);
+		
+		# --BEHAVIOR-- adminAfterUserUpdate
 		$core->callBehavior('adminAfterUserUpdate',$cur,$core->auth->userID());
 		
-		http::redirect('preferences.php?upd=1');
+		http::redirect('preferences.php?updated=1');
 	}
 	catch (Exception $e)
@@ -233,7 +279,7 @@
 		echo '<p class="message">'.__('Personal information has been successfully updated.').'</p>';
 }
-
-echo '<h2>'.$page_title.'</h2>';
-
+if (!empty($_GET['updated'])) {
+		echo '<p class="message">'.__('Personal options has been successfully updated.').'</p>';
+}
 if (!empty($_GET['append'])) {
 		echo '<p class="message">'.__('Favorites have been successfully added.').'</p>';
@@ -245,4 +291,6 @@
 		echo '<p class="message">'.__('Favorites have been successfully removed.').'</p>';
 }
+
+echo '<h2>'.$page_title.'</h2>';
 
 # User profile
@@ -316,5 +364,5 @@
 
 echo
-'<form action="preferences.php" method="post" id="user-form">'.
+'<form action="preferences.php" method="post" id="user-options">'.
 '<fieldset><legend>'.__('My options').'</legend>'.
 
@@ -331,4 +379,22 @@
 form::checkbox('user_wysiwyg',1,$user_options['enable_wysiwyg'],'',12).' '.
 __('Enable WYSIWYG mode').'</label></p>'.
+'<br class="clear" />'. //Opera sucks
+'</fieldset>';
+
+echo
+'<fieldset><legend>'.__('Dashboard modules').'</legend>'.
+
+'<p><label for="user_dm_doclinks" class="classic">'.
+form::checkbox('user_dm_doclinks',1,$user_dm_doclinks,'',13).' '.
+__('Display documentation links').'</label></p>'.
+
+'<p><label for="user_dm_dcnews" class="classic">'.
+form::checkbox('user_dm_dcnews',1,$user_dm_dcnews,'',14).' '.
+__('Display Dotclear news').'</label></p>'.
+
+'<p><label for="user_dm_quickentry" class="classic">'.
+form::checkbox('user_dm_quickentry',1,$user_dm_quickentry,'',15).' '.
+__('Display quick entry form').'</label></p>'.
+
 '<br class="clear" />'. //Opera sucks
 '</fieldset>';
Index: inc/core/class.dc.workspace.php
===================================================================
--- inc/core/class.dc.workspace.php	(revision 3)
+++ inc/core/class.dc.workspace.php	(revision 13)
@@ -103,5 +103,5 @@
 	}
 	
-	private function prefExists($id,$global=false)
+	public function prefExists($id,$global=false)
 	{
 		$array = $global ? 'global' : 'local';
Index: locales/fr/main.po
===================================================================
--- locales/fr/main.po	(revision 11)
+++ locales/fr/main.po	(revision 13)
@@ -2704,2 +2704,5 @@
 msgid "Favorites has been successfully updated."
 msgstr "Les favoris ont été mis à jour avec succès."
+
+msgid "Personal options has been successfully updated."
+msgstr "Vos options personnelles ont été enregistrées avec succès."
