diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php
index 8eacca6f09ed46c4511a2f514a60cd329b91e5c1..6c9b964ead9d3961794406f1c358ba0202bd67b3 100644
--- a/htdocs/projet/tasks/time.php
+++ b/htdocs/projet/tasks/time.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2005		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
- * Copyright (C) 2006-2015	Laurent Destailleur		<eldy@users.sourceforge.net>
+ * Copyright (C) 2006-2016	Laurent Destailleur		<eldy@users.sourceforge.net>
  * Copyright (C) 2010-2012	Regis Houssin			<regis.houssin@capnetworks.com>
  * Copyright (C) 2011		Juanjo Menent			<jmenent@2byte.es>
  *
@@ -40,11 +40,31 @@ $confirm=GETPOST('confirm','alpha');
 $withproject=GETPOST('withproject','int');
 $project_ref=GETPOST('project_ref','alpha');
 
+$search_dateday=GETPOST('search_dateday');
+$search_datemonth=GETPOST('search_datemonth');
+$search_dateyear=GETPOST('search_dateyear');
+$search_datehour='';
+$search_datewithhour='';
+$search_note=GETPOST('search_note','alpha');
+$search_duration=GETPOST('search_duration','int');
+$search_value=GETPOST('search_value','int');
+
 // Security check
 $socid=0;
 if ($user->societe_id > 0) $socid = $user->societe_id;
 if (!$user->rights->projet->lire) accessforbidden();
 
+$limit = GETPOST("limit")?GETPOST("limit","int"):$conf->liste_limit;
+$sortfield = GETPOST("sortfield",'alpha');
+$sortorder = GETPOST("sortorder",'alpha');
+$page = GETPOST("page",'int');
+if ($page == -1) { $page = 0; }
+$offset = $limit * $page;
+$pageprev = $page - 1;
+$pagenext = $page + 1;
+if (! $sortfield) $sortfield='t.task_date,t.task_datehour,t.rowid';
+if (! $sortorder) $sortorder='DESC';
+
 $object = new Task($db);
 $projectstatic = new Project($db);
 
@@ -53,6 +73,28 @@ $projectstatic = new Project($db);
  * Actions
  */
 
+$parameters=array('socid'=>$socid, 'projectid'=>$projectid);
+$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
+if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+
+include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
+
+// Purge search criteria
+if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") ||GETPOST("button_removefilter")) // All test are required to be compatible with all browsers
+{
+    $search_date='';
+    $search_datehour='';
+    $search_datewithhour='';
+    $search_note='';
+    $search_duration='';
+    $search_value='';
+    $search_date_creation='';
+    $search_date_update='';
+    $toselect='';
+    $search_array_options=array();
+    $action='';
+}
+
 if ($action == 'addtimespent' && $user->rights->projet->lire)
 {
 	$error=0;
@@ -202,7 +244,6 @@ if (GETPOST('projectid'))
     
 }
 
-
     
 /*
  * View
@@ -247,7 +288,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
 
 			print '<table class="border" width="100%">';
 
-	       $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php">'.$langs->trans("BackToList").'</a>';
+	        $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php">'.$langs->trans("BackToList").'</a>';
 			
 			// Ref
 			print '<tr><td class="titlefield">';
@@ -492,6 +533,29 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
 	
 	if ($projectstatic->id > 0)
 	{	
+	    // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
+	    $hookmanager->initHooks(array('tasktimelist'));
+	    $extrafields = new ExtraFields($db);
+
+	    // Definition of fields for list
+	    $arrayfields=array(
+	        't.task_date'=>array('label'=>$langs->trans("Date"), 'checked'=>1),
+	        'author'=>array('label'=>$langs->trans("By"), 'checked'=>1),
+	        't.note'=>array('label'=>$langs->trans("Note"), 'checked'=>1),
+	        't.task_duration'=>array('label'=>$langs->trans("Duration"), 'checked'=>1),
+	        'value'=>array('label'=>$langs->trans("Value"), 'checked'=>1, 'enabled'=>$conf->salaries->enabled),
+	    );
+	    // Extra fields
+	    if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
+	    {
+	        foreach($extrafields->attribute_label as $key => $val)
+	        {
+	            $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]);
+	        }
+	    }
+
+
+	    
 		/*
 		 *  List of time spent
 		 */
@@ -503,8 +567,10 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
 		$sql .= " , ".MAIN_DB_PREFIX."user as u";
 		$sql .= " WHERE t.fk_user = u.rowid";
 		if (empty($projectidforalltimes)) $sql .= " AND t.fk_task =".$object->id;
