diff -aburN --exclude='CVS*' phpgwapi.org/inc/class.categories.inc.php phpgwapi/inc/class.categories.inc.php
--- phpgwapi.org/inc/class.categories.inc.php	2006-01-12 11:35:04.000000000 +0100
+++ phpgwapi/inc/class.categories.inc.php	2006-01-12 11:35:18.000000000 +0100
@@ -523,6 +523,97 @@
 			}
 		}
 
+
+		function formatted_xslt_list($data=0)
+		{
+			if(is_array($data))
+			{
+				$format			= (isset($data['format'])?$data['format']:'filter');
+				$type			= (isset($data['type'])?$data['type']:'all');
+				$selected		= (isset($data['selected'])?$data['selected']:'');
+				$self			= (isset($data['self'])?$data['self']:'');
+				$globals		= (isset($data['globals'])?$data['globals']:True);
+				$link_data		= (isset($data['link_data'])?$data['link_data']:0);
+				$select_name	= (isset($data['select_name'])?$data['select_name']:'cat_id');
+			}
+			else
+			{
+				return False;
+			}
+
+			if (!is_array($selected))
+			{
+				$selected = explode(',',$selected);
+			}
+
+			if ($type != 'all')
+			{
+				$cats = $this->return_array($type,$start,False,$query,$sort,$order,$globals);
+			}
+			else
+			{
+				$cats = $this->return_sorted_array($start,False,$query,$sort,$order,$globals);
+			}
+
+			$GLOBALS['phpgw']->xslttpl->add_file($GLOBALS['phpgw']->common->get_tpl_dir('phpgwapi','default') . SEP . 'categories');
+
+			if($self)
+			{
+				for ($i=0;$i<count($cats);$i++)
+				{
+					if ($cats[$i]['id'] == $self)
+					{
+						unset($cats[$i]);
+					}
+				}
+				reset($cats);
+			}
+
+			while (is_array($cats) && list(,$cat) = each($cats))
+			{
+				$sel_cat = '';
+				if (in_array($cat['id'],$selected))
+				{
+					$sel_cat = 'selected';
+				}
+
+				$name = '';
+				for ($i=0;$i<$cat['level'];$i++)
+				{
+					$name .= '&nbsp;.&nbsp;';
+				}
+				$name .= $GLOBALS['phpgw']->strip_html($cat['name']);
+
+				if ($cat['app_name'] == 'phpgw')
+				{
+					$name .= ' <' . lang('Global') . '>';
+				}
+				if ($cat['owner'] == '-1')
+				{
+					$name .= ' <' . lang('Global') . ' ' . lang($this->app_name) . '>';
+				}
+
+				$cat_list[] = array
+				(
+					'cat_id'	=> $cat['id'],
+					'name'		=> $name,
+					'selected'	=> $sel_cat
+				);
+			}
+
+			$cat_data = array
+			(
+				'cat_list'				=> $cat_list,
+				'lang_no_cat'			=> lang('no category'),
+				'lang_cat_statustext'	=> lang('Select the category the data belong to. To do not use a category select NO CATEGORY'),
+				'select_url'			=> $GLOBALS['phpgw']->link('/index.php',$link_data),
+				'select_name'			=> $select_name,
+				'lang_submit'			=> lang('submit')
+			);
+			return $cat_data;
+		}
+
+
 		/**
 		* Add category
 		*
diff -aburN --exclude='CVS*' phpgwapi.org/inc/class.common.inc.php phpgwapi/inc/class.common.inc.php
--- phpgwapi.org/inc/class.common.inc.php	2006-01-12 11:35:04.000000000 +0100
+++ phpgwapi/inc/class.common.inc.php	2006-01-12 11:35:18.000000000 +0100
@@ -737,13 +737,13 @@
 		* @param string $appname Application name, defaults to $phpgw_info['flags']['currentapp']
 		* @return string Template directory of given application
 		*/
-		function get_tpl_dir($appname = '')
+		function get_tpl_dir($appname = '',$layout = '')
 		{
 			if (! $appname)
 			{
 				$appname = $GLOBALS['phpgw_info']['flags']['currentapp'];
 			}
-			if ($appname == 'home' || $appname == 'logout' || $appname == 'login')
+			if ($appname == 'home' || $appname == 'logout' || $appname == 'login' || $appname == 'about' || $appname == 'help')
 			{
 				$appname = 'phpgwapi';
 			}
@@ -774,6 +774,11 @@
 			$tpldir         = PHPGW_SERVER_ROOT . '/' . $appname . '/templates/' . $GLOBALS['phpgw_info']['server']['template_set'];
 			$tpldir_default = PHPGW_SERVER_ROOT . '/' . $appname . '/templates/default';
 
+			if ($layout == 'default')
+			{
+				$tpldir = $tpldir_default;
+			}
+
 			if (@is_dir($tpldir))
 			{
 				return $tpldir;
@@ -1132,7 +1137,7 @@
 		/**
 		* Load the phpgw header
 		*/
-		function phpgw_header()
+		function phpgw_header($navbar = False)
 		{
 			include(PHPGW_INCLUDE_ROOT . '/phpgwapi/templates/' . $GLOBALS['phpgw_info']['server']['template_set']
 				. '/head.inc.php');
@@ -1143,12 +1148,29 @@
 			{
 				echo parse_navbar();
 			}
+
+			if ($navbar)
+			{
+				echo parse_navbar();
+			}
+
+			/* used for xslt apps without xslt framework */
+			if($GLOBALS['phpgw_info']['flags']['xslt_app'])
+			{
+				$GLOBALS['phpgw']->xslttpl->add_file('app_data');
+			}
 		}
 
 		function phpgw_footer()
 		{
 			if (!defined('PHPGW_FOOTER'))
 			{
+				/* used for xslt apps without xslt framework */
+				if($GLOBALS['phpgw_info']['flags']['xslt_app'])
+				{
+					$GLOBALS['phpgw']->xslttpl->pparse();
+				}
+
 				define('PHPGW_FOOTER',True);
 				if (!isset($GLOBALS['phpgw_info']['flags']['nofooter']) || !$GLOBALS['phpgw_info']['flags']['nofooter'])
 				{
@@ -1994,4 +2016,88 @@
 			return intval($id);
 		}
 
+		/**
+		* Generate a consistant msgbox for app apps to use
+		* makes it easier and more consistant to generate message boxes
+		*
+		* @param string $text ???
+		* @param bool $type ???
+		* @param string $base ???
+		* @returns ????
+		*/
+
+		function msgbox($text = '', $type = True, $base = '')
+		{
+			if ($text=='' && @isset($GLOBALS['phpgw_info']['flags']['msgbox_data']))
+			{
+				$text = $GLOBALS['phpgw_info']['flags']['msgbox_data'];
+				unset($GLOBALS['phpgw_info']['flags']['msgbox_data']);
+			}
+			elseif($text=='')
+			{
+				return;
+			}
+
+			$GLOBALS['phpgw']->xslttpl->add_file($this->get_tpl_dir('phpgwapi','default') . SEP . 'msgbox');
+
+			$prev_helper = $GLOBALS['phpgw']->translation->translator_helper;
+			$GLOBALS['phpgw']->translation->translator_helper = '';
+
+			if (is_array($text))
+			{
+				foreach($text as $key => $value)
+				{
+					if ($value == True)
+					{
+						$img	= $this->image('phpgwapi','msgbox_good');
+						$alt	= lang('OK');
+					}
+					else
+					{
+						$img	= $this->image('phpgwapi','msgbox_bad');
+						$alt	= lang('ERROR');
+					}
+
+					$data[] = array
+					(
+						'msgbox_text'				=> lang($key),
+						'msgbox_img'				=> $img,
+						'msgbox_img_alt'			=> $alt,
+						'lang_msgbox_statustext'	=> $alt
+					);
+				}
+			}
+			else
+			{
+				if ($type == True)
+				{
+					$img	= $this->image('phpgwapi','msgbox_good');
+					$alt	= lang('OK');
+				}
+				else
+				{
+					$img	= $this->image('phpgwapi','msgbox_bad');
+					$alt	= lang('ERROR');
+				}
+
+				$data = array
+				(
+					'msgbox_text'				=> lang($text),
+					'msgbox_img'				=> $img,
+					'msgbox_img_alt'			=> $alt,
+					'lang_msgbox_statustext'	=> $alt
+				);
+			}
+
+			$GLOBALS['phpgw']->translation->translator_helper = $prev_helper;
+
+			if ($base)
+			{
+				$GLOBALS['phpgw']->xslttpl->set_var($base,array('msgbox_data' => $data),True);
+			}
+			else
+			{
+				return $data;
+			}
+		}
 	}
diff -aburN --exclude='CVS*' phpgwapi.org/inc/class.nextmatchs.inc.php phpgwapi/inc/class.nextmatchs.inc.php
--- phpgwapi.org/inc/class.nextmatchs.inc.php	2006-01-12 11:35:04.000000000 +0100
+++ phpgwapi/inc/class.nextmatchs.inc.php	2006-01-12 11:35:18.000000000 +0100
@@ -3,20 +3,27 @@
 	* Handles limiting number of rows displayed
 	* @author Joseph Engo <jengo@phpgroupware.org>
 	* @author Bettina Gille <ceb@phpgroupware.org>
-	* @copyright Copyright (C) 2000-2004 Free Software Foundation, Inc. http://www.fsf.org/
+	* @copyright Copyright (C) 2000-2005 Free Software Foundation, Inc. http://www.fsf.org/
 	* @license http://www.fsf.org/licenses/lgpl.html GNU Lesser General Public License
 	* @package phpgwapi
 	* @subpackage gui
-	* @version $Id: class.nextmatchs.inc.php,v 1.43.2.6.2.11 2004/11/06 15:34:26 powerstat Exp $
+	* @version $Id: class.nextmatchs.inc.php,v 1.73 2005/04/26 09:43:07 powerstat Exp $
 	*/
 
+
+	/**
+	* Include nextmatchs XSLT
+	*/
+	include_once(PHPGW_API_INC . '/class.nextmatchs_xslt.inc.php');
+
+
 	/**
 	* Handles limiting number of rows displayed
 	* 
 	* @package phpgwapi
 	* @subpackage gui
 	*/
-	class nextmatchs
+	class nextmatchs extends nextmatchs_xslt
 	{
 		var $maxmatches;
 		var $action;
@@ -307,11 +314,11 @@
 				($start > $this->maxmatches))
 			{
 				$extravars['start'] = 0;
-				$ret_str .= $this->set_link('left','first.gif',$scriptname,lang('First page'),$extravars);
+				$ret_str .= $this->set_link('left','first',$scriptname,lang('First page'),$extravars);
 			}
 			else
 			{
-				$ret_str .= $this->set_icon('left','first-grey.gif',lang('First page'));
+				$ret_str .= $this->set_icon('left','first-grey',lang('First page'));
 			}
 
 			if ($start != 0)
@@ -325,11 +332,11 @@
 				{
 					$extravars['start'] = ($start - $this->maxmatches);
 				}
-				$ret_str .= $this->set_link('left','left.gif',$scriptname,lang('Previous page'),$extravars);
+				$ret_str .= $this->set_link('left','left',$scriptname,lang('Previous page'),$extravars);
 			}
 			else
 			{
-				$ret_str .= $this->set_icon('left','left-grey.gif',lang('Previous page'));
+				$ret_str .= $this->set_icon('left','left-grey',lang('Previous page'));
 			}
 			return $ret_str;
 		} /* left() */
@@ -362,22 +369,22 @@
 				($total > $start + $this->maxmatches))
 			{
 				$extravars['start'] = ($start + $this->maxmatches);
-				$ret_str .= $this->set_link('right','right.gif',$scriptname,lang('Next page'),$extravars);
+				$ret_str .= $this->set_link('right','right',$scriptname,lang('Next page'),$extravars);
 			}
 			else
 			{
-				$ret_str .= $this->set_icon('right','right-grey.gif',lang('Next page'));
+				$ret_str .= $this->set_icon('right','right-grey',lang('Next page'));
 			}
 
 			if (($start != $total - $this->maxmatches) &&
 				(($total - $this->maxmatches) > ($start + $this->maxmatches)))
 			{
 				$extravars['start'] = ($total - $this->maxmatches);
-				$ret_str .= $this->set_link('right','last.gif',$scriptname,lang('Last page'),$extravars);
+				$ret_str .= $this->set_link('right','last',$scriptname,lang('Last page'),$extravars);
 			}
 			else
 			{
-				$ret_str .= $this->set_icon('right','last-grey.gif',lang('Last page'));
+				$ret_str .= $this->set_icon('right','last-grey',lang('Last page'));
 			}
 			return $ret_str;
 		} /* right() */
