* * -------------------------------------------- * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the * * Free Software Foundation; either version 2 of the License, or (at your * * option) any later version. * \**************************************************************************/ /* $Id$ */ class xul_io { var $widget2xul; var $attr2xul; var $xul2widget; function xul_io() { $this->xmltool = CreateObject('etemplate.xmltool'); $this->attr2xul = array( // how to translate attr, common to all widgets 'name' => 'id', 'help' => 'statustext', 'span' => 'span,class', 'type' => '', // this is the widget-name => dont write as attr 'disabled' => 'disabled=true', 'readonly' => 'readonly=true', 'size' => 'options' ); $this->widget2xul = array( // how to translate widget-names and widget-spec. attr. 'label' => array( '.name' => 'description', 'label' => 'value' ), 'text' => array( '.name' => 'textbox', 'size' => 'size,maxlength' ), 'textarea' => array( '.name' => 'textbox', '.set' => 'multiline=true', 'size' => 'rows,cols' ), 'integer' => array( '.name' => 'textbox', '.set' => 'type=integer', 'size' => 'min,max,size' ), 'float' => array( '.name' => 'textbox', '.set' => 'type=float', 'size' => 'min,max,size' ), 'select' => array( '.name' => 'menulist,menupopup', ), 'select-multi' => array( // multiselection, if size > 0 '.name' => 'listbox', 'size' => 'rows' ), 'template' => array( '.name' => 'grid', 'size' => 'content' ), 'image' => array( '.name' => 'image', 'label' => 'src' ), 'tab' => array( '.name' => 'tabbox,tabs,tabpanels' ), 'button' => array( '.name' => 'button', 'size' => 'image,ro_image' ) ); $this->xul2widget = array( 'menupopup' => 'select', 'listbox' => 'select', 'description' => 'label' ); } function set_attributes(&$widget,$attr,$val,$spanned='') { if ($attr != '') { $attrs = explode(',',$attr); if (count($attrs)) { $vals = count($attrs) > 1 ? explode(',',$val) : array($val); while (list($n,$attr) = each($attrs)) { if (($val = $vals[$n]) != '') { if ($attr == 'span') { $spanned = $val == 'all' ? 999 : $val - 1; } list($attr,$set) = explode('=',$attr); $widget->set_attribute($attr,$set != '' ? $set : $val); } } } } } function etempl2grid($etempl,&$root,$embeded_too=True) { $xul_grid = new xmlnode('grid'); $xul_grid->set_attribute('id',$etempl->name); $xul_grid->set_attribute('template',$etempl->template); $xul_grid->set_attribute('lang',$etempl->lang); $xul_grid->set_attribute('group',$etempl->group); $xul_grid->set_attribute('version',$etempl->version); $this->set_attributes($xul_grid,'width,height,border,class,spacing,padding',$etempl->size); $xul_columns = new xmlnode('columns'); $xul_rows = new xmlnode('rows'); reset($etempl->data); list(,$opts) = each ($etempl->data); // read over options-row while (list($r,$row) = each ($etempl->data)) { $xul_row = new xmlnode('row'); $this->set_attributes($xul_row,'class,valign',$opts["c$r"]); $this->set_attributes($xul_row,'height',$opts["h$r"]); $spanned = 0; while (list($c,$cell) = each($row)) { if ($r == '1') // write columns only once in the first row { $xul_column = new xmlnode('column'); $this->set_attributes($xul_column,'width',$opts[$c]); $xul_columns->add_node($xul_column); } if ($spanned) { --$spanned; continue; // spanned cells are not written } $type = $cell['type']; if (is_array($type)) { list(,$type) = each($type); } if ($type == 'template' && $cell['name'][0] != '@' && $embeded_too) { $embeded = new etemplate($cell['name']); $this->etempl2grid($embeded,&$root,$embeded_too); unset($embeded); } if (substr($type,0,6) == 'select') { $type = $cell['size'] > 1 ? 'select-multi' : 'select'; } $widgetattr2xul = isset($this->widget2xul[$type]) ? $this->widget2xul[$type] : array(); $type = isset($widgetattr2xul['.name']) ? $widgetattr2xul['.name'] : $type; list($parent,$child,$child2) = explode(',',$type); $widget = new xmlnode($parent); if ($child) { $child = new xmlnode($child); } if ($child2) { $child2 = new xmlnode($child2); } if (isset($widgetattr2xul['.set'])) // set default-attr for type { $attrs = explode(',',$widgetattr2xul['.set']); while (list(,$attr) = each($attrs)) { list($attr,$val) = explode('=',$attr); $widget->set_attribute($attr,$val); } } switch ($parent) { case 'nextmatch': $embeded = new etemplate($cell['size']); $this->etempl2grid($embeded,&$root,$embeded_too); unset($embeded); break; case 'tabbox': $labels = explode('|',$cell['label']); unset($cell['label']); $helps = explode('|',$cell['help']); unset($cell['help']); $names = explode('|',$cell['name']); unset($cell['name']); for ($n = 0; $n < count($labels); ++$n) { $tab = new xmlnode('tab'); $tab->set_attribute('label',$labels[$n]); $tab->set_attribute('statustext',$helps[$n]); $child->add_node($tab); $grid = new xmlnode('grid'); $grid->set_attribute('id',$names[$n]); $child2->add_node($grid); $embeded = new etemplate($names[$n]); $this->etempl2grid($embeded,&$root,$embeded_too); unset($embeded); } break; case 'menulist': // id,options belongs to the 'menupopup' child $child->set_attribute('id',$cell['name']); unset($cell['name']); if (isset($cell['size']) && $cell['size'] != '') { $child->set_attribute('options',$cell['size']); unset($cell['size']); } if ($cell['type'] != 'select') // one of the sub-types { $child->set_attribute('type',$cell['type']); } break; case 'menulist': case 'listbox': if ($cell['type'] != 'select') // one of the sub-types { $widget->set_attribute('type',$cell['type']); } break; } while (list($attr,$val) = each($cell)) { if (is_array($val)) // correct old buggy etemplates { list(,$val) = each($val); } if (isset($widgetattr2xul[$attr])) { $attr = $widgetattr2xul[$attr]; } elseif (isset($this->attr2xul[$attr])) { $attr = $this->attr2xul[$attr]; } $this->set_attributes($widget,$attr,$val,&$spanned); } if ($child) { $widget->add_node($child); } if ($child2) { $widget->add_node($child2); } $xul_row->add_node($widget); } $xul_rows->add_node($xul_row); } $xul_grid->add_node($xul_columns); $xul_grid->add_node($xul_rows); if ($etempl->style != '') { $styles = new xmlnode('styles'); $styles->set_value($etempl->style); $xul_grid->add_node($styles); } $root->add_node($xul_grid); return ''; } function export($etempl) { if ($this->debug) { echo "
etempl->data = "; _debug_array($etempl->data); } $doc = new xmldoc(); $doc->add_comment('$Id$'); $xul_overlay = new xmlnode('overlay'); $this->etempl2grid($etempl,&$xul_overlay); $doc->add_root($xul_overlay); $xml = $doc->export_xml(); //if ($this->debug) { echo "
\n" . htmlentities($xml) . "\n\n"; } return $xml; } function import(&$etempl,$data) { if ($this->debug) { echo "
\n" . htmlentities($data) . "\n
\n"; } $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); $vals = $index = ''; $ok = xml_parse_into_struct($parser, $data, $vals, $index); if (!$ok || !is_array($vals)) { $err = 'Error Line '.xml_get_current_line_number($parser).', Column '.xml_get_current_column_number($parser). ': '.xml_error_string(xml_get_error_code($parser)); } xml_parser_free($parser); if ($err != '') { return $err; } while (list($n,$node) = each($vals)) { $type = $node['type']; $tag = $node['tag']; $attr = is_array($node['attributes']) ? $node['attributes'] : array(); if ($attr['id']) { $attr['name'] = $attr['id']; unset($attr['id']); } if (isset($attr['options']) && $attr['options'] != '') { $attr['size'] = $attr['options']; unset($attr['options']); } if ($tag == 'grid' && $type == 'complete' && !is_array($tab_attr)) { $tag = 'template'; } if ($tag != 'textbox' && !isset($attr['type'])) { $attr['type'] = $this->xul2widget[$tag] ? $this->xul2widget[$tag] : $tag; } if ($this->debug) { echo "
$node[level]: $tag/$type: value='$node[value]' attr=\n"; _debug_array($attr);
}
switch ($tag)
{
case 'overlay':
break;
case 'grid':
if ($type != 'close' && is_array($tab_attr))
{
$tab_names[] = $attr['name'];
break;
}
if ($node['level'] > 2) // level 1 is the overlay
{
return "Can't import nested $node[tag]'s !!!";
}
if ($type != 'open')
{
break;
}
if ($grid_started) // more than one grid in the file --> place it into the cache
{
$cname = ($etempl->template == '' ? 'default' : $etempl->template).'/'.$etempl->name.
($etempl->lang == '' ? '' : '.'.$etempl->lang);
$imported[] = $etempl->name;
$GLOBALS['phpgw_info']['etemplate']['cache'][$cname] = $etempl->as_array(1);
}
$grid_started = True;
$etempl->init($attr);
$size_opts = array('padding','spacing','class','border','height','width');
for ($size = ''; list(,$opt) = each($size_opts); )
{
$size = $attr[$opt] . ($size != '' ? ",$size" : '');
}
$etempl->size = $size;
$etempl->cols = $etempl->rows = 0;
$etempl->data = array();
break;
case 'columns':
case 'rows':
break;
case 'column':
if ($type != 'complete')
{
return 'place widgets in