-		$sql .= " ORDER BY t.task_date DESC, t.task_datehour DESC, t.rowid DESC";
-
+		if ($search_ref) $sql .= natural_search('c.ref', $search_ref);
+		
+		$sql .= $db->order($sortfield, $sortorder);
+        
 		$var=true;
 		$resql = $db->query($sql);
 		if ($resql)
@@ -534,25 +600,138 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
 			dol_print_error($db);
 		}
 
+		
+		
+		$arrayofselected=is_array($toselect)?$toselect:array();
+		
+		$params='';
+		if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage;
+		if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
+		if ($search_note != '') $params.= '&amp;search_note='.urlencode($search_note);
+		if ($search_duration != '') $params.= '&amp;search_field2='.urlencode($search_duration);
+		if ($optioncss != '') $param.='&optioncss='.$optioncss;
+		// Add $param from extra fields
+		/*foreach ($search_array_options as $key => $val)
+		{
+		    $crit=$val;
+		    $tmpkey=preg_replace('/search_options_/','',$key);
+		    if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val);
+		}*/
+		if ($projectstatic->id) $params.='&amp;projectid='.$projectstatic->id;
+		if ($withproject) $params.='&amp;withproject='.$withproject;
+		
+		
+		$arrayofmassactions =  array(
+		    //'presend'=>$langs->trans("SendByMail"),
+		    //'builddoc'=>$langs->trans("PDFMerge"),
+		);
+		//if ($user->rights->projet->creer) $arrayofmassactions['delete']=$langs->trans("Delete");
+		if ($massaction == 'presend') $arrayofmassactions=array();
+		$massactionbutton=$form->selectMassAction('', $arrayofmassactions);
+		
+		
+		
 		print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'">';
+        if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
 		print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-		print '<input type="hidden" name="action" value="updateline">';
-		print '<input type="hidden" name="id" value="'.$object->id.'">';
+	    print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
+		print '<input type="hidden" name="action" value="list">';
+	    print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
+	    print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
+		
+	    print '<input type="hidden" name="projectid" value="'.$projectstatic->id.'">';
 		print '<input type="hidden" name="withproject" value="'.$withproject.'">';
 
-		print '<table class="noborder" width="100%">';
-		print '<tr class="liste_titre">';
-		print '<td width="100">'.$langs->trans("Date").'</td>';
-		print '<td>'.$langs->trans("By").'</td>';
-		print '<td align="left">'.$langs->trans("Note").'</td>';
-		print '<td align="right">'.$langs->trans("TimeSpent").'</td>';
-		if (! empty($conf->salaries->enabled))
+		$moreforfilter = '';
+		
+		$parameters=array();
+		$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters);    // Note that $action and $object may have been modified by hook
+		if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint;
+		else $moreforfilter = $hookmanager->resPrint;
+		
+		if (! empty($moreforfilter))
 		{
-			print '<td align="right">'.$langs->trans("Value").'</td>';
+		    print '<div class="liste_titre liste_titre_bydiv centpercent">';
+		    print $moreforfilter;
+		    print '</div>';
 		}
-		print '<td>&nbsp;</td>';
+		
+		$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
+		$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
+		
+		print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
+		
+		print '<tr class="liste_titre">';
+        if (! empty($arrayfields['t.task_date']['checked'])) print_liste_field_titre($arrayfields['t.task_date']['label'],$_SERVER['PHP_SELF'],'t.task_date,t.task_datehour,t.rowid','',$params,'',$sortfield,$sortorder);
+        if (! empty($arrayfields['t.task_datehour']['checked'])) print_liste_field_titre($arrayfields['t.task_datehour']['label'],$_SERVER['PHP_SELF'],'t.task_date,t.task_datehour,t.rowid','',$params,'',$sortfield,$sortorder);
+        if (! empty($arrayfields['author']['checked'])) print_liste_field_titre($arrayfields['author']['label'],$_SERVER['PHP_SELF'],'','',$params,'',$sortfield,$sortorder);
+		if (! empty($arrayfields['t.note']['checked'])) print_liste_field_titre($arrayfields['t.note']['label'],$_SERVER['PHP_SELF'],'t.note','',$params,'',$sortfield,$sortorder);
+		if (! empty($arrayfields['t.task_duration']['checked'])) print_liste_field_titre($arrayfields['t.task_duration']['label'],$_SERVER['PHP_SELF'],'t.task_duration','',$params,'align="right"',$sortfield,$sortorder);
+		if (! empty($arrayfields['value']['checked'])) print_liste_field_titre($arrayfields['value']['label'],$_SERVER['PHP_SELF'],'','',$params,'align="right"',$sortfield,$sortorder);
+		// Extra fields
+		/*
+    	if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
+    	{
+    	   foreach($extrafields->attribute_label as $key => $val) 
+    	   {
+               if (! empty($arrayfields["ef.".$key]['checked'])) 
+               {
+    				$align=$extrafields->getAlignFlag($key);
+    				print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],"ef.".$key,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder);
+               }
+    	   }
+    	}*/
+	    // Hook fields
+    	$parameters=array('arrayfields'=>$arrayfields);
+        $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters);    // Note that $action and $object may have been modified by hook
+        print $hookmanager->resPrint;
+    	print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="right"',$sortfield,$sortorder,'maxwidthsearch ');
 		print "</tr>\n";
 