@@ -521,7 +528,7 @@
 					{
 						$qfield = $search_obj[$index][0];
 					}
-					$str .= '<option value="' . $search_obj[$index][0] . '"' . ($qfield == $search_obj[$index][0]?' selected="selected"':'') . '>' . lang($search_obj[$index][1]) . '</option>';
+					$str .= '<option value="' . $search_obj[$index][0] . '"' . ($qfield == $search_obj[$index][0]?' selected':'') . '>' . lang($search_obj[$index][1]) . '</option>';
 				}
 				$str = '<select name="qfield">' . $str . '</select>' . "\n";
 			}
@@ -595,7 +602,7 @@
 					{
 						$filter = $filter_obj[$index][0];
 					}
-					$str .= '         <option value="' . $filter_obj[$index][0] . '"'.($filter == $filter_obj[$index][0]?' selected="selected"':'') . '>' . $filter_obj[$index][1] . '</option>'."\n";
+					$str .= '         <option value="' . $filter_obj[$index][0] . '"'.($filter == $filter_obj[$index][0]?' selected':'') . '>' . $filter_obj[$index][1] . '</option>'."\n";
 				}
 
 				$str = '        <select name="filter" onChange="this.form.submit()">'."\n" . $str . '        </select>';
@@ -655,7 +662,7 @@
 				{
 					$filter = $filter_obj[$index][0];
 				}
-				$str .= '         <option value="' . $filter_obj[$index][0] . '"'.($filter == $filter_obj[$index][0]?' selected="selected"':'') . '>' . $filter_obj[$index][1] . '</option>'."\n";
+				$str .= '         <option value="' . $filter_obj[$index][0] . '"'.($filter == $filter_obj[$index][0]?' selected':'') . '>' . $filter_obj[$index][1] . '</option>'."\n";
 			}
 
 			$str = '        <select name="filter" onChange="this.form.submit()">'."\n" . $str . '        </select>';
@@ -685,7 +692,6 @@
 			{
 				$GLOBALS['tr_color'] = $GLOBALS['phpgw_info']['theme']['row_on'];
 			}
-
 			return $GLOBALS['tr_color'];
 		}
 
@@ -710,16 +716,31 @@
 		@param $program ?
 		@param $text ?
 		@param $extra default ''
+		@param $build_an_href default True
 		*/
-		function show_sort_order($sort,$var,$order,$program,$text,$extra='',$build_a_href=True)
+		function show_sort_order($sort, $var = '', $order = '', $program = '', $text = '', $extra='', $build_an_href = True)
+		{
+			if(is_array($sort))
 		{
-			list($filter,$qfield,$start) = $this->get_var();
+				$temp_format	= $sort['sort'];
+				$var			= (isset($sort['var'])?$sort['var']:'');
+				$order			= (isset($sort['order'])?$sort['order']:'');
+				$program		= (isset($sort['program'])?$sort['program']:'/index.php');
+				$text			= (isset($sort['text'])?$sort['text']:'xslt');
+				$extra			= (isset($sort['extra'])?$sort['extra']:'');
+				$build_an_href	= (isset($sort['build_an_href'])?$sort['build_an_href']:True);
+				settype($sort,'string');
+				$sort			= $temp_format;
+				unset($temp_format);
+			}
+
+			list($filter,$qfield,$start,$NULL1,$NULL) = $this->get_var();
 
-			if (($order == $var) && ($sort == 'ASC'))
+			if(($order == $var) && ($sort == 'ASC'))
 			{
 				$sort = 'DESC';
 			}
-			elseif (($order == $var) && ($sort == 'DESC'))
+			elseif(($order == $var) && ($sort == 'DESC'))
 			{
 				$sort = 'ASC';
 			}
@@ -728,7 +749,7 @@
 				$sort = 'ASC';
 			}
 
-			if (is_array($extra))
+			if(is_array($extra))
 			{
 				$extra = $this->extras_to_string($extra);
 			}
@@ -737,7 +758,11 @@
 
 			$link = ($this->action?$this->page($extravar):$GLOBALS['phpgw']->link($program,$extravar));
 
-			if ($build_a_href)
+			if ($text == 'xslt')
+			{
+				return $link;
+			}
+			elseif($build_an_href)
 			{
 				return '<a href="' . $link . '">' . $text . '</a>';
 			}