+		// Fields title search
+		print '<tr class="liste_titre">';
+		// LIST_OF_TD_TITLE_SEARCH
+		if (! empty($arrayfields['t.task_date']['checked'])) print '<td class="liste_titre"></td>';
+		if (! empty($arrayfields['t.task_datehour']['checked'])) print '<td class="liste_titre"></td>';
+		if (! empty($arrayfields['author']['checked'])) print '<td class="liste_titre"></td>';
+		if (! empty($arrayfields['t.note']['checked'])) print '<td class="liste_titre"><input type="text" class="flat" name="search_note" value="'.$search_note.'" size="10"></td>';
+		if (! empty($arrayfields['t.task_duration']['checked'])) print '<td class="liste_titre right"></td>';
+		if (! empty($arrayfields['value']['checked'])) print '<td class="liste_titre"></td>';
+		// Extra fields
+		/*
+		if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
+		{
+		    foreach($extrafields->attribute_label as $key => $val)
+		    {
+		        if (! empty($arrayfields["ef.".$key]['checked']))
+		        {
+		            $align=$extrafields->getAlignFlag($key);
+		            $typeofextrafield=$extrafields->attribute_type[$key];
+		            print '<td class="liste_titre'.($align?' '.$align:'').'">';
+		            if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select')))
+		            {
+		                $crit=$val;
+		                $tmpkey=preg_replace('/search_options_/','',$key);
+		                $searchclass='';
+		                if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring';
+		                if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum';
+		                print '<input class="flat'.($searchclass?' '.$searchclass:'').'" size="4" type="text" name="search_options_'.$tmpkey.'" value="'.dol_escape_htmltag($search_array_options['search_options_'.$tmpkey]).'">';
+		            }
+		            print '</td>';
+		        }
+		    }
+		}*/
+		// Fields from hook
+		$parameters=array('arrayfields'=>$arrayfields);
+		$reshook=$hookmanager->executeHooks('printFieldListOption',$parameters);    // Note that $action and $object may have been modified by hook
+		print $hookmanager->resPrint;
+		// Action column
+		print '<td class="liste_titre" align="right">';
+		$searchpitco=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1);
+		print $searchpitco;
+		print '</td>';
+		print '</tr>'."\n";		
+		
 		$total = 0;
 		$totalvalue = 0;
 		foreach ($tasks as $task_time)
@@ -564,76 +743,92 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
 			$date2=$db->jdate($task_time->task_datehour);
 
 			// Date
-			print '<td class="nowrap">';
-			if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
+			if (! empty($arrayfields['t.task_date']['checked']))
 			{
-				print $form->select_date(($date2?$date2:$date1),'timeline',1,1,2,"timespent_date",1,0,1);
-			}
-			else
-			{
-				print dol_print_date(($date2?$date2:$date1),($task_time->task_date_withhour?'dayhour':'day'));
+    			print '<td class="nowrap">';
+    			if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
+    			{
+    				print $form->select_date(($date2?$date2:$date1),'timeline',1,1,2,"timespent_date",1,0,1);
+    			}
+    			else
+    			{
+    				print dol_print_date(($date2?$date2:$date1),($task_time->task_date_withhour?'dayhour':'day'));
+    			}
+    			print '</td>';
 			}
-			print '</td>';
-
 			// User
-			print '<td>';
-			if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
-			{
-				$contactsoftask=$object->getListContactId('internal');
-				if (!in_array($task_time->fk_user,$contactsoftask)) {
-					$contactsoftask[]=$task_time->fk_user;
-				}
-				if (count($contactsoftask)>0) {
-					print img_object('','user','class="hideonsmartphone"');
-					print $form->select_dolusers($task_time->fk_user,'userid_line',0,'',0,'',$contactsoftask);
-				}else {
-					print img_error($langs->trans('FirstAddRessourceToAllocateTime')).$langs->trans('FirstAddRessourceToAllocateTime');
-				}
-			}
-			else
-			{
-				$userstatic->id         = $task_time->fk_user;
-				$userstatic->lastname	= $task_time->lastname;
-				$userstatic->firstname 	= $task_time->firstname;
-				print $userstatic->getNomUrl(1);
-			}
-			print '</td>';
+            if (! empty($arrayfields['author']['checked'])) 
+            {
+                print '<td>';
+    			if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
+    			{
+    				$contactsoftask=$object->getListContactId('internal');
+    				if (!in_array($task_time->fk_user,$contactsoftask)) {
+    					$contactsoftask[]=$task_time->fk_user;
+    				}
+    				if (count($contactsoftask)>0) {
+    					print img_object('','user','class="hideonsmartphone"');
+    					print $form->select_dolusers($task_time->fk_user,'userid_line',0,'',0,'',$contactsoftask);
+    				}else {
+    					print img_error($langs->trans('FirstAddRessourceToAllocateTime')).$langs->trans('FirstAddRessourceToAllocateTime');
+    				}
+    			}
+    			else
+    			{
+    				$userstatic->id         = $task_time->fk_user;
+    				$userstatic->lastname	= $task_time->lastname;
+    				$userstatic->firstname 	= $task_time->firstname;
+    				print $userstatic->getNomUrl(1);
+    			}
+    			print '</td>';
+            }
 
 			// Note
-			print '<td align="left">';
-			if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
-			{
-				print '<textarea name="timespent_note_line" width="95%" rows="'.ROWS_2.'">'.$task_time->note.'</textarea>';
-			}
-			else
-			{
-				print dol_nl2br($task_time->note);
-			}
-			print '</td>';
-
+            if (! empty($arrayfields['t.note']['checked'])) 
+            {
+                print '<td align="left">';
+    			if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
+    			{
+    				print '<textarea name="timespent_note_line" width="95%" rows="'.ROWS_2.'">'.$task_time->note.'</textarea>';
+    			}
+    			else
+    			{
+    				print dol_nl2br($task_time->note);
+    			}
+    			print '</td>';
+            }
+            
 			// Time spent
-			print '<td align="right">';
-			if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
-			{
-				print '<input type="hidden" name="old_duration" value="'.$task_time->task_duration.'">';
-				print $form->select_duration('new_duration',$task_time->task_duration,0,'text');
-			}
-			else
-			{
-				print convertSecondToTime($task_time->task_duration,'allhourmin');
-			}
-			print '</td>';
-
+            if (! empty($arrayfields['t.task_duration']['checked']))
+            {
+    			print '<td align="right">';
+    			if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
+    			{
+    				print '<input type="hidden" name="old_duration" value="'.$task_time->task_duration.'">';
+    				print $form->select_duration('new_duration',$task_time->task_duration,0,'text');
+    			}
+    			else
+    			{
+    				print convertSecondToTime($task_time->task_duration,'allhourmin');
+    			}
+    			print '</td>';
+            }
+            
 			// Value spent
-			if ($conf->salaries->enabled)
-			{
+            if (! empty($arrayfields['value']['checked'])) 
+            {
 				print '<td align="right">';
 				print price(price2num($task_time->thm * $task_time->task_duration / 3600), 1, $langs, 1, -1, -1, $conf->currency);
 				print '</td>';
 			}
 
-			// Edit and delete icon
-			print '<td align="center" valign="middle" width="80">';
+			// Fields from hook
+			$parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj);
+			$reshook=$hookmanager->executeHooks('printFieldListValue',$parameters);    // Note that $action and $object may have been modified by hook
+			print $hookmanager->resPrint;
+		
+            // Action column
+			print '<td class="right" valign="middle" width="80">';
 			if ($action == 'editline' && $_GET['lineid'] == $task_time->rowid)
 			{
 				print '<input type="hidden" name="lineid" value="'.$_GET['lineid'].'">';
@@ -659,6 +854,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
 			$total += $task_time->task_duration;
 			$totalvalue += price2num($task_time->thm * $task_time->task_duration / 3600);
 		}
+		
 		print '<tr class="liste_total"><td colspan="3" class="liste_total">'.$langs->trans("Total").'</td>';
 		print '<td align="right" class="nowrap liste_total">'.convertSecondToTime($total,'allhourmin').'</td>';
 		if ($conf->salaries->enabled)