@@ -816,7 +841,7 @@
 		/*!
 		@function nav_left_right_imap
 		@abstract same code as left and right (as of Dec 07, 2001) except all combined into one function
-		@param feed_vars : array with these elements: <br />
+		@param feed_vars : array with these elements: <br>
 			start 
 			total 
 			cmd_prefix 
@@ -848,11 +873,11 @@
 				($feed_vars['start'] > $this->maxmatches))
 			{
 				$out_vars['start'] = 0;
-				$return_array['first_page'] = $this->set_link_imap('left','first.gif',lang('First page'),$out_vars);
+				$return_array['first_page'] = $this->set_link_imap('left','first',lang('First page'),$out_vars);
 			}
 			else
 			{
-				$return_array['first_page'] = $this->set_icon_imap('left','first-grey.gif',lang('First page'));
+				$return_array['first_page'] = $this->set_icon_imap('left','first-grey',lang('First page'));
 			}
 			// previous page
 			if($feed_vars['start'] != 0)
@@ -866,11 +891,11 @@
 				{
 					$out_vars['start'] = ($feed_vars['start'] - $this->maxmatches);
 				}
-				$return_array['prev_page'] = $this->set_link_imap('left','left.gif',lang('Previous page'),$out_vars);
+				$return_array['prev_page'] = $this->set_link_imap('left','left',lang('Previous page'),$out_vars);
 			}
 			else
 			{
-				$return_array['prev_page'] = $this->set_icon_imap('left','left-grey.gif',lang('Previous page'));
+				$return_array['prev_page'] = $this->set_icon_imap('left','left-grey',lang('Previous page'));
 			}
 
 			// re-initialize the out_vars
@@ -881,22 +906,22 @@
 				($feed_vars['total'] > $feed_vars['start'] + $this->maxmatches))
 			{
 				$out_vars['start'] = ($feed_vars['start'] + $this->maxmatches);
-				$return_array['next_page'] = $this->set_link_imap('right','right.gif',lang('Next page'),$out_vars);
+				$return_array['next_page'] = $this->set_link_imap('right','right',lang('Next page'),$out_vars);
 			}
 			else
 			{
-				$return_array['next_page'] = $this->set_icon_imap('right','right-grey.gif',lang('Next page'));
+				$return_array['next_page'] = $this->set_icon_imap('right','right-grey',lang('Next page'));
 			}
 			// last page
 			if(($feed_vars['start'] != $feed_vars['total'] - $this->maxmatches) &&
 				(($feed_vars['total'] - $this->maxmatches) > ($feed_vars['start'] + $this->maxmatches)))
 			{
 				$out_vars['start'] = ($feed_vars['total'] - $this->maxmatches);
-				$return_array['last_page'] = $this->set_link_imap('right','last.gif',lang('Last page'),$out_vars);
+				$return_array['last_page'] = $this->set_link_imap('right','last',lang('Last page'),$out_vars);
 			}
 			else
 			{
-				$return_array['last_page'] = $this->set_icon_imap('right','last-grey.gif',lang('Last page'));
+				$return_array['last_page'] = $this->set_icon_imap('right','last-grey',lang('Last page'));
 			}
 			return $return_array;
 		}
@@ -921,5 +946,6 @@
 			$img_full = $GLOBALS['phpgw']->common->image('phpgwapi',$img);
 			return '<img src="'.$img_full.'" border="0" width="12" height="12" alt="'.$alt_text.'">'."\r\n";
 		}
+
 	} // End of nextmatchs class
 ?>
diff -aburN --exclude='CVS*' phpgwapi.org/inc/class.nextmatchs_xslt.inc.php phpgwapi/inc/class.nextmatchs_xslt.inc.php
--- phpgwapi.org/inc/class.nextmatchs_xslt.inc.php	1970-01-01 01:00:00.000000000 +0100
+++ phpgwapi/inc/class.nextmatchs_xslt.inc.php	2006-01-12 11:35:18.000000000 +0100
@@ -0,0 +1,138 @@
+<?php
+	/**
+	* Handles xslt nm widgets
+	* @author Bettina Gille <ceb@phpgroupware.org>
+	* @copyright Copyright (C) 2005 Free Software Foundation, Inc. http://www.fsf.org/
+	* @license http://www.fsf.org/licenses/gpl.html GNU General Public License
+	* @package phpgwapi
+	* @subpackage gui
+	* @version $Id: class.nextmatchs_xslt.inc.php,v 1.2 2005/04/26 09:43:08 powerstat Exp $
+	*/
+
+	/**
+	* XSLT nextmatch
+	*
+	* @package phpgwapi
+	* @subpackage gui
+	*/
+	class nextmatchs_xslt
+	{
+		var $maxmatches;
+		var $action;
+		var $template;
+
+		function nextmatchs_xslt()
+		{
+
+		}
+
+		function xslt_filter($data=0)
+		{
+			$GLOBALS['phpgw']->xslttpl->add_file($GLOBALS['phpgw']->common->get_tpl_dir('phpgwapi','default') . SEP . 'filter_select');
+
+			if(is_array($data))
+			{
+				$filter		= (isset($data['filter'])?$data['filter']:'');
+				$format		= (isset($data['format'])?$data['format']:'all');
+				$link_data	= (isset($data['link_data'])?$data['link_data']:'');
+			}
+			else
+			{
+				//$filter = get_var('filter',Array('GET','POST'));
+				//$filter = $data;
+				//$format	= 'all';
+				return False;
+			}
+
+			switch($format)
+			{
+				case 'yours':
+					$filter_obj = array
+					(
+						array('key' => 'none','lang' => lang('show all')),
+						array('key' => 'yours','lang' => lang('only yours'))
+					);
+					break;
+				case 'private':
+					$filter_obj = array
+					(
+						array('key' => 'none','lang' => lang('show all')),
+						array('key' => 'private','lang' => lang('only private'))
+					);
+					break;
+				default:
+					$filter_obj = array
+					(
+						array('key' => 'none','lang' => lang('show all')),
+						array('key' => 'yours','lang' => lang('only yours')),
+						array('key' => 'private','lang' => lang('only private'))
+					);
+			}
+
+			for($i=0;$i<count($filter_obj);$i++)
+			{
+				if($filter_obj[$i]['key'] == $filter)
+				{
+					$filter_obj[$i]['selected'] = 'yes';
+				}
+			}
+
+			$filter_data = array
+			(
+				'filter_list'				=> $filter_obj,
+				'lang_filter_statustext'	=> lang('Select the filter. To show all entries select SHOW ALL'),
+				'lang_submit'				=> lang('submit'),
+				'select_url'				=> $GLOBALS['phpgw']->link('/index.php',$link_data)
+			);
+			return $filter_data;
+		}
+
+		function xslt_search($values=0)
+		{
+			$GLOBALS['phpgw']->xslttpl->add_file($GLOBALS['phpgw']->common->get_tpl_dir('phpgwapi','default') . SEP . 'search_field');
+
+			$search_data = array
+			(
+				'lang_searchfield_statustext'	=> lang('Enter the search string. To show all entries, empty this field and press the SUBMIT button again'),
+				'lang_searchbutton_statustext'	=> lang('Submit the search string'),
+				'query'							=> $values['query'],
+				'lang_search'					=> lang('search'),
+				'select_url'					=> $GLOBALS['phpgw']->link('/index.php',$values['link_data'])
+			);
+			return $search_data;
+		}
+
+		function xslt_nm($values = 0)
+		{
+			$GLOBALS['phpgw']->xslttpl->add_file($GLOBALS['phpgw']->common->get_tpl_dir('phpgwapi','default') . SEP . 'nextmatchs');
+
+			$nm_data = array
+			(
+				'img_width'			=> ($GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']=='funkwerk'?'':'12'),
+				'img_height'		=> ($GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']=='funkwerk'?'':'12'),
+				'allow_all_rows'	=> (isset($values['allow_all_rows'])?False:'yes'),
+				'start_record'		=> intval($values['start']),
+				'record_limit'		=> $this->maxmatches,
+				'num_records'		=> intval($values['num_records']),
+				'all_records'		=> intval($values['all_records']),
+				'nextmatchs_url'	=> $GLOBALS['phpgw']->link('/index.php',$values['link_data']),
+				'first_img'			=> $GLOBALS['phpgw']->common->image('phpgwapi','first'),
+				'first_grey_img'	=> $GLOBALS['phpgw']->common->image('phpgwapi','first-grey'),
+				'left_img'			=> $GLOBALS['phpgw']->common->image('phpgwapi','left'),
+				'left_grey_img'		=> $GLOBALS['phpgw']->common->image('phpgwapi','left-grey'),
+				'right_img'			=> $GLOBALS['phpgw']->common->image('phpgwapi','right'),
+				'right_grey_img'	=> $GLOBALS['phpgw']->common->image('phpgwapi','right-grey'),
+				'last_img'			=> $GLOBALS['phpgw']->common->image('phpgwapi','last'),
+				'last_grey_img'		=> $GLOBALS['phpgw']->common->image('phpgwapi','last-grey'),
+				'all_img'			=> $GLOBALS['phpgw']->common->image('phpgwapi','down_nm'),
+				'title_first'		=> lang('first page'),
+				'title_previous'	=> lang('previous page'),
+				'title_next'		=> lang('next page'),
+				'title_last'		=> lang('last page'),
+				'title_all'			=> lang('show all'),
+				'lang_showing'		=> $this->show_hits(intval($values['all_records']),intval($values['start']))
+			);
+			return $nm_data;
+		}
+	}
+?>
diff -aburN --exclude='CVS*' phpgwapi.org/inc/class.xmltool.inc.php phpgwapi/inc/class.xmltool.inc.php
--- phpgwapi.org/inc/class.xmltool.inc.php	1970-01-01 01:00:00.000000000 +0100
+++ phpgwapi/inc/class.xmltool.inc.php	2006-01-12 11:35:18.000000000 +0100
@@ -0,0 +1,636 @@
+<?php
+	/**
+	* XML tools
+	* @author Bettina Gille [ceb@phpgroupware.org]
+	* @author Dan Kuykendall <seek3r@phpgroupware.org>
+	* @author Ralf Becker <ralfbecker@outdoortraining.de>
+	* @copyright Copyright (C) 2002-2005 Free Software Foundation, Inc. http://www.fsf.org/
+	* @license http://www.gnu.org/licenses/gpl.html GNU General Public License
+	* @package phpgwapi
+	* @subpackage xml
+	* @version $Id: class.xmltool.inc.php,v 1.11 2005/04/26 09:43:08 powerstat Exp $
+	* @internal This class based on boGraph.php3 - Double Choco Latte - Source Configuration Management System Copyright (C) 1999  Michael L. Dean & Tim R. Norman
+	*/
+
+
+	/**
+	* Convert variable to XML
+	*
+	* @param string $name
+	* @param string $data
+	* @return string XML string
+	*/
+	function var2xml($name, $data)
+	{
+		$doc = new xmltool('root','','');
+		return $doc->import_var($name,$data,True,True);
+	}
+
+
+	/**
+	* XML tools
+	*
+	* @package phpgwapi
+	* @subpackage xml
+	*/
+	class xmltool
+	{
+		/* for root nodes */
+		var $xmlversion = '1.0';
+		var $doctype = Array();
+		/* shared */
+		var $node_type = '';
+		var $name = '';
+		var $data_type;
+		var $data;
+		/* for nodes */
+		var $attributes = Array();
+		var $comments = Array();
+		var $indentstring = "\t";
+		
+		/* start the class as either a root or a node */
+		function xmltool ($node_type = 'root', $name='',$indentstring="\t")
+		{
+			$this->node_type = $node_type;
+			$this->indentstring = $indentstring;
+			if ($this->node_type == 'node')
+			{
+				if($name !== '')
+				{
+					$this->name = $name;
+				}
+				else
+				{
+					echo 'You must name node type objects<br>';
+					exit;
+				}
+			}
+		}
+		
+		function set_version ($version = '1.0')
+		{
+			$this->xmlversion = $version;
+			return True;
+		}
+
+		function set_doctype ($name, $uri = '')
+		{
+			if ($this->node_type == 'root')
+			{
+				$this->doctype[$name] = $uri;
+				return True;
+			}
+			else
+			{
+				return False;
+			}
+		}
+
+		function add_node ($node_object, $name = '')
+		{
+			switch ($this->node_type)
+			{
+				case 'root':
+					if (is_object($node_object))
+					{
+						$this->data = $node_object;
+					}
+					else
+					{
+						$this->data = $this->import_var($name, $node_object);
+					}
+					break;
+				case 'node':
+					if(!is_array($this->data))
+					{
+						$this->data = Array();
+						$this->data_type = 'node';
+					}
+					if (is_object($node_object))
+					{
+						if ($name != '')
+						{
+							$this->data[$name] = $node_object;
+						}
+						else
+						{
+							$this->data[] = $node_object;
+						}
+					}
+					else
+					{
+						$this->data[$name] = $this->import_var($name, $node_object);
+					}
+					return True;
+					break;
+			}
+		}
+
+		function get_node ($name = '')	// what is that function doing: NOTHING !!!
+		{
+			switch	($this->data_type)
+			{
+				case 'root':
+					break;
+				case 'node':
+					break;
+				case 'object':
+					break;
+			}
+		
+		}
+
+		function set_value ($string)
+		{
+			$this->data = $string;
+			$this->data_type = 'value';
+			return True;
+		}
+		
+		function get_value ()
+		{
+			if($this->data_type == 'value')
+			{
+				return $this->data;
+			}
+			else
+			{
+				return False;
+			}
+		}
+
+		function set_attribute ($name, $value = '')
+		{
+			$this->attributes[$name] = $value;
+			return True;
+		}
+
+		function get_attribute ($name)
+		{
+			return $this->attributes[$name];
+		}
+
+		function get_attributes ()
+		{
+			return $this->attributes;
+		}
+
+		function add_comment ($comment)
+		{
+			$this->comments[] = $comment;
+			return True;
+		}
+
+		function import_var($name, $value,$is_root=False,$export_xml=False)
+		{
+			//echo "<p>import_var: this->indentstring='$this->indentstring'</p>\n";
+			$node = new xmltool('node',$name,$this->indentstring);
+			switch (gettype($value))
+			{
+				case 'string':
+				case 'integer':
+				case 'double':
+				case 'NULL':
+					$node->set_value($value);
+					break;
+				case 'boolean':
+					if($value == True)
+					{
+						$node->set_value('1');
+					}
+					else
+					{
+						$node->set_value('0');
+					}
+					break;
+				case 'array':
+					$new_index = False;
+					while (list ($idxkey, $idxval) = each ($value))
+					{
+						if(is_array($idxval))
+						{
+							while (list ($k, $i) = each ($idxval))
+							{
+								if (is_int($k))
+								{
+									$new_index = True;
+								}
+							}
+						}
+					}
+					reset($value);
+					while (list ($key, $val) = each ($value))
+					{
+						if($new_index)
+						{
+							$keyname = $name;
+							$nextkey = $key;
+						}
+						else
+						{
+							$keyname = $key;
+							$nextkey = $key;
+						}
+						switch (gettype($val))
+						{
+							case 'string':
+							case 'integer':
+							case 'double':
+							case 'NULL':
+								$subnode = new xmltool('node', $nextkey,$this->indentstring);
+								$subnode->set_value($val);
+								$node->add_node($subnode);
+								break;
+							case 'boolean':
+								$subnode = new xmltool('node', $nextkey,$this->indentstring);
+								if($val == True)
+								{
+									$subnode->set_value('1');
+								}
+								else
+								{
+									$subnode->set_value('0');
+								}
+								$node->add_node($subnode);
+								break;
+							case 'array':
+								list($first_key) = each($val); reset($val);
+								if($new_index && is_int($first_key))
+								{
+									while (list ($subkey, $subval) = each ($val))
+									{
+										$node->add_node($this->import_var($nextkey, $subval));
+									}
+								}
+								else
+								{
+									$subnode = $this->import_var($nextkey, $val);
+									$node->add_node($subnode);
+								}
+								break;
+							case 'object':
+								$subnode = new xmltool('node', $nextkey,$this->indentstring);
+								$subnode->set_value('PHP_SERIALIZED_OBJECT&:'.serialize($val));
+								$node->add_node($subnode);
+								break;
+							case 'resource':
+								echo 'Halt: Cannot package PHP resource pointers into XML<br>';
+								exit;
+							default:
+								echo 'Halt: Invalid or unknown data type<br>';
+								exit;
+						}
+
+					}
+					break;
+				case 'object':
+					$node->set_value('PHP_SERIALIZED_OBJECT&:'.serialize($value));
+					break;
+				case 'resource':
+					echo 'Halt: Cannot package PHP resource pointers into XML<br>';
+					exit;
+				default:
+					echo 'Halt: Invalid or unknown data type<br>';
+					exit;
+			}
+	
+			if($is_root)
+			{
+				$this->add_node($node);
+				if($export_xml)
+				{
+					$xml = $this->export_xml();
+					return $xml;
+				}
+				else
+				{
+					return True;
+				}
+			}
+			else
+			{
+				$this->add_node($node);
+				return $node;
+			}
+		}
+
+		function export_var()
+		{
+			if($this->node_type == 'root')
+			{
+				return $this->data->export_var();
+			}
+
+			if($this->data_type != 'node')
+			{	
+				$found_at = strstr($this->data,'PHP_SERIALIZED_OBJECT&:');
+				if($found_at != False)
+				{
+					return unserialize(str_replace ('PHP_SERIALIZED_OBJECT&:', '', $this->data));
+				}
+				return $this->data;
+			}
+			else
+			{
+				$new_index = False;
+				reset($this->data);
+				while(list($key,$val) = each($this->data))
+				{
+					if(!isset($found_keys[$val->name]))
+					{
+						$found_keys[$val->name] = True;
+					}
+					else
+					{
+						$new_index = True;
+					}
+				}
+
+				if($new_index)
+				{
+					reset($this->data);
+					while(list($key,$val) = each($this->data))
+					{
+
+						$return_array[$val->name][] = $val->export_var();
+					}				
+				}
+				else
+				{
+					reset($this->data);
+					while(list($key,$val) = each($this->data))
+					{
+						$return_array[$val->name] = $val->export_var();
+					}
+				}
+				return $return_array;
+			}
+		}
+
+		function export_struct()
+		{
+			if($this->node_type == 'root')
+			{
+				return $this->data->export_struct();
+			}
+
+			$retval['tag'] = $this->name;
+			$retval['attributes'] = $this->attributes;
+			if($this->data_type != 'node')
+			{	
+				$found_at = strstr($this->data,'PHP_SERIALIZED_OBJECT&:');
+				if($found_at != False)
+				{
+					$retval['value'] = unserialize(str_replace ('PHP_SERIALIZED_OBJECT&:', '', $this->data));
+				}
+				else
+				{
+					$retval['value'] = $this->data;
+				}
+				return $retval;
+			}
+			else
+			{
+				reset($this->data);
+				while(list($key,$val) = each($this->data))
+				{
+					$retval['children'][] = $val->export_struct();
+				}				
+				return $retval;
+			}
+		}
+
+		
+		function import_xml_children($data, &$i, $parent_node)
+		{
+			while (++$i < count($data))
+			{
+				switch ($data[$i]['type'])
+				{
+					case 'cdata':
+					case 'complete':
+						$node = new xmltool('node',$data[$i]['tag'],$this->indentstring);
+						if(is_array($data[$i]['attributes']) && count($data[$i]['attributes']) > 0)
+						{
+							while(list($k,$v)=each($data[$i]['attributes']))
+							{
+								$node->set_attribute($k,$v);
+							}
+						}
+						$node->set_value($data[$i]['value']);
+						$parent_node->add_node($node);
+						break;
+					case 'open':
+						$node = new xmltool('node',$data[$i]['tag'],$this->indentstring);
+						if(is_array($data[$i]['attributes']) && count($data[$i]['attributes']) > 0)
+						{
+							while(list($k,$v)=each($data[$i]['attributes']))
+							{
+								$node->set_attribute($k,$v);
+							}
+						}
+						
+						$node = $this->import_xml_children($data, $i, $node);
+						$parent_node->add_node($node);
+						break;
+					case 'close':
+						return $parent_node;
+				}
+			}
+		}
+		
+		function import_xml($xmldata) 
+		{
+			$parser = xml_parser_create();
+			xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+			xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE,   1);
+			xml_parse_into_struct($parser, $xmldata, $vals, $index);
+			xml_parser_free($parser);
+			unset($index);	
+			$node = new xmltool('node',$vals[0]['tag'],$this->indentstring);
+			if(isset($vals[0]['attributes']))
+			{
+				while(list($key,$value) = each($vals[0]['attributes']))
+				{
+					$node->set_attribute($key, $value);
+				}
+			}
+			switch ($vals[0]['type'])
+			{
+				case 'complete':
+					$node->set_value($vals[0]['value']);
+					break;
+				case 'cdata':
+					$node->set_value($vals[0]['value']);
+					break;
+				case 'open':
+					$node = $this->import_xml_children($vals, $i = 0, $node);
+					break;
+				case 'closed':
+					exit;
+			}
+			$this->add_node($node);
+		}
+
+		function export_xml($indent = 1)
+		{
+			if ($this->node_type == 'root')
+			{
+				$result = '<?xml version="'.$this->xmlversion.'" encoding="' . lang('charset') . '"?>'."\n";
+				if(count($this->doctype) == 1)
+				{
+					list($doctype_name,$doctype_uri) = each($this->doctype);
+					$result .= '<!DOCTYPE '.$doctype_name.' SYSTEM "'.$doctype_uri.'">'."\n";
+				}
+				if(count($this->comments) > 0 )
+				{
+					//reset($this->comments);
+					while(list($key,$val) = each ($this->comments))
+					{
+						$result .= "<!-- $val -->\n";
+					}
+				}
+				if(is_object($this->data))
+				{
+					$indent = 0;
+					$result .= $this->data->export_xml($indent);
+				}
+				return $result;
+			}
+			else /* For node objects */
+			{
+				for ($i = 0; $i < $indent; $i++)
+				{
+					$indentstring .= $this->indentstring;
+				}
+
+				$result = $indentstring.'<'.$this->name;
+				if(count($this->attributes) > 0 )
+				{
+					reset($this->attributes);
+					while(list($key,$val) = each ($this->attributes))
+					{
+						$result .= ' '.$key.'="'.htmlspecialchars($val).'"';
+					}
+				}
+
+				$endtag_indent = $indentstring;
+				if (empty($this->data_type))
+				{
+					$result .= '/>'."\n";
+				}
+				else
+				{
+					$result .= '>';
+
+					switch ($this->data_type)
+					{
+						case 'value':
+							if(is_array($this->data))
+							{
+								$type_error = True;
+								break;
+							}
+							
+							/*if(preg_match("(&|<)", $this->data))	// this is unnecessary with htmlspecialchars($this->data)
+							{
+								$result .= '<![CDATA['.$this->data.']]>';
+								$endtag_indent = '';		
+							}
+							else*/if(strlen($this->data) > 30 && !empty($this->indentstring))
+							{
+								$result .= "\n".$indentstring.$this->indentstring.htmlspecialchars($this->data)."\n";
+								$endtag_indent = $indentstring;
+							}
+							else
+							{
+								$result .= htmlspecialchars($this->data);
+								$endtag_indent = '';
+							}
+							break;
+						case 'node':
+							$result .= "\n";
+							if(!is_array($this->data))
+							{
+								$type_error = True;
+								break;
+							}
+				
+							$subindent = $indent+1;
+							reset($this->data);
+							while(list($key,$val) = each ($this->data))
+							{
+								if(is_object($val))
+								{
+									$result .= $val->export_xml($subindent);
+								}
+							}
+							break;
+						default:
+						if($this->data != '')
+						{
+							echo 'Invalid or unset data type ('.$this->data_type.'). This should not be possible if using the class as intended<br>';
+						}
+					}
+
+					if ($type_error)
+					{
+						echo 'Invalid data type. Tagged as '.$this->data_type.' but data is '.gettype($this->data).'<br>';
+					}
+
+					$result .= $endtag_indent.'</'.$this->name.'>';
+					if($indent != 0)
+					{
+						$result .= "\n";
+					}
+				}
+				if(count($this->comments) > 0 )
+				{
+					reset($this->comments);
+					while(list($key,$val) = each ($this->comments))
+					{
+						$result .= $endtag_indent."<!-- $val -->\n";
+					}
+				}
+				return $result;
+			}
+		}
+	}
+
+
+	/**
+	* XML node
+	*
+	* @package phpgwapi
+	* @subpackage xml
+	*/
+	class xmlnode extends xmltool
+	{
+		function xmlnode($name)
+		{
+			$this->xmltool('node',$name);
+		}
+	}
+
+
+	/**
+	* XML doc
+	*
+	* @package phpgwapi
+	* @subpackage xml
+	*/
+	class xmldoc extends xmltool
+	{
+		function xmldoc($version = '1.0')
+		{
+			$this->xmltool('root');
+			$this->set_version($version);
+		}
+
+		function add_root($root_node)
+		{
+			return $this->add_node($root_node);
+		}
+	}
+
+?>
diff -aburN --exclude='CVS*' phpgwapi.org/inc/class.xslttemplates.inc.php phpgwapi/inc/class.xslttemplates.inc.php
--- phpgwapi.org/inc/class.xslttemplates.inc.php	1970-01-01 01:00:00.000000000 +0100
+++ phpgwapi/inc/class.xslttemplates.inc.php	2006-01-12 11:37:51.000000000 +0100
@@ -0,0 +1,332 @@
+<?php
+	/**
+	* XSLT Template class
+	* @author Dan Kuykendall <seek3r@phpgroupware.org>
+	* @author Bettina Gille [ceb@phpgroupware.org]
+	* @author Ralf Becker <ralfbecker@outdoor-training.de>
+	* @copyright Copyright (C) 2002-2005 Free Software Foundation, Inc. http://www.fsf.org/
+	* @license http://www.gnu.org/licenses/lpl.html GNU General Public License
+	* @package phpgwapi
+	* @subpackage gui
+	* @version $Id: class.xslttemplates.inc.php,v 1.20 2005/04/26 09:43:08 powerstat Exp $
+	*/
+
+	if(!extension_loaded('xslt') && !extension_loaded('xsl'))
+	{
+
+		echo 'PHP CONFIGURATION. xslt-extension is not loaded. Please contact the system administrator.';
+		exit();
+	}
+
+
+	/**
+	* Include xml tool
+	*/
+	require_once('class.xmltool.inc.php');
+
+
+	/**
+	* XSLT template engine
+	*
+	* @package phpgwapi
+	* @subpackage gui
+	*/
+	class xslttemplates
+	{
+		var $rootdir = '';
+		var $prev_rootdir = '';
+
+		/**
+		* The xslfiles will be loaded up and merged into $xsldata
+		* @var array XSL files to load
+		*/
+		var $xslfiles = Array();
+		var	$xsldata = '';
+
+		/**
+		* Users can set $vars which will be converted into xmldata before xsl processing.
+		* Or they can generate their own XML data and set it directly when they have
+		* need for a more robust schema.
+		* @var array Variables to convert into xml-data
+		*/
+		var $vars = Array();
+		var $xmlvars = Array();
+		var $xmldata = '';
+
+		function xslttemplates($root = '.')
+		{
+			if(@isset($GLOBALS['phpgw_info']['flags']['printview']) && $GLOBALS['phpgw_info']['flags']['printview'] == True)
+			{
+				$this->print = True;
+			}
+			$this->set_root($root);
+
+		}
+
+		function halt($msg)
+		{
+			echo $msg;
+			exit;
+		}
+
+		function set_root($rootdir)
+		{
+			if (!is_dir($rootdir))
+			{
+				$this->halt('set_root: '.$rootdir.' is not a directory.');
+				return False;
+			}
+			$this->prev_rootdir = $this->rootdir;
+			$this->rootdir = $rootdir;
+			return True;
+		}
+
+		function reset_root()
+		{
+			$this->rootdir = $this->prev_rootdir;
+		}
+
+		function add_file($filename,$rootdir='',$time=1)
+		{
+			if (!is_array($filename))
+			{
+				if($rootdir=='')
+				{
+					$rootdir=$this->rootdir;
+				}
+
+				if (substr($filename, 0, 1) != SEP && substr($filename, 1, 1) != ':')
+				{
+					$new_filename = $rootdir . SEP . $filename;
+				}
+				else
+				{
+					$new_filename = $filename;
+				}
+
+				if ($this->print && $time!=2 && $time!=4)
+				{
+					$new_filename = $new_filename.'_print';
+				}
+
+//				echo 'Rootdir: '.$rootdir.'<br>'."\n".'Filename: '.$filename.'<br>'."\n".'New Filename: '.$new_filename.'<br>'."\n";
+				if (!file_exists($new_filename.'.xsl'))
+				{
+					switch($time)
+					{
+						case 2:
+							$new_root = str_replace($GLOBALS['phpgw_info']['server']['template_set'],'base',$rootdir);
+							$this->add_file($filename,$new_root,3);
+							return;
+							break;
+						case 3:
+							$this->add_file($filename,$rootdir,4);
+							return;
+							break;
+						case 4:
+							$this->halt("filename: file $new_filename.xsl does not exist.");
+							break;
+						default:
+							if (!$this->print)
+							{
+								$new_root = str_replace($GLOBALS['phpgw_info']['server']['template_set'],'base',$rootdir);
+								$this->add_file($filename,$new_root,4);
+								return;
+							}
+							else
+							{
+								$this->add_file($filename,$rootdir,2);
+								return;
+							}
+					}
+				}
+				else
+				{
+					$this->xslfiles[$filename] = $new_filename.'.xsl';
+				}
+			}
+			else
+			{
+				reset($filename);
+				while(list(,$file) = each($filename))
+				{
+					$this->add_file($file);
+				}
+			}
+		}
+
+		function set_var($name, $value, $append = False)
+		{
+			if($append)
+			{
+				if (is_array($value))
+				{
+					while(list($key,$val) = each($value))
+					{
+
+						if (is_array($val) && is_array($this->vars[$name][$key]))
+						{
+							$this->vars[$name][$key] = array_merge($this->vars[$name][$key],$val);
+						}
+						else
+						{
+							$this->vars[$name][$key] .= $val;
+						}
+					}
+				}
+			}
+			else
+			{
+				$this->vars[$name] = $value;
+			}
+		}
+
+		function set_xml($xml, $append = False)
+		{
+			if(!$append)
+			{
+				$this->xmlvars = $xml;
+			}
+			else
+			{
+				$this->xmlvars .= $xml;
+			}
+		}
+
+		function get_var($name)
+		{
+			return $this->vars[$name];
+		}
+
+		function get_vars()
+		{
+			return $this->vars;
+		}
+
+		function get_xml()
+		{
+			return $this->xmlvars;
+		}
+
+		function xsl_parse()
+		{
+			if(count($this->xslfiles) > 0)
+			{
+				$this->xsldata = '<?xml version="1.0" encoding="' . lang('charset') . '"?>'."\n";
+				$this->xsldata .= '<!DOCTYPE xsl:stylesheet ['."\n";
+				$this->xsldata .= '<!ENTITY nl "&#10;">'."\n";
+				$this->xsldata .= '<!ENTITY nbsp "&#160;">'."\n";
+				$this->xsldata .= ']>'."\n";
+				$this->xsldata .= '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">'."\n";
+				$this->xsldata .= '<xsl:output method="html" version="1.0" encoding="' . lang('charset') . '" indent="yes" omit-xml-declaration="yes" doctype-public="-//W3C/DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" standalone="yes" media-type="text/html"/>'."\n";
+				$this->xsldata .= '<xsl:template match="/">'."\n";
+				$this->xsldata .= "\t".'<xsl:apply-templates select="PHPGW"/>'."\n";
+				$this->xsldata .= '</xsl:template>'."\n";
+				reset($this->xslfiles);
+				while(list($dummy,$xslfile) = each($this->xslfiles))
+				{
+//					echo 'XSLFILES: '.$dummy.'<br>'."\n".'XSL File: '.$xslfile.'<br>'."\n";
+					$fd = fopen ($xslfile, "r");
+					$this->xsldata .= fread($fd, filesize($xslfile));
+					fclose ($fd);
+				}
+				$this->xsldata .= '</xsl:stylesheet>'."\n";
+			}
+			else
+			{
+				echo 'Error: No XSL files have been selected';
+				exit;
+			}
+			return $this->xsldata;
+		}
+
+		function xml_parse()
+		{
+			$this->xmldata = '';
+			$xmlvars = $this->xmlvars;
+
+			$xmldata = $this->vars;
+
+			/* auto generate xml based on vars */
+
+			while(list($key,$value) = each($xmlvars))
+			{
+				$xmldata[$key] = $value;
+			}
+			$this->xmldata = var2xml('PHPGW',$xmldata);
+			return $this->xmldata;
+		}
+
+		function list_lineno($xml)
+		{
+			$xml = explode("\n",$xml);
+
+			echo "<pre>\n";
+			for ($n=1; isset($xml[$n]); ++$n)
+			{
+				echo "$n: ".htmlentities($xml[$n])."\n";
+			}
+			echo "</pre>\n";
+		}
+
+		function parse($parsexsl = True, $parsexml = True)
+		{
+			$GLOBALS['phpgw']->common->phpgw_header($GLOBALS['phpgw_info']['flags']['noframework']?False:True);
+
+			if($parsexsl)
+			{
+				$this->xsl_parse();
+			}
+			if($parsexml)
+			{
+				$this->xml_parse();
+			}
+
+			$minor = explode(".",phpversion());
+
+			if ($minor[0] == 5)
+			{
+				$xml = new DOMDocument;
+				$xml->loadXML($this->xmldata);
+
+				$xsl = new DOMDocument;
+				$xsl->loadXML($this->xsldata);
+
+				// Configure the transformer
+				$proc = new XSLTProcessor;
+				$proc->importStyleSheet($xsl); // attach the xsl rules
+
+				$html =  $proc->transformToXML($xml);
+			}			
+			else
+			{
+				$xsltproc = xslt_create();
+				$arguments = array('/_xml' => $this->xmldata, '/_xsl' => $this->xsldata);
+				$html = xslt_process($xsltproc,'arg:/_xml','arg:/_xsl',NULL,$arguments);
+				xslt_free($xsltproc);
+			}
+
+			if (!$html)
+			{
+				echo "<p>xml-data = ";  $this->list_lineno($this->xmldata);
+				echo "<p>xsl-data = "; $this->list_lineno($this->xsldata);
+				if ($minor[0] == 4)
+				{
+					die(/*$this->xsldata.*/"\n\n XSLT processing error: ".xslt_error($xsltproc));
+				}
+			}
+
+			return $html;
+		}
+
+		function pparse()
+		{
+			print $this->parse();
+			return False;
+		}
+		function pp()
+		{
+			return $this->pparse();
+		}
+	}
+?>
diff -aburN --exclude='CVS*' phpgwapi.org/inc/functions.inc.php phpgwapi/inc/functions.inc.php
--- phpgwapi.org/inc/functions.inc.php	2006-01-12 11:35:04.000000000 +0100
+++ phpgwapi/inc/functions.inc.php	2006-01-12 11:35:18.000000000 +0100
@@ -369,6 +369,7 @@
 		if(!@$GLOBALS['phpgw_info']['flags']['disable_Template_class'])
 		{
 			$GLOBALS['phpgw']->template = CreateObject('phpgwapi.Template',PHPGW_APP_TPL);
+			$GLOBALS['phpgw']->xslttpl = CreateObject('phpgwapi.xslttemplates',PHPGW_APP_TPL);
 		}
 
 		/*************************************************************************\
diff -aburN --exclude='CVS*' phpgwapi.org/templates/default/categories.xsl phpgwapi/templates/default/categories.xsl
--- phpgwapi.org/templates/default/categories.xsl	1970-01-01 01:00:00.000000000 +0100
+++ phpgwapi/templates/default/categories.xsl	2006-01-12 11:35:18.000000000 +0100
@@ -0,0 +1,54 @@
+<!-- $Id: categories.xsl,v 1.3 2005/01/18 23:51:15 ceb Exp $ -->
+
+	<xsl:template name="categories">
+		<xsl:choose>
+			<xsl:when test="cat_filter != ''">
+				<xsl:apply-templates select="cat_filter"/>
+			</xsl:when>
+			<xsl:when test="cat_select != ''">
+				<xsl:apply-templates select="cat_select"/>
+			</xsl:when>
+		</xsl:choose>
+	</xsl:template>
+
+	<xsl:template match="cat_filter">
+		<xsl:variable name="select_url"><xsl:value-of select="select_url"/></xsl:variable>
+		<xsl:variable name="select_name"><xsl:value-of select="select_name"/></xsl:variable>
+		<xsl:variable name="lang_submit"><xsl:value-of select="lang_submit"/></xsl:variable>
+		<form method="post" action="{$select_url}">
+			<select name="{$select_name}" onChange="this.form.submit();" onMouseout="window.status='';return true;">
+				<xsl:attribute name="onMouseover">
+					<xsl:text>window.status='</xsl:text>
+						<xsl:value-of select="lang_cat_statustext"/>
+					<xsl:text>'; return true;</xsl:text>
+				</xsl:attribute>
+				<option value="none"><xsl:value-of select="lang_no_cat"/></option>
+					<xsl:apply-templates select="cat_list"/>
+			</select>
+			<noscript>
+				<xsl:text> </xsl:text>
+				<input type="submit" name="submit" value="{$lang_submit}"/>
+			</noscript>
+		</form>
+	</xsl:template>
+
+	<xsl:template match="cat_select">
+	<xsl:variable name="lang_cat_statustext"><xsl:value-of select="lang_cat_statustext"/></xsl:variable>
+	<xsl:variable name="select_name"><xsl:value-of select="select_name"/></xsl:variable>
+		<select name="{$select_name}" class="forms" onMouseover="window.status='{$lang_cat_statustext}'; return true;" onMouseout="window.status='';return true;">
+			<option value="none"><xsl:value-of select="lang_no_cat"/></option>
+				<xsl:apply-templates select="cat_list"/>
+		</select>
+	</xsl:template>
+
+	<xsl:template match="cat_list">
+	<xsl:variable name="cat_id"><xsl:value-of select="cat_id"/></xsl:variable>
+		<xsl:choose>
+			<xsl:when test="selected != ''">
+				<option value="{$cat_id}" selected="selected"><xsl:value-of disable-output-escaping="yes" select="name"/></option>
+			</xsl:when>
+			<xsl:otherwise>
+				<option value="{$cat_id}"><xsl:value-of disable-output-escaping="yes" select="name"/></option>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
diff -aburN --exclude='CVS*' phpgwapi.org/templates/default/filter_select.xsl phpgwapi/templates/default/filter_select.xsl
--- phpgwapi.org/templates/default/filter_select.xsl	1970-01-01 01:00:00.000000000 +0100
+++ phpgwapi/templates/default/filter_select.xsl	2006-01-12 11:35:18.000000000 +0100
@@ -0,0 +1,36 @@
+<!-- $Id: filter_select.xsl,v 1.3 2005/01/18 23:51:15 ceb Exp $ -->
+
+	<xsl:template name="filter_select">
+		<xsl:apply-templates select="filter_data"/>
+	</xsl:template>
+
+	<xsl:template match="filter_data">
+		<xsl:variable name="select_url"><xsl:value-of select="select_url"/></xsl:variable>
+		<xsl:variable name="lang_submit"><xsl:value-of select="lang_submit"/></xsl:variable>
+		<form method="post" action="{$select_url}">
+			<select name="filter" onChange="this.form.submit()" onMouseout="window.status='';return true;">
+				<xsl:attribute name="onMouseover">
+					<xsl:text>window.status='</xsl:text>
+						<xsl:value-of select="lang_filter_statustext"/>
+					<xsl:text>'; return true;</xsl:text>
+				</xsl:attribute>
+				<xsl:apply-templates select="filter_list"/>
+			</select>
+			<noscript>
+				<xsl:text> </xsl:text>
+				<input type="submit" class="forms" name="submit" value="{$lang_submit}"/> 
+			</noscript>
+		</form>
+	</xsl:template>
+
+	<xsl:template match="filter_list">
+	<xsl:variable name="key"><xsl:value-of select="key"/></xsl:variable>
+		<xsl:choose>
+			<xsl:when test="selected = 'yes'">
+				<option value="{$key}" selected="selected"><xsl:value-of select="lang"/></option>
+			</xsl:when>
+			<xsl:otherwise>
+				<option value="{$key}"><xsl:value-of select="lang"/></option>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
diff -aburN --exclude='CVS*' phpgwapi.org/templates/default/msgbox.xsl phpgwapi/templates/default/msgbox.xsl
--- phpgwapi.org/templates/default/msgbox.xsl	1970-01-01 01:00:00.000000000 +0100
+++ phpgwapi/templates/default/msgbox.xsl	2006-01-12 11:39:59.000000000 +0100
@@ -0,0 +1,28 @@
+<!-- $Id: msgbox.xsl,v 1.3 2005/01/18 23:51:15 ceb Exp $ -->
+
+	<xsl:template name="msgbox">
+		<xsl:apply-templates select="msgbox_data"/>
+	</xsl:template>
+
+	<xsl:template match="msgbox_data">
+		<table cellpadding="2" cellspacing="0" align="center" class="msgbox">
+			<tr>
+				<td align="center" valign="middle">
+					<xsl:choose>
+						<xsl:when test="msgbox_img != ''">
+						<xsl:variable name="msgbox_img"><xsl:value-of select="msgbox_img"/></xsl:variable>
+						<xsl:variable name="msgbox_img_alt"><xsl:value-of select="msgbox_img_alt"/></xsl:variable>
+							<img src="{$msgbox_img}" alt="{$msgbox_img_alt}" title="{$msgbox_img_alt}" onMouseout="window.status='';return true;">
+								<xsl:attribute name="onMouseover">
+									<xsl:text>window.status='</xsl:text>
+										<xsl:value-of select="lang_msgbox_statustext"/>
+									<xsl:text>'; return true;</xsl:text>
+								</xsl:attribute>
+							</img><xsl:text> </xsl:text>
+						</xsl:when>
+					</xsl:choose>
+					<xsl:value-of disable-output-escaping="yes" select="msgbox_text"/>
+				</td>
+			</tr>
+		</table>
+	</xsl:template>
diff -aburN --exclude='CVS*' phpgwapi.org/templates/default/nextmatchs.xsl phpgwapi/templates/default/nextmatchs.xsl
--- phpgwapi.org/templates/default/nextmatchs.xsl	1970-01-01 01:00:00.000000000 +0100
+++ phpgwapi/templates/default/nextmatchs.xsl	2006-01-12 11:35:18.000000000 +0100
@@ -0,0 +1,178 @@
+<!-- $Id: nextmatchs.xsl,v 1.3 2005/01/18 23:51:15 ceb Exp $ -->
+
+<xsl:template name="nextmatchs">
+	<xsl:choose>
+		<xsl:when test="nm_data != ''">
+			<xsl:apply-templates select="nm_data"/>
+		</xsl:when>
+	</xsl:choose>
+</xsl:template>
+
+<xsl:template match="nm_data">
+<!--	<xsl:param name="nextmatchs_params"/> -->
+	<xsl:variable name="allow_all_rows"><xsl:value-of select="allow_all_rows"/></xsl:variable>
+	<xsl:variable name="start_record"><xsl:value-of select="start_record"/></xsl:variable>
+	<xsl:variable name="cur_record"><xsl:value-of select="number($start_record) + number(1)"/></xsl:variable>
+	<xsl:variable name="record_limit"><xsl:value-of select="record_limit"/></xsl:variable>
+	<xsl:variable name="num_records"><xsl:value-of select="num_records"/></xsl:variable>
+	<xsl:variable name="all_records"><xsl:value-of select="all_records"/></xsl:variable>
+	<xsl:variable name="nextmatchs_url"><xsl:value-of select="nextmatchs_url"/></xsl:variable>
+	<xsl:variable name="first_img"><xsl:value-of select="first_img"/></xsl:variable>
+	<xsl:variable name="first_grey_img"><xsl:value-of select="first_grey_img"/></xsl:variable>
+	<xsl:variable name="left_img"><xsl:value-of select="left_img"/></xsl:variable>
+	<xsl:variable name="left_grey_img"><xsl:value-of select="left_grey_img"/></xsl:variable>
+	<xsl:variable name="right_img"><xsl:value-of select="right_img"/></xsl:variable>
+	<xsl:variable name="right_grey_img"><xsl:value-of select="right_grey_img"/></xsl:variable>
+	<xsl:variable name="last_img"><xsl:value-of select="last_img"/></xsl:variable>
+	<xsl:variable name="last_grey_img"><xsl:value-of select="last_grey_img"/></xsl:variable>
+	<xsl:variable name="all_img"><xsl:value-of select="all_img"/></xsl:variable>
+
+	<xsl:variable name="img_width"><xsl:value-of select="img_width"/></xsl:variable>
+	<xsl:variable name="img_height"><xsl:value-of select="img_height"/></xsl:variable>
+
+	<xsl:variable name="title_first"><xsl:value-of select="title_first"/></xsl:variable>
+	<xsl:variable name="title_previous"><xsl:value-of select="title_previous"/></xsl:variable>
+	<xsl:variable name="title_next"><xsl:value-of select="title_next"/></xsl:variable>
+	<xsl:variable name="title_last"><xsl:value-of select="title_last"/></xsl:variable>
+	<xsl:variable name="title_all"><xsl:value-of select="title_all"/></xsl:variable>
+
+	<table border="0" width="100%">
+		<tr>
+			<xsl:choose>
+				<xsl:when test="number($cur_record) > number(1)">
+				<xsl:variable name="first"><xsl:value-of select="nextmatchs_url"/>&amp;start=0</xsl:variable>
+					<td width="25">
+						<a href="{$first}"><img src="{$first_img}" border="0" width="{$img_width}" height="{$img_height}" alt="{$title_first}" title="{$title_first}"/></a>
+					</td>
+				</xsl:when>
+				<xsl:otherwise>
+					<td width="25">
+						<img src="{$first_grey_img}" border="0" width="{$img_width}" height="{$img_height}"/>
+					</td>
+				</xsl:otherwise>
+			</xsl:choose>
+
+			<xsl:choose>
+				<xsl:when test="number($cur_record) > number(1)">
+				<xsl:variable name="prev_num"><xsl:value-of select="number($cur_record) - number($record_limit)"/></xsl:variable>
+					<xsl:choose>
+						<xsl:when test="number($prev_num)+number(1) >= number(1)">
+							<xsl:choose>
+								<xsl:when test="number($cur_record) - number($record_limit) > number(0)">
+								<xsl:variable name="prev_number"><xsl:value-of select="number($cur_record) - number($record_limit)"/></xsl:variable>
+								<xsl:variable name="prev"><xsl:value-of select="nextmatchs_url"/>&amp;start=<xsl:value-of select="number($prev_number) - number(1)"/></xsl:variable>
+									<td width="25">
+										<a href="{$prev}"><img src="{$left_img}" border="0" width="{$img_width}" height="{$img_height}" alt="{$title_previous}" title="{$title_previous}"/></a>
+									</td>
+								</xsl:when>
+								<xsl:otherwise>
+								<xsl:variable name="prev"><xsl:value-of select="nextmatchs_url"/>&amp;start=0</xsl:variable>
+									<td width="25">
+										<a href="{$prev}"><img src="{$left_grey_img}" border="0" width="{$img_width}" height="{$img_height}"/></a>
+									</td>
+								</xsl:otherwise>
+							</xsl:choose>
+						</xsl:when>
+						<xsl:otherwise>
+							<td width="25">
+								<img src="{$left_grey_img}" border="0" width="{$img_width}" height="{$img_height}"/>
+							</td>
+						</xsl:otherwise>
+					</xsl:choose>
+				</xsl:when>
+				<xsl:otherwise>
+					<td width="25">
+						<img src="{$left_grey_img}" border="0" width="{$img_width}" height="{$img_height}"/>
+					</td>
+				</xsl:otherwise>
+			</xsl:choose>
+		
+			<!-- <xsl:choose>
+				<xsl:when test="number($num_records) = number(0)">
+					<td nowrap="nowrap" align="center">0 - 0 of 0&#160;</td>
+				</xsl:when>
+				<xsl:otherwise>
+					<xsl:choose>
+						<xsl:when test="number($cur_record) + number($record_limit) > number($num_records)">
+						<xsl:variable name="of_num"><xsl:value-of select="number($cur_record)+number($num_records) - number(1)"/></xsl:variable>
+							<td nowrap="nowrap" align="center">
+								<xsl:value-of select="$cur_record"/> - <xsl:value-of select="$of_num"/> of <xsl:value-of select="$all_records"/>&#160;
+							</td>
+						</xsl:when>
+						<xsl:otherwise>
+						<xsl:variable name="of_num"><xsl:value-of select="number($cur_record) + number($record_limit) - number(1)"/></xsl:variable>
+							<td nowrap="nowrap" align="center">
+								<xsl:value-of select="$cur_record"/> - <xsl:value-of select="$of_num"/> of <xsl:value-of select="$all_records"/>&#160;
+							</td>
+						</xsl:otherwise>
+					</xsl:choose>							
+				</xsl:otherwise>
+			</xsl:choose> -->
+
+			<td nowrap="nowrap" align="center"><xsl:value-of select="lang_showing"/></td>
+			<xsl:choose>
+				<xsl:when test="number($all_records) > (number($start_record) + number($record_limit))">
+				<xsl:variable name="next_num"><xsl:value-of select="number($cur_record) + number($record_limit)"/></xsl:variable>
+					<xsl:choose>
+						<xsl:when test="number($all_records) > number($next_num)-number(1)">
+						<xsl:variable name="next"><xsl:value-of select="nextmatchs_url"/>&amp;start=<xsl:value-of select="number($next_num) - number(1)"/></xsl:variable>
+							<td width="25" align="right">
+								<a href="{$next}"><img src="{$right_img}" border="0" width="{$img_width}" height="{$img_height}" alt="{$title_next}" title="{$title_next}"/></a>
+							</td>
+						</xsl:when>
+						<xsl:otherwise>
+							<td width="25" align="right">
+								<img src="{$right_grey_img}" border="0" width="{$img_width}" height="{$img_height}"/>
+							</td>
+						</xsl:otherwise>
+					</xsl:choose>
+				</xsl:when>
+				<xsl:otherwise>
+					<td width="25" align="right">
+						<img src="{$right_grey_img}" border="0" width="{$img_width}" height="{$img_height}"/>
+					</td>
+				</xsl:otherwise>
+			</xsl:choose>
+
+			<xsl:choose>
+				<xsl:when test="number($all_records) > (number($start_record) + number($record_limit))">
+				<xsl:variable name="last_num"><xsl:value-of select="number($all_records)-number($record_limit)+number(1)"/></xsl:variable>
+					<xsl:choose>
+						<xsl:when test="number($last_num) > number($cur_record)">
+						<xsl:variable name="last"><xsl:value-of select="nextmatchs_url"/>&amp;start=<xsl:value-of select="number($last_num)-number(1)"/></xsl:variable>
+							<td width="25" align="right">
+								<a href="{$last}"><img src="{$last_img}" border="0" width="{$img_width}" height="{$img_height}" alt="{$title_last}" title="{$title_last}"/></a>
+							</td>
+						</xsl:when>
+						<xsl:otherwise>
+							<td width="25" align="right">
+								<img src="{$last_grey_img}" border="0" width="{$img_width}" height="{$img_height}"/>
+							</td>
+						</xsl:otherwise>
+					</xsl:choose>
+				</xsl:when>
+				<xsl:otherwise>
+					<td width="25" align="right">
+						<img src="{$last_grey_img}" border="0" width="{$img_width}" height="{$img_height}"/>
+					</td>
+				</xsl:otherwise>
+			</xsl:choose>
+
+			<xsl:choose>
+			<!--<xsl:when test="number($all_records) =1"> -->
+				<xsl:when test="allow_all_rows != ''">
+				<xsl:variable name="all"><xsl:value-of select="nextmatchs_url"/>&amp;start=0</xsl:variable>
+					<td width="25" align="right">
+						<a href="{$all}"><img src="{$all_img}" border="0" alt="{$title_all}" title="{$title_all}"/></a>
+					</td>
+				</xsl:when>
+			<!--	<xsl:otherwise>
+				<xsl:variable name="all"><xsl:value-of select="nextmatchs_url"/>&amp;allrows=1</xsl:variable>
+					<td width="25" align="right">
+						<a href="{$all}"><img src="{$all_img}" border="0"/></a>
+					</td>
+				</xsl:otherwise> -->
+			</xsl:choose>
+		</tr>
+	</table>
+</xsl:template>
diff -aburN --exclude='CVS*' phpgwapi.org/templates/default/search_field.xsl phpgwapi/templates/default/search_field.xsl
--- phpgwapi.org/templates/default/search_field.xsl	1970-01-01 01:00:00.000000000 +0100
+++ phpgwapi/templates/default/search_field.xsl	2006-01-12 11:35:18.000000000 +0100
@@ -0,0 +1,28 @@
+<!-- $Id: search_field.xsl,v 1.3 2005/01/18 23:51:15 ceb Exp $ -->
+
+	<xsl:template name="search_field">
+		<xsl:apply-templates select="search_data"/>
+	</xsl:template>
+
+	<xsl:template match="search_data">
+		<xsl:variable name="select_url"><xsl:value-of select="select_url"/></xsl:variable>
+		<xsl:variable name="query"><xsl:value-of select="query"/></xsl:variable>
+		<xsl:variable name="lang_search"><xsl:value-of select="lang_search"/></xsl:variable>
+			<form method="post" action="{$select_url}">
+				<input type="text" name="query" value="{$query}" onMouseout="window.status='';return true;">
+					<xsl:attribute name="onMouseover">
+						<xsl:text>window.status='</xsl:text>
+							<xsl:value-of select="lang_searchfield_statustext"/>
+						<xsl:text>'; return true;</xsl:text>
+					</xsl:attribute>
+				</input>
+				<xsl:text> </xsl:text>
+				<input type="submit" name="submit" value="{$lang_search}" onMouseout="window.status='';return true;"> 
+					<xsl:attribute name="onMouseover">
+						<xsl:text>window.status='</xsl:text>
+							<xsl:value-of select="lang_searchbutton_statustext"/>
+						<xsl:text>'; return true;</xsl:text>
+					</xsl:attribute>
+				</input>
+			</form>
+	</xsl:template>
