Changeset 3894


Ignore:
Timestamp:
Oct 20, 2010, 9:35:51 AM (13 years ago)
Author:
Gregory Vincic
Message:

Fixes #711. Use method fieldset.setOpen(false) to hide the fieldset.

Location:
trunk/client/servlet
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/client/servlet/src/org/proteios/gui/form/Fieldset.java

    r3842 r3894  
    11/*
    2  $Id$
    3 
    4  Copyright (C) 2006, 2007 Gregory Vincic
    5 
    6  Files are copyright by their respective authors. The contributions to
    7  files where copyright is not explicitly stated can be traced with the
    8  source code revision system.
    9 
    10  This file is part of Proteios.
    11  Available at http://www.proteios.org/
    12 
    13  proteios-2.x is free software; you can redistribute it and/or
    14  modify it under the terms of the GNU General Public License
    15  as published by the Free Software Foundation; either version 2
    16  of the License, or (at your option) any later version.
    17 
    18  Proteios is distributed in the hope that it will be useful,
    19  but WITHOUT ANY WARRANTY; without even the implied warranty of
    20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    21  GNU General Public License for more details.
    22 
    23  You should have received a copy of the GNU General Public License
    24  along with this program; if not, write to the Free Software
    25  Foundation, Inc., 59 Temple Place - Suite 330,
    26  Boston, MA  02111-1307, USA.
    27  */
     2    $Id$
     3   
     4    Copyright (C) 2006, 2007, 2010 Gregory Vincic
     5   
     6    Files are copyright by their respective authors. The contributions to
     7    files where copyright is not explicitly stated can be traced with the
     8    source code revision system.
     9   
     10    This file is part of Proteios.
     11    Available at http://www.proteios.org/
     12   
     13    proteios-2.x is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License
     15    as published by the Free Software Foundation; either version 2
     16    of the License, or (at your option) any later version.
     17   
     18    Proteios is distributed in the hope that it will be useful,
     19    but WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     21    GNU General Public License for more details.
     22   
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place - Suite 330,
     26    Boston, MA  02111-1307, USA.
     27*/
    2828package org.proteios.gui.form;
    2929
     30import java.util.ArrayList;
     31import java.util.List;
    3032import org.proteios.gui.GUIElement;
    3133import org.proteios.gui.Title;
    32 import java.util.ArrayList;
    33 import java.util.List;
    3434
    3535/**
    36  * Groups a set of fields together
    37  *
    38  * @author gregory
    39  */
     36    Groups a set of fields together     
     37*/
    4038public class Fieldset
    41     extends GUIElement<Fieldset>
     39extends GUIElement<Fieldset>
    4240{
    43  
    44   private List<GUIElement> fields = null;
    45   private Title title = null;
     41    private List<GUIElement> fields = null;
     42    private Title title = null;
     43    /*
     44        Set the open flag to false to hide e.g. advanced fieldsets from the user.
     45    */
     46    private Boolean open = true;
    4647
     48    public Fieldset()
     49    {
     50        this.title = new Title("");
     51    }
     52   
     53    public Fieldset(String title)
     54    {
     55        this.title = new Title(title);
     56    }
     57   
     58    public Title getTitle()
     59    {
     60        return this.title;
     61    }
     62   
     63    /**
     64        * Set the fieldset legens Title object.
     65        *
     66        * @param legendTitle Title The legend Title to set.
     67    */
     68    public void setTitle(Title title)
     69    {
     70        this.title = title;
     71    }
     72   
     73    public void setTitle(String title)
     74    {
     75        this.title.setTitle(title);
     76    }
     77   
     78    public List<GUIElement> getFields()
     79    {
     80        if (fields == null)
     81        return new ArrayList<GUIElement>(0);
     82        return fields;
     83    }
     84   
     85    public void setFields(List<GUIElement> fields)
     86    {
     87        this.fields = fields;
     88    }
     89   
     90    public void add(GUIElement field)
     91    {
     92        if (fields == null)
     93        {
     94            this.fields = new ArrayList<GUIElement>();
     95        }
     96        if (field != null)
     97        fields.add(field);
     98    }
     99   
     100    public void add(int i, GUIElement field)
     101    {
     102        if (fields == null)
     103        {
     104            this.fields = new ArrayList<GUIElement>();
     105        }
     106        if (field != null)
     107        fields.add(i, field);
     108    }
     109   
     110    public int size()
     111    {
     112        if(this.fields == null)
     113        {
     114            return 0;
     115        }
     116        return this.fields.size();
     117    }
    47118
    48  public Fieldset()
    49  {
    50   this.title = new Title("");
    51  }
     119    public void setOpen(Boolean open)
     120    {
     121        this.open = open;
     122    }
    52123
    53  public Fieldset(String title)
    54  {
    55   this.title = new Title(title);
    56  } 
    57 
    58   public Title getTitle()
    59   {
    60     return this.title;
    61   }
    62 
    63 
    64   /**
    65    * Set the fieldset legens Title object.
    66    *
    67    * @param legendTitle Title The legend Title to set.
    68    */
    69   public void setTitle(Title title)
    70   {
    71     this.title = title;
    72   }
    73 
    74 public void setTitle(String title)
    75   {
    76     this.title.setTitle(title);
    77   }
    78 
    79 
    80   public List<GUIElement> getFields()
    81   {
    82     if (fields == null)
    83       return new ArrayList<GUIElement>(0);
    84     return fields;
    85   }
    86 
    87 
    88   public void setFields(List<GUIElement> fields)
    89   {
    90     this.fields = fields;
    91   }
    92 
    93 
    94   public void add(GUIElement field)
    95   {
    96     if (fields == null)
    97     {
    98       this.fields = new ArrayList<GUIElement>();
    99     }
    100     if (field != null)
    101       fields.add(field);
    102   }
    103 
    104 
    105   public void add(int i, GUIElement field)
    106   {
    107     if (fields == null)
    108     {
    109       this.fields = new ArrayList<GUIElement>();
    110     }
    111     if (field != null)
    112       fields.add(i, field);
    113   }
    114 
    115  public int size()
    116  {
    117   if(this.fields == null)
    118   {
    119    return 0;
    120   }
    121   return this.fields.size();
    122  }
     124    public Boolean isOpen()
     125    {
     126        return this.open;
     127    }
    123128}
  • trunk/client/servlet/src/org/proteios/gui/web/GUIConverter.java

    r3842 r3894  
    11/*
    2  $Id$
    3 
    4  Copyright (C) 2006 Gregory Vincic
    5  Copyright (C) 2007 Gregory Vincic, Olle Mansson
    6 
    7  Files are copyright by their respective authors. The contributions to
    8  files where copyright is not explicitly stated can be traced with the
    9  source code revision system.
    10 
    11  This file is part of Proteios.
    12  Available at http://www.proteios.org/
    13 
    14  Proteios-2.x is free software; you can redistribute it and/or
    15  modify it under the terms of the GNU General Public License
    16  as published by the Free Software Foundation; either version 2
    17  of the License, or (at your option) any later version.
    18 
    19  Proteios is distributed in the hope that it will be useful,
    20  but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    22  GNU General Public License for more details.
    23 
    24  You should have received a copy of the GNU General Public License
    25  along with this program; if not, write to the Free Software
    26  Foundation, Inc., 59 Temple Place - Suite 330,
    27  Boston, MA  02111-1307, USA.
    28  */
     2    $Id$
     3   
     4    Copyright (C) 2006 Gregory Vincic
     5    Copyright (C) 2007 Gregory Vincic, Olle Mansson
     6   
     7    Files are copyright by their respective authors. The contributions to
     8    files where copyright is not explicitly stated can be traced with the
     9    source code revision system.
     10   
     11    This file is part of Proteios.
     12    Available at http://www.proteios.org/
     13   
     14    Proteios-2.x is free software; you can redistribute it and/or
     15    modify it under the terms of the GNU General Public License
     16    as published by the Free Software Foundation; either version 2
     17    of the License, or (at your option) any later version.
     18   
     19    Proteios is distributed in the hope that it will be useful,
     20    but WITHOUT ANY WARRANTY; without even the implied warranty of
     21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     22    GNU General Public License for more details.
     23   
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 59 Temple Place - Suite 330,
     27    Boston, MA  02111-1307, USA.
     28*/
    2929package org.proteios.gui.web;
    3030
     31import java.lang.reflect.InvocationTargetException;
     32import java.lang.reflect.Method;
     33import java.text.SimpleDateFormat;
     34import java.util.Date;
     35import java.util.Iterator;
     36import java.util.List;
     37import java.util.Properties;
     38import java.util.Random;
     39import java.util.Set;
     40import javax.servlet.http.HttpServletRequest;
    3141import org.proteios.AbstractLink;
    3242import org.proteios.ActionLink;
     
    7181import org.proteios.gui.table.Row;
    7282import org.proteios.gui.table.TreeRow;
    73 
    7483import se.lu.thep.waf.constraints.VString;
    7584import se.lu.thep.waf.dom.html.A;
     
    98107import se.lu.thep.waf.dom.html.Ul;
    99108
    100 import java.lang.reflect.InvocationTargetException;
    101 import java.lang.reflect.Method;
    102 import java.text.SimpleDateFormat;
    103 import java.util.Date;
    104 import java.util.Iterator;
    105 import java.util.List;
    106 import java.util.Properties;
    107 import java.util.Random;
    108 import java.util.Set;
     109/**
     110    * Converts org.proteios.gui.* GUIElements to Tag objects
     111    *
     112    * @see HtmlFactory LayoutFactory
     113    * @author gregory
     114*/
     115public class GUIConverter
     116extends AbstractGUIConverter<Tag>
     117{
     118    private final String contextPath;
     119    private HtmlFactory hf;
     120    private HttpServletRequest request = null;
     121    private final SimpleDateFormat formatter = new SimpleDateFormat(
     122    "yyyy-MM-dd HH:mm:ss");
     123    private String imagePath;
     124    private Localizer locale = null;
     125    private Properties iconSet = null;
     126    /**
     127        * This flag is used to tell converter methods not to generate it's own form
     128        * tag. Used e.g. when converting the table configuration content so that
     129        * the config fields are a part of the table form.
     130    */
     131    private Tag currentFormTag = null;
     132    private String currentFormId = null;
     133    private TypeUtil typeUtil = new TypeUtil();
     134   
     135    public HttpServletRequest getRequest()
     136    {
     137        return request;
     138    }
     139   
     140    public void setRequest(HttpServletRequest request)
     141    {
     142        this.request = request;
     143        hf.setRequest(request);
     144    }
     145   
     146    public GUIConverter(String contextPath)
     147    {
     148        super();
     149        this.contextPath = contextPath + "/app";
     150        this.imagePath = contextPath + "/static/img/";
     151        this.hf = new HtmlFactory(contextPath);
     152    }
     153   
     154    private Random r = new Random();
     155   
     156    public Tag convert(Image img)
     157    {
     158        ActionLink viewAction;
     159        String imgId, imgSrc, loadingImgSrc;
     160        Tag div, script;
     161        Img imgT;
     162        Boolean useFrame;
     163        // static source is used unless ViewAction is set
     164        imgId = "img" + r.nextInt(10);
     165        imgSrc = imagePath + img.getStaticSrc();
     166        viewAction = img.getViewAction();
     167        if (viewAction != null)
     168        {
     169            imgSrc = contextPath + "?action=" + img.getViewAction().toString();
     170        }
     171        loadingImgSrc = imagePath + "loading.gif";
     172        useFrame = img.getFramed();
     173        div = hf.newLayoutDiv();
     174        if (useFrame)
     175        {
     176            div.addClass("imageContainer");
     177            // If bot height and width are set use those
     178            if (img.getHeight() > 0 && img.getWidth() > 0)
     179            div
     180            .setStyle("height : " + img.getHeight() + "px; width : " + img
     181            .getWidth() + "px");
     182        }
     183        imgT = div.newImg().setId(imgId).setClass("image");
     184        // First we show the loading img
     185        imgT.setSrc(loadingImgSrc);
     186        //
     187        if (img.getImageMap() != null && img.getImageMap().getImageMapAreaList() != null)
     188        {
     189            String imageMapStr = "ImageMap" + imgId;
     190            imgT.setUsemap("#" + imageMapStr);
     191            // Create image map
     192            Map map = new Map();
     193            map.setParent(div);
     194            div.add(map);
     195            map.setName(imageMapStr);
     196            List<ImageMapArea> imageMapAreaList = img.getImageMap().getImageMapAreaList();
     197            for (int i = 0; i < imageMapAreaList.size(); i++)
     198            {
     199                // Get image map area data from image object
     200                ImageMapArea imageMapArea = (ImageMapArea) imageMapAreaList .get(i);
     201                int xTopLeft = imageMapArea.getXTopLeft();
     202                int yTopLeft = imageMapArea.getYTopLeft();
     203                int xBottomRight = imageMapArea.getXBottomRight();
     204                int yBottomRight = imageMapArea.getYBottomRight();
     205                String hrefStr = imageMapArea.getHrefStr();
     206                String toolTipStr = imageMapArea.getToolTipStr();
     207                String onMouseoverStr = null;
     208                String onMouseoutStr = null;
     209                if (toolTipStr != null && !toolTipStr.equals(""))
     210                {
     211                    onMouseoverStr = new String("showtip(this,event,'" + toolTipStr + "')");
     212                    onMouseoutStr = new String("hidetip()");
     213                }
     214                // Create new image map area
     215                Area area = new Area();
     216                area.setParent(map);
     217                map.add(area);
     218                area.setShape("RECT");
     219                area.setCoords(xTopLeft, yTopLeft, xBottomRight, yBottomRight);
     220                if (hrefStr != null && !hrefStr.equals(""))
     221                {
     222                    area.setHref(hrefStr);
     223                }
     224                if (onMouseoverStr != null && !onMouseoverStr.equals(""))
     225                {
     226                    area.setOnMousover(onMouseoverStr);
     227                }
     228                if (onMouseoutStr != null && !onMouseoutStr.equals(""))
     229                {
     230                    area.setOnMousout(onMouseoutStr);
     231                }
     232            }
     233        }
     234        script = div.newScript();
     235        script.newCData("var " + imgId + " = new Image();");
     236        script.newCData(imgId + ".src = \"" + imgSrc + "\";");
     237        script.newCData("getElement('" + imgId + "').src = " + imgId + ".src;");
     238        return div;
     239    }
     240   
     241    public Tag convert(IFrame obj)
     242    {
     243        Tag tag = hf.newIFrame(obj);
     244        String src = contextPath + "?action=" + obj.getSrc().toString();
     245        tag.setAttribute(new Attribute("src", src));
     246        String id = this.nextId();
     247        tag.setId(id);
     248        tag
     249        .setAttribute(new Attribute("onload", "resize_iframe('" + id + "')"));
     250        return tag;
     251    }
     252   
     253    public Tag convert(Listing list)
     254    {
     255        Div layout = hf.newLayoutDiv();
     256        Div listing = layout.newDiv().setClass("listing");
     257        String title = list.getTitle();
     258        if (title != null)
     259        {
     260            listing.add(hf.newBar().addClass("title").add(
     261            new CData(locale.get(title) + "&nbsp;")));
     262        }
     263        List<ListItem> items = list.getItems();
     264        if (items.size() > 0)
     265        {
     266            Tag dl = new Dl();
     267            for (ListItem item : items)
     268            {
     269                Tag dt = dl.newDt();
     270                Tag dd = dl.newDd();
     271                if (item.getDate() != null)
     272                {
     273                    String date = formatter.format(item.getDate());
     274                    dt.newCData(date + " - ");
     275                }
     276                dt.newCData(item.getTitle());
     277                dd.newCData(item.getContent());
     278            }
     279            listing.add(dl);
     280        }
     281        else
     282        {
     283            listing.newDiv().setClass("empty").newCData("Empty");
     284        }
     285        return layout;
     286    }
     287   
     288    /**
     289        * @param action
     290        * @return goToLocation('action.toString()')
     291    */
     292    private String action2js(ActionLink action)
     293    {
     294        StringBuilder sb = new StringBuilder();
     295        if (action != null)
     296        {
     297            String jsMethod = "rightGo";
     298            sb.append(jsMethod + "('");
     299            sb.append(action.toString());
     300            sb.append("')");
     301        }
     302        return sb.toString();
     303    }
     304   
     305    public Tag convert(org.proteios.gui.TreeMenu menu)
     306    {
     307        Tag layout = new Div().setId("menuh-container").newDiv().setId("menuh");
     308        for (Node node : menu.getRoot().getChildNodes())
     309        {
     310            Tag top = new Ul();
     311            top.add(convert(node));
     312            layout.add(top);
     313        }
     314        return layout.getRoot();
     315    }
     316   
     317    public Tag convert(org.proteios.gui.MainMenu menu)
     318    {
     319        Tag div, ul;
     320       
     321        div = hf.newLayoutDiv();
     322        ul = convert((org.proteios.gui.TreeMenu) menu);
     323       
     324        div.add(ul);
     325        return div;
     326    }
     327   
     328    public String convert(ClosePopup button)
     329    {
     330        return "closeAllVisiblePopups()";
     331    }
     332   
     333    public Tag<?> convert(ActionLink pageLink, String formId, boolean localize)
     334    {
     335        String js = action2js(pageLink, formId);
     336        A tag = new A();
     337        tag.setHref(js);
     338        // Add the icon if any
     339        String icon = (String) iconSet.get(pageLink.getLabel());
     340        if (icon != null)
     341        {
     342            tag.newImg().setSrc(imagePath + icon);
     343        }
     344        String label = localize ? locale.get(pageLink.getLabel()) : pageLink
     345        .getLabel();
     346        tag.newCData(label);
     347        return tag;
     348    }
     349   
     350    /**
     351        * Converts an ActionLink such that each parameter of the ActionLink is a
     352        * call to the javascript method addField(formId, name, value) before adding
     353        * submitFormAs(formId, actionId)
     354        *
     355        * @param pageLink
     356        * @param formId
     357        * @return string of javascript code used in eg. href of a tags
     358    */
     359    private String action2js(ActionLink pageLink, String formId)
     360    {
     361        StringBuilder js = new StringBuilder();
     362        js.append("javascript:");
     363        List<Parameter> params = pageLink.getParameters();
     364        if (params != null)
     365        {
     366            for (Parameter param : params)
     367            {
     368                js.append("addField(");
     369                js.append("'");
     370                js.append(formId);
     371                js.append("','");
     372                js.append(param.name);
     373                js.append("','");
     374                js.append(param.value);
     375                js.append("');");
     376            }
     377        }
     378        js.append("submitFormAs('");
     379        js.append(formId);
     380        js.append("','");
     381        js.append(pageLink.getActionId());
     382        js.append("');");
     383        return js.toString();
     384    }
     385   
     386    public Tag convert(Scroller scroller, String formId)
     387    {
     388        Tag scrollBar = hf.newBar().addClass("scroller");
     389        // page links
     390        List<ActionLink> pageLinks = scroller.getPageLinks();
     391        for (int i = 0; i < pageLinks.size(); i++)
     392        {
     393            ActionLink pageLink = pageLinks.get(i);
     394            if (pageLink != null)
     395            {
     396                if (!pageLink.isSelected() && !pageLink.isDisabled())
     397                {
     398                    // Link to back or forward page
     399                    boolean localize = true;
     400                    if (i > 1 && i < 7)
     401                    {
     402                        // Do not localize page numbers
     403                        localize = false;
     404                    }
     405                    scrollBar.add(convert(pageLink, formId, false));
     406                }
     407                else
     408                {
     409                    if (pageLink.isDisabled())
     410                    {
     411                        // Current page, text label only
     412                        scrollBar.newSpan().setClass("disabled").newCData(
     413                        pageLink.getLabel() + "&nbsp;");
     414                    }
     415                    else
     416                    {
     417                        scrollBar.newSpan().setClass("selected").newCData(
     418                        pageLink.getLabel() + "&nbsp;");
     419                    }
     420                }
     421            }
     422        }
     423        // Total number of items
     424        int total = scroller.getTotalCount();
     425        scrollBar.newBr();
     426        int from = scroller.getFrom();
     427        int to = from + scroller.getMax();
     428        if (to > total)
     429        to = total;
     430        from++; // As we start from 0
     431        scrollBar.newCData("Showing " + from + "-" + to + " of " + total);
     432        // Add rows/page field if table is controlled by ConfigureTableFactory2
     433        ActionLink configureTableAction = scroller.getTable()
     434        .getConfigureTableAction();
     435        if (configureTableAction != null && configureTableAction.getActionId()
     436        .equals("org.proteios.action.ConfigureTableFactory2"))
     437        {
     438            // Add number of rows per page field
     439            scrollBar.newCData("&nbsp;&nbsp;&nbsp;Rows/page ");
     440            scrollBar.newTh().newInput().setSize(3).setName(
     441            Scroller.VMAXRESULT.getName()).setValue(
     442            Integer.toString(scroller.getMax()));
     443        }
     444        // TODO gregory add Localizer to GUIConverter
     445        scrollBar.add(new CData("&nbsp;"));
     446        return scrollBar.getRoot();
     447    }
     448   
     449    /**
     450        * @param table to convert
     451        * @return root tag
     452    */
     453    public Tag convert(org.proteios.gui.table.Table table)
     454    {
     455        // <DIV class="layout"...
     456        Tag layout = hf.newLayoutDiv();
     457        // <FORM ...
     458        Scroller scroller = null;
     459        Toolbar toolbar = null;
     460        String formId = null;
     461        boolean outerForm = false;
     462        if (currentFormTag == null)
     463        {
     464            outerForm = true;
     465            formId = "formOf" + table.getId();
     466            currentFormId = formId;
     467            currentFormTag = layout.newForm().setId(formId).setMethod("POST")
     468            .setAction(contextPath);
     469            // Add hidden submit button
     470            currentFormTag.newInput().setType("submit").setClass("hidden");
     471            // Add hidden action field and set the default action
     472            toolbar = table.getToolbar();
     473            if (toolbar != null)
     474            {
     475                Input field = currentFormTag.newInput()
     476                .setId(formId + "action").setName("action").setType(
     477                "hidden");
     478                if (toolbar.getDefaultAction() != null)
     479                {
     480                    AbstractLink defaultLink = toolbar.getDefaultAction();
     481                    if (defaultLink != null && ActionLink.class
     482                    .isAssignableFrom(defaultLink.getClass()))
     483                    {
     484                        field
     485                        .setValue(((ActionLink) defaultLink).getActionId());
     486                    }
     487                }
     488               
     489            }
     490            scroller = table.getScroller();
     491            List<TextField<?>> hiddenFields = table.getHiddenFields();
     492            if (hiddenFields != null && hiddenFields.size() > 0)
     493            {
     494                for (TextField<?> f : hiddenFields)
     495                {
     496                    currentFormTag.add(convert(f));
     497                }
     498            }
     499        }
     500        else
     501        {
     502            formId = currentFormId;
     503            toolbar = table.getToolbar();
     504        }
     505        // <DIV class="table" ...
     506        Tag tableLayout = currentFormTag.newDiv().setClass("table");
     507        // Table title
     508        String title = table.getTitle();
     509        String subtitle = table.getSubtitle();
     510        Tag titleBar = hf.newBar();
     511        ActionLink configureTableAction = table.getConfigureTableAction();
     512        // Table configuration popup
     513        if (title != null)
     514        {
     515            if (configureTableAction != null && configureTableAction
     516            .getActionId().equals(
     517            "org.proteios.action.ConfigureTableFactory2"))
     518            {
     519                // Add the icon only if there is a GUI to display
     520                Img configIcon = new Img().setSrc(imagePath + "/columns.gif")
     521                .setClass("tableConfigIcon");
     522                String id = nextId();
     523                A options = new A();
     524                options.setStyle("float:right; font-size: 0.9em; text-decoration: none");
     525                options.newCData("Table Options");
     526                options.setHref("javascript:popup('" + id + "')");
     527                configIcon.setOnClick("popup('" + id + "')");
     528                // Insert the popup div inside the form tag
     529                Div popupLayout = currentFormTag.newDiv().setClass(
     530                "popupLayout").setId(id);
     531                TitledWindow tw = new TitledWindow("TableOptions");
     532                tw.setStatic(false);
     533                Tag popContent = convert(tw);
     534                popupLayout.add(popContent);
     535                // Header
     536                Tag tbl = popContent.newDiv().setClass("table").newDiv()
     537                .setClass("tableContent").newTable().setCellPadding(1)
     538                .setCellSpacing(0);
     539                Tag trh = tbl.newTr();
     540                trh.newTh().newCData(locale.get("Show"));
     541                trh.newTh().newCData(locale.get("ColumnDisplayOrder"));
     542                trh.newTh().newCData(locale.get("OrderBy"));
     543                trh.newTh().newCData(locale.get("ColumnSortPriority"));
     544                trh.newTh().newCData(locale.get("Column"));
     545                // Toolbar
     546                titleBar.add(configIcon);
     547                titleBar.add(options);
     548                // Table configuration updated flag set to "true"
     549                Input tableConfigurationUpdatedField = trh.newInput().
     550                setName("tableConfigurationUpdated").setType("hidden");
     551                tableConfigurationUpdatedField.setValue("true");
     552                // Get number of potential sort columns
     553                int nSortColumns = 0;
     554                for (Column col : table.getHeader())
     555                {
     556                    AttributeDefinition ad = col.getAttributeDefinition();
     557                    if (ad != null)
     558                    {
     559                        if (col.getDisplayFilter())
     560                        {
     561                            nSortColumns++;
     562                        }
     563                    }
     564                }
     565                // Add column selection here
     566                boolean firstColumnIsIdColumn = false; // Used below to indicate if 'Id' is part of the header
     567                int nColumns = table.getHeader().size();
     568                for (Column col : table.getHeader())
     569                {
     570                    AttributeDefinition ad = col.getAttributeDefinition();
     571                    if (ad != null)
     572                    {
     573                        Tr tr = tbl.newTr();
     574                        // Show
     575                        Input inputTag = tr.newTd().newInput().setType(
     576                        "checkbox").setName("show" + ad.getKey());
     577                        if (col.isVisible())
     578                        inputTag.setAttribute(new Attribute("checked",
     579                        "checked"));
     580                        // Column display order select box
     581                        Integer colDisplayOrder = col.getDisplayOrder();
     582                       
     583                        if (ad.getKey().equals("Id"))
     584                        {
     585                            // Disable display order select box for "Id" column
     586                            tr.newTd().newCData("" + colDisplayOrder + "&nbsp;");
     587                            firstColumnIsIdColumn = true;
     588                        }
     589                        else
     590                        {
     591                            // Add display order select box for other columns
     592                            Tag displayOrderSelectBox = new Select().setName("displayOrder" + ad.getKey());
     593                            for (int i=0; i < nColumns; i++)
     594                            {
     595                                int displayOrderValue = i + 1;
     596                                // If first column is "Id" column, reserve this position
     597                                if (!firstColumnIsIdColumn || displayOrderValue > 1)
     598                                {
     599                                    String displayOrderValueStr = "" + displayOrderValue;
     600                                    Option displayOrderOption = displayOrderSelectBox.newOption().setValue(displayOrderValueStr);
     601                                    displayOrderOption.newCData(displayOrderValueStr);
     602                                    if (colDisplayOrder != null && colDisplayOrder == displayOrderValue)
     603                                    {
     604                                        displayOrderOption.select();
     605                                    }
     606                                }
     607                            }
     608                            tr.newTd().add(displayOrderSelectBox);
     609                        }
     610                                   
     611                        // Order by
     612                        if (col.getDisplayFilter())
     613                        {
     614                            Tag s = new Select().setName("orderBy" + ad
     615                            .getKey());
     616                            Option def = s.newOption().setValue("");
     617                            def.newCData("&nbsp;");
     618                            Option asc = s.newOption().setValue("asc");
     619                            asc.newCData("asc");
     620                            Option desc = s.newOption().setValue("desc");
     621                            desc.newCData("desc");
     622                            if (col.getOrder() == null)
     623                            {
     624                                def.select();
     625                            }
     626                            else if (col.getOrder().equals(SortOrder.ASC))
     627                            {
     628                                asc.select();
     629                            }
     630                            else if (col.getOrder().equals(SortOrder.DESC))
     631                            {
     632                                desc.select();
     633                            }
     634                            tr.newTd().add(s);
     635                        }
     636                        else
     637                        {
     638                            tr.newTd().newCData("&nbsp;");
     639                        }
     640                        // Column sort priority
     641                        if (col.getDisplayFilter())
     642                        {
     643                            // Sort priority select box
     644                            Tag s = new Select().setName("sortPriority" + ad
     645                            .getKey());
     646                            Option def = s.newOption().setValue("");
     647                            def.newCData("&nbsp;");
     648                            Integer colSortPriority = col.getSortPriority();
     649                            if (colSortPriority == null)
     650                            {
     651                                def.select();
     652                            }
     653                            for (int i=0; i < nSortColumns; i++)
     654                            {
     655                                int sortPriorityValue = i + 1;
     656                                String sortPriorityValueStr = "" + sortPriorityValue;
     657                                Option sortPriorityOption = s.newOption().setValue(sortPriorityValueStr);
     658                                sortPriorityOption.newCData(sortPriorityValueStr);
     659                                if (colSortPriority != null && colSortPriority == sortPriorityValue)
     660                                {
     661                                    sortPriorityOption.select();
     662                                }
     663                            }
     664                            tr.newTd().add(s);
     665                        }
     666                        else
     667                        {
     668                            tr.newTd().newCData("&nbsp;");
     669                        }
     670                        // Column name
     671                        tr.newTd().setAttribute(new Attribute("width", "100%"))
     672                        .newCData(locale.get(col.getValue()));
     673                    }
     674                }
     675                Tag popToolbar = popContent.newDiv().setClass("toolbar");
     676                Tag ul = popToolbar.newUl();
     677                ul
     678                .newLi()
     679                .setOnClick(
     680                "submitFormAs('" + formId + "','org.proteios.action.ConfigureTableFactory2')")
     681                .newCData(locale.get("Apply"));
     682            }
     683        }
     684        // End table configuration
     685        if (title != null)
     686        {
     687            tableLayout.add(titleBar.addClass("title").add(
     688            new CData(locale.get(title) + "&nbsp;")));
     689            if (subtitle != null)
     690            {
     691                titleBar.newCData(" - ");
     692                titleBar.newSpan().setClass("subtitle").newCData(subtitle);
     693            }
     694        }
     695        // <DIV>
     696        Tag tableContent = tableLayout.newDiv().setClass("tableContent");
     697        // <TABLE ...
     698        Tag tbl = new Table().setId(table.getId()).setCellSpacing(0)
     699        .setCellPadding(1).setAttribute(new Attribute("border", "0"))
     700        .setAttribute(new Attribute("width", "100%"));
     701        tableContent.add(tbl);
     702        Tr header = tbl.newTr().setClass("header");
     703        Tr filter = tbl.newTr().setClass("filter").addClass("header");
     704        Iterator<Column> cols = table.getHeader().iterator();
     705        int colspan = 0;
     706        boolean useRowAction = true;
     707        Attribute selected = new Attribute("selected", "selected");
     708        while (cols.hasNext())
     709        {
     710            colspan++;
     711            Column c = cols.next();
     712            if (c.isVisible())
     713            {
     714                if (c.getAction() != null)
     715                useRowAction = false;
     716                Tag col = convert(c, table);
     717                String operator = "";
     718                String value = "";
     719                Filter f = c.getFilter();
     720                if (c.getDisplayFilter())
     721                {
     722                    if (f != null)
     723                    {
     724                        operator = f.getOperator().getSymbol();
     725                        value = f.getValue().toString();
     726                    }
     727                    AttributeDefinition ad = c.getAttributeDefinition();
     728                    if (ad != null)
     729                    {
     730                        Class<?> valueType = ad.getAttributeType();
     731                        String name = "where" + ad.getKey();
     732                        String inputValue = operator + value;
     733                        if (operator.equals(Operator.LIKE.getSymbol()))
     734                        inputValue = Operator.EQ.getSymbol() + value;
     735                        if (typeUtil.isBoolean(valueType))
     736                        {
     737                            Tag select = filter.newTh().newSelect().setName(
     738                            name);
     739                            select.newOption().newCData("");
     740                            Tag yesOption = select.newOption()
     741                            .setValue("=true");
     742                            Tag noOption = select.newOption()
     743                            .setValue("=false");
     744                            if (inputValue.equals("=true"))
     745                            yesOption.setAttribute(selected);
     746                            else if (inputValue.equals("=false"))
     747                            noOption.setAttribute(selected);
     748                            yesOption.newCData("yes");
     749                            noOption.newCData("no");
     750                        }
     751                        else if (valueType.isEnum())
     752                        {
     753                            Tag select = filter.newTh().newSelect().setName(
     754                            name);
     755                            select.newOption().newCData("");
     756                            for (Object o : valueType.getEnumConstants())
     757                            {
     758                                try
     759                                {
     760                                    Method valueGetter = o.getClass()
     761                                    .getMethod("getValue");
     762                                    String enumValue = valueGetter.invoke(o
     763                                    ).toString();
     764                                    String label = o.toString();
     765                                    Tag option = select.newOption().setValue(
     766                                    enumValue);
     767                                    option.newCData(label);
     768                                    if (value.equals(enumValue))
     769                                    {
     770                                        option.setAttribute(selected);
     771                                    }
     772                                }
     773                                catch (SecurityException e)
     774                                {
     775                                    e.printStackTrace();
     776                                }
     777                                catch (NoSuchMethodException e)
     778                                {
     779                                    e.printStackTrace();
     780                                }
     781                                catch (IllegalArgumentException e)
     782                                {
     783                                    e.printStackTrace();
     784                                }
     785                                catch (IllegalAccessException e)
     786                                {
     787                                    e.printStackTrace();
     788                                }
     789                                catch (InvocationTargetException e)
     790                                {
     791                                    e.printStackTrace();
     792                                }
     793                            }
     794                        }
     795                        else
     796                        {
     797                            filter.newTh().newInput().setClass("filter")
     798                            .setSize(7).setName(name).setValue(
     799                            inputValue.replace('%', '*'));
     800                        }
     801                    }
     802                }
     803                else
     804                {
     805                    filter.newTh().newCData("&nbsp;");
     806                }
     807                if (!cols.hasNext())
     808                col.addClass("lastCol");
     809                // Add optional header action, e.g. for sorting
     810                AbstractLink link = c.getHeaderAction();
     811                if (link instanceof ActionLink)
     812                {
     813                    ActionLink headerAction = (ActionLink) link;
     814                    if (headerAction != null)
     815                    {
     816                        ActionLink hAction = new ActionLink(headerAction
     817                        .getLabel(), headerAction.getActionId());
     818                        List<Parameter> parameters = headerAction
     819                        .getParameters();
     820                        if (parameters != null)
     821                        {
     822                            // Add already defined parameters
     823                            for (Parameter param : parameters)
     824                            {
     825                                hAction.addParameter(param);
     826                            }
     827                        }
     828                        col.setOnClick(action2js(hAction, formId));
     829                        col.setClass("link");
     830                    }
     831                }
     832                header.add(col);
     833            }
     834        }
     835        // Convert rows
     836        Iterator<Row> rows = table.getRows().iterator();
     837        boolean noRows = true;
     838        while (rows.hasNext())
     839        {
     840            noRows = false;
     841            Row row = rows.next();
     842            Tr tr = null;
     843            tr = convert(row);
     844            tbl.add(tr);
     845            if (!rows.hasNext())
     846            {
     847                /*
     848                    * If last row is filter row, set noRows flag to display "Empty"
     849                    * message for data content.
     850                */
     851                if (row.getId().equals("-1"))
     852                {
     853                    noRows = true;
     854                }
     855                else
     856                {
     857                    tr.addClass("lastRow");
     858                }
     859            }
     860            if (useRowAction)
     861            {
     862                ActionLink rowAction = row.getActionLink();
     863                if (rowAction != null)
     864                {
     865                    tr.setOnClick(action2js(rowAction));
     866                    tr.addClass("hand");
     867                }
     868                String jsAction = row.getJsAction();
     869                if (jsAction != null)
     870                tr.setOnClick(jsAction);
     871            }
     872            if (row.isRemoved())
     873            tr.addClass("removed");
     874        }
     875        if (noRows)
     876        {
     877            tbl.newTr().addClass("lastRow").newTd().addClass("lastCol")
     878            .setAttribute(new Attribute("colspan", colspan)).newCData(
     879            "Empty");
     880        }
     881        if (scroller != null)
     882        tableLayout.add(convert(scroller, currentFormId));
     883        if (toolbar != null)
     884        currentFormTag.add(convert(toolbar, currentFormId));
     885        layout.newScript().newCData("initTable('" + table.getId() + "');");
     886        if (outerForm)
     887        {
     888            // Clear the current form tag so that subsequent converters do not
     889            // use this form
     890            currentFormTag = null;
     891            currentFormId = null;
     892        }
     893        return layout.getRoot();
     894    }
     895   
     896    public Tag convert(org.proteios.gui.table.FolderTable table)
     897    {
     898        String formId = "tableForm" + table.getId();
     899        Tag layout = hf.newLayoutDiv();
     900        Tag form = layout.newForm().setId(formId).setMethod("POST").setAction(
     901        contextPath);
     902        Toolbar tb = table.getToolbar();
     903        if (tb != null)
     904        {
     905            Input field = form.newInput().setId(formId + "action").setName(
     906            "action").setType("hidden");
     907            if (tb.getDefaultAction() != null)
     908            field.setValue(((ActionLink) tb.getDefaultAction())
     909            .getActionId());
     910        }
     911        Tag tblDiv = form.newDiv().setClass("table");
     912        tblDiv.add(hf.newBar().addClass("title").add(
     913        new CData(table.getTitle())));
     914        Tag tbl = tblDiv.newTable().setId(table.getId()).setCellSpacing(0)
     915        .setCellPadding(1).setAttribute(new Attribute("border", "0"));
     916        Tr header = tbl.newTr().setClass("header");
     917        Iterator<Column> cols = table.getHeader().iterator();
     918        while (cols.hasNext())
     919        {
     920            Tag col = convert(cols.next());
     921            header.add(col);
     922            if (!cols.hasNext())
     923            col.addClass("lastCol");
     924        }
     925        Iterator<TreeRow> rows = table.getRows().iterator();
     926        while (rows.hasNext())
     927        {
     928            TreeRow row = rows.next();
     929            Tr tr = null;
     930            // Convert row
     931            tr = convert(row);
     932            tbl.add(tr);
     933            if (!rows.hasNext())
     934            tr.addClass("lastRow");
     935        }
     936        if (tb != null)
     937        form.add(convert(tb, formId));
     938        tblDiv.newScript()
     939        .newCData(
     940        "initTreeTable('" + table.getId() + "', " + table
     941        .getFoldColumn() + ");");
     942        tblDiv.newScript().newCData("initTable('" + table.getId() + "');");
     943        return layout.getRoot();
     944    }
     945   
     946    public Tr convert(Row row)
     947    {
     948        Tr tr = new Tr().setId(row.getId());
     949        Set<String> tags = row.getTags();
     950        if(tags != null && tags.contains("shared"))
     951        {
     952            tr.addClass("shared");     
     953        }
     954        Iterator<Cell<?>> cells = row.getCells().iterator();
     955        while (cells.hasNext())
     956        {
     957            Tag td = convert(cells.next());
     958            tr.add(td);
     959            if (!cells.hasNext())
     960            td.addClass("lastCol");
     961        }
     962        return tr;
     963    }
     964   
     965    public Tr convert(TreeRow row)
     966    {
     967        Tr tr = new Tr().setId(row.getId()).setClass("L" + row.getLevel());
     968        ActionLink rowAction = row.getActionLink();
     969        if (rowAction != null)
     970        tr.setOnClick(action2js(rowAction));
     971        String jsAction = row.getJsAction();
     972        if (jsAction != null)
     973        tr.setOnClick(jsAction);
     974        Iterator<Cell<?>> cells = row.getCells().iterator();
     975        boolean first = true;
     976        while (cells.hasNext())
     977        {
     978            Cell<?> cell = cells.next();
     979            Tag td = convert(cell);
     980            if (first)
     981            {
     982                td.addClass(row.getIcon());
     983                first = false;
     984            }
     985            tr.add(td);
     986            if (!cells.hasNext())
     987            td.addClass("lastCol");
     988        }
     989        return tr;
     990    }
     991   
     992    public Tag convert(Separator sep)
     993    {
     994        return new Hr();
     995    }
     996   
     997    public <D extends Object> Tag convert(Cell<D> cell)
     998    {
     999        D value = cell.getValue();
     1000        if (value instanceof Checkbox)
     1001        {
     1002            Tag content = convert((Checkbox) value, false);
     1003            return new Td().add(content);
     1004        }
     1005        else if (value instanceof TextField)
     1006        {
     1007            TextField f = (TextField) value;
     1008            Input in = new Input().setName(f.getId()).setSize(10);
     1009            Object fvalue = f.getValue();
     1010            if (fvalue instanceof String)
     1011            {
     1012                in.setValue((String) fvalue);
     1013            }
     1014            else
     1015            {
     1016                in.setValue(fvalue.toString());
     1017            }
     1018            return new Td().add(in);
     1019        }
     1020        String strValue = "";
     1021        if (value instanceof Date)
     1022        {
     1023            // if hh:mm:ss is 00:00:00 then only display the date
     1024            strValue = formatter.format(cell.getValue());
     1025            strValue = strValue.replace(" 00:00:00", "");
     1026        }
     1027        else if (value instanceof Boolean)
     1028        {
     1029            strValue = ((Boolean) value) ? "yes" : "no";
     1030        }
     1031        else if (value != null)
     1032        {
     1033            strValue = String.valueOf(value);
     1034        }
     1035        // Fixes empty td tags displaying border
     1036        strValue = strValue + "&nbsp;";
     1037        Td td = new Td().add(new CData(strValue));
     1038        if (cell.isWrap())
     1039        td.addClass("nowrap");
     1040        // Action for this cell
     1041        AbstractLink cellAction = cell.getActionLink();
     1042        if (cellAction instanceof ActionLink)
     1043        {
     1044            if (cellAction != null)
     1045            {
     1046                td.setOnClick(action2js((ActionLink) cellAction));
     1047                td.setClass("link");
     1048            }
     1049            String jsAction = cell.getJsAction();
     1050            if (jsAction != null)
     1051            {
     1052                td.setOnClick(jsAction);
     1053                td.setClass("link");
     1054            }
     1055        }
     1056        else if (cellAction instanceof CrossLink)
     1057        {
     1058            CrossLink link = (CrossLink) cellAction;
     1059            ActionLink action = (ActionLink) link.getAction();
     1060            GUIElement gui = link.getGui();
     1061            if (gui instanceof org.proteios.gui.table.Table)
     1062            {
     1063                org.proteios.gui.table.Table table = (org.proteios.gui.table.Table) gui;
     1064                String formId = "formOf" + table.getId();
     1065                td.setOnClick(action2js(action, formId));
     1066                td.setClass("link");
     1067            }
     1068        }
     1069        return td;
     1070    }
     1071   
     1072    public Tag convert(Column col)
     1073    {
     1074        Th th = new Th();
     1075        if (col.isBigText())
     1076        th.setAttribute(new Attribute("width", "100%"));
     1077        th.add(new CData(locale.get(col.getValue()) + "&nbsp;"));
     1078        return th;
     1079    }
     1080   
     1081    public Tag convert(Column col, org.proteios.gui.table.Table table)
     1082    {
     1083        Th th = new Th();
     1084        if (col.isBigText())
     1085        {
     1086            th.setAttribute(new Attribute("width", "100%"));
     1087        }
     1088        if (col.isAsCheckBox())
     1089        {
     1090            Img icon = new Img();
     1091            icon.setSrc(imagePath + "/checkall.gif");
     1092            th.add(icon);
     1093            th.setOnClick("checkAllRowsInTable('formOf" + table.getId() + "')");
     1094        }
     1095        else
     1096        {
     1097            th.add(new CData(locale.get(col.getValue()) + "&nbsp;"));
     1098        }
     1099        return th;
     1100    }
     1101   
     1102    public Tag convert(Text txt)
     1103    {
     1104        Tag layout = hf.newTextArea();
     1105        Tag cdata = new CData(txt.getContent());
     1106        layout.add(cdata);
     1107        return layout;
     1108    }
     1109   
     1110    public Tag convert(TitledWindow win)
     1111    {
     1112        Tag window = new Div().setClass("titledWindow");
     1113        Tag title = new Div().addClass("title");
     1114        if (!win.isStatic())
     1115        {
     1116            window.addClass("popup");
     1117            window.newScript().newCData(
     1118            "Drag.init(getElement('" + getLastId() + "'));");
     1119            String id = getLastId();
     1120            title.newImg().setSrc(imagePath + (String) iconSet.get("Close"))
     1121            .setClass("close").setOnClick("closePopup('" + id + "')");
     1122        }
     1123        if (win.getTitle() != null)
     1124        {
     1125            title.add(new CData(
     1126            locale.get(win.getTitle().getTitle()) + "&nbsp;"));
     1127            String subtitle = win.getTitle().getSubtitle();
     1128            if (subtitle != null)
     1129            {
     1130                title.newCData(" - ");
     1131                title.newSpan().setClass("subtitle").newCData(subtitle);
     1132            }
     1133        }
     1134        window.add(title.getRoot());
     1135        GUIElement<?> contentG = win.getContent();
     1136        if (contentG != null)
     1137        {
     1138            // This is really not well designed but is necessary if the contentG
     1139            // is a table as the table converter puts the table inside any
     1140            // existing currentFormTag
     1141            Tag tmp = currentFormTag;
     1142            currentFormTag = window;
     1143            Tag content = contentG.convert(this);
     1144            currentFormTag.add(content.getRoot());
     1145            currentFormTag = tmp;
     1146        }
     1147        Toolbar tb = win.getToolbar();
     1148        if (tb != null)
     1149        window.add(convert(tb));
     1150        return window.getRoot();
     1151    }
     1152   
     1153    @SuppressWarnings("unused")
     1154    public Tag convert(Space space)
     1155    {
     1156        return new Div().setClass("space");
     1157    }
     1158   
     1159    public Tag convert(Message msg)
     1160    {
     1161        Tag layout = hf.newLayoutDiv().newDiv().setId("message");
     1162        layout.newCData(msg.getMessage());
     1163        return layout.getRoot();
     1164    }
     1165   
     1166    int idCounter = 0;
     1167    String lastId = "";
     1168   
     1169    public String nextId()
     1170    {
     1171        idCounter++;
     1172        lastId = "id" + idCounter;
     1173        return lastId;
     1174    }
     1175   
     1176    public String getLastId()
     1177    {
     1178        return lastId;
     1179    }
     1180   
     1181    public Tag convert(org.proteios.gui.Error err)
     1182    {
     1183        Tag layout = hf.newLayoutDiv().newDiv().setId("error");
     1184        layout.newCData(err.getError());
     1185        return layout.getRoot();
     1186    }
     1187   
     1188    public Tag convert(org.proteios.gui.form.Form w)
     1189    {
     1190        Tag layout;
     1191        boolean clearForm;
     1192        Toolbar tb;
     1193        Form form;
     1194        Input field;
     1195        AbstractLink defaultAction;
     1196       
     1197        layout = hf.newLayoutDiv();
     1198        clearForm = false;
     1199        if (currentFormTag == null)
     1200        {
     1201            clearForm = true;
     1202            currentFormTag = layout.newDiv().setClass("form").newForm().setId(
     1203            w.getId()).setMethod("POST").setAction(contextPath);
     1204            currentFormId = w.getId();
     1205            currentFormTag.add(new Input().setType("submit").setStyle(
     1206            "display: none"));
     1207        }
     1208        tb = w.getToolbar();
     1209        // This might cause a failure if the currentFormTag is not a Form
     1210        form = (Form) currentFormTag;
     1211        if (tb != null)
     1212        {
     1213            field = form.newInput().setId(w.getId() + "action").setName(
     1214            "action").setType("hidden");
     1215            if (tb.getDefaultAction() != null)
     1216            {
     1217                defaultAction = tb.getDefaultAction();
     1218                if (defaultAction instanceof ActionLink)
     1219                field.setValue(((ActionLink) defaultAction).getActionId());
     1220            }
     1221        }
     1222        List<org.proteios.gui.form.Fieldset> fieldsets = w.getFieldsets();
     1223        if (fieldsets != null)
     1224        {
     1225            for (org.proteios.gui.form.Fieldset fs : fieldsets)
     1226            {
     1227                Tag fieldset = convertFieldset(fs, form);
     1228                form.add(fieldset);
     1229            }
     1230        }
     1231        // Toolbar
     1232        if (tb != null)
     1233        layout.getRoot().add(convert(tb));
     1234        if (clearForm)
     1235        {
     1236            currentFormTag = null;
     1237            currentFormId = null;
     1238        }
     1239        return layout.getRoot();
     1240    }
     1241   
     1242    public Tag convert(org.proteios.gui.form.Fieldset fs)
     1243    {
     1244        return convertFieldset(fs, null);
     1245    }
     1246   
     1247    private int fieldsetId = 0;
     1248    private int nextFieldsetId() { fieldsetId++; return fieldsetId; }
    1091249
    110 import javax.servlet.http.HttpServletRequest;
     1250    private Tag convertFieldset(org.proteios.gui.form.Fieldset fs, Form form)
     1251    {
     1252        Fieldset fieldset;
     1253        Tag legend, title, fields, table, row, helpC, input, btn;       
     1254        String subtitle;
     1255        org.proteios.gui.form.Field field;
     1256        String id = "fs" + nextFieldsetId();
     1257      String btnId = "btn" + id;
     1258        fieldset = new Fieldset();
     1259        // Fieldset legend
     1260        legend = fieldset.newDiv().setClass("legend");
     1261        title = new Div().addClass("title");
     1262      legend.setOnClick("toggleFieldset('" + id + "')");   
     1263    btn = new Div();
     1264        btn.addClass("toggle");
     1265    btn.setId(btnId);
     1266    legend.add(btn);
     1267    btn.newCData( fs.isOpen() ? "-" : "+");
    1111268
    112 /**
    113  * Converts org.proteios.gui.* GUIElements to Tag objects
    114  *
    115  * @see HtmlFactory LayoutFactory
    116  * @author gregory
    117  */
    118 public class GUIConverter
    119     extends AbstractGUIConverter<Tag>
    120 {
    121   private final String contextPath;
    122   private HtmlFactory hf;
    123   private HttpServletRequest request = null;
    124   private final SimpleDateFormat formatter = new SimpleDateFormat(
    125     "yyyy-MM-dd HH:mm:ss");
    126   private String imagePath;
    127   private Localizer locale = null;
    128   private Properties iconSet = null;
    129   /**
    130    * This flag is used to tell converter methods not to generate it's own form
    131    * tag. Used e.g. when converting the table configuration content so that
    132    * the config fields are a part of the table form.
    133    */
    134   private Tag currentFormTag = null;
    135   private String currentFormId = null;
    136   private TypeUtil typeUtil = new TypeUtil();
    137 
    138 
    139   public HttpServletRequest getRequest()
    140   {
    141     return request;
    142   }
    143 
    144 
    145   public void setRequest(HttpServletRequest request)
    146   {
    147     this.request = request;
    148     hf.setRequest(request);
    149   }
    150 
    151 
    152   public GUIConverter(String contextPath)
    153   {
    154     super();
    155     this.contextPath = contextPath + "/app";
    156     this.imagePath = contextPath + "/static/img/";
    157     this.hf = new HtmlFactory(contextPath);
    158   }
    159 
    160   private Random r = new Random();
    161 
    162 
    163   public Tag convert(Image img)
    164   {
    165     ActionLink viewAction;
    166     String imgId, imgSrc, loadingImgSrc;
    167     Tag div, script;
    168     Img imgT;
    169     Boolean useFrame;
    170     // static source is used unless ViewAction is set
    171     imgId = "img" + r.nextInt(10);
    172     imgSrc = imagePath + img.getStaticSrc();
    173     viewAction = img.getViewAction();
    174     if (viewAction != null)
    175     {
    176       imgSrc = contextPath + "?action=" + img.getViewAction().toString();
    177     }
    178     loadingImgSrc = imagePath + "loading.gif";
    179     useFrame = img.getFramed();
    180     div = hf.newLayoutDiv();
    181     if (useFrame)
    182     {
    183       div.addClass("imageContainer");
    184       // If bot height and width are set use those
    185       if (img.getHeight() > 0 && img.getWidth() > 0)
    186         div
    187           .setStyle("height : " + img.getHeight() + "px; width : " + img
    188             .getWidth() + "px");
    189     }
    190     imgT = div.newImg().setId(imgId).setClass("image");
    191     // First we show the loading img
    192     imgT.setSrc(loadingImgSrc);
    193     //
    194     if (img.getImageMap() != null && img.getImageMap().getImageMapAreaList() != null)
    195     {
    196       String imageMapStr = "ImageMap" + imgId;
    197       imgT.setUsemap("#" + imageMapStr);
    198       // Create image map
    199       Map map = new Map();
    200       map.setParent(div);
    201       div.add(map);
    202       map.setName(imageMapStr);
    203       List<ImageMapArea> imageMapAreaList = img.getImageMap().getImageMapAreaList();
    204       for (int i = 0; i < imageMapAreaList.size(); i++)
    205       {
    206         // Get image map area data from image object
    207         ImageMapArea imageMapArea = (ImageMapArea) imageMapAreaList .get(i);
    208         int xTopLeft = imageMapArea.getXTopLeft();
    209         int yTopLeft = imageMapArea.getYTopLeft();
    210         int xBottomRight = imageMapArea.getXBottomRight();
    211         int yBottomRight = imageMapArea.getYBottomRight();
    212         String hrefStr = imageMapArea.getHrefStr();
    213         String toolTipStr = imageMapArea.getToolTipStr();
    214         String onMouseoverStr = null;
    215         String onMouseoutStr = null;
    216         if (toolTipStr != null && !toolTipStr.equals(""))
    217         {
    218           onMouseoverStr = new String("showtip(this,event,'" + toolTipStr + "')");
    219           onMouseoutStr = new String("hidetip()");
    220         }
    221         // Create new image map area
    222         Area area = new Area();
    223         area.setParent(map);
    224         map.add(area);
    225         area.setShape("RECT");
    226         area.setCoords(xTopLeft, yTopLeft, xBottomRight, yBottomRight);
    227         if (hrefStr != null && !hrefStr.equals(""))
    228         {
    229           area.setHref(hrefStr);
    230         }
    231         if (onMouseoverStr != null && !onMouseoverStr.equals(""))
    232         {
    233           area.setOnMousover(onMouseoverStr);
    234         }
    235         if (onMouseoutStr != null && !onMouseoutStr.equals(""))
    236         {
    237           area.setOnMousout(onMouseoutStr);
    238         }
    239       }
    240     }
    241     script = div.newScript();
    242     script.newCData("var " + imgId + " = new Image();");
    243     script.newCData(imgId + ".src = \"" + imgSrc + "\";");
    244     script.newCData("getElement('" + imgId + "').src = " + imgId + ".src;");
    245     return div;
    246   }
    247 
    248 
    249   public Tag convert(IFrame obj)
    250   {
    251     Tag tag = hf.newIFrame(obj);
    252     String src = contextPath + "?action=" + obj.getSrc().toString();
    253     tag.setAttribute(new Attribute("src", src));
    254     String id = this.nextId();
    255     tag.setId(id);
    256     tag
    257       .setAttribute(new Attribute("onload", "resize_iframe('" + id + "')"));
    258     return tag;
    259   }
    260 
    261 
    262   public Tag convert(Listing list)
    263   {
    264     Div layout = hf.newLayoutDiv();
    265     Div listing = layout.newDiv().setClass("listing");
    266     String title = list.getTitle();
    267     if (title != null)
    268     {
    269       listing.add(hf.newBar().addClass("title").add(
    270         new CData(locale.get(title) + "&nbsp;")));
    271     }
    272     List<ListItem> items = list.getItems();
    273     if (items.size() > 0)
    274     {
    275       Tag dl = new Dl();
    276       for (ListItem item : items)
    277       {
    278         Tag dt = dl.newDt();
    279         Tag dd = dl.newDd();
    280         if (item.getDate() != null)
    281         {
    282           String date = formatter.format(item.getDate());
    283           dt.newCData(date + " - ");
    284         }
    285         dt.newCData(item.getTitle());
    286         dd.newCData(item.getContent());
    287       }
    288       listing.add(dl);
    289     }
    290     else
    291     {
    292       listing.newDiv().setClass("empty").newCData("Empty");
    293     }
    294     return layout;
    295   }
    296 
    297 
    298   /**
    299    * @param action
    300    * @return goToLocation('action.toString()')
    301    */
    302   private String action2js(ActionLink action)
    303   {
    304     StringBuilder sb = new StringBuilder();
    305     if (action != null)
    306     {
    307       String jsMethod = "rightGo";
    308       sb.append(jsMethod + "('");
    309       sb.append(action.toString());
    310       sb.append("')");
    311     }
    312     return sb.toString();
    313   }
    314 
    315 
    316   public Tag convert(org.proteios.gui.TreeMenu menu)
    317   {
    318     Tag layout = new Div().setId("menuh-container").newDiv().setId("menuh");
    319     for (Node node : menu.getRoot().getChildNodes())
    320     {
    321       Tag top = new Ul();
    322       top.add(convert(node));
    323       layout.add(top);
    324     }
    325     return layout.getRoot();
    326   }
    327 
    328 
    329   public Tag convert(org.proteios.gui.MainMenu menu)
    330   {
    331     Tag div, ul;
    332 
    333     div = hf.newLayoutDiv();
    334     ul = convert((org.proteios.gui.TreeMenu) menu);
    335 
    336     div.add(ul);
    337     return div;
    338   }
    339 
    340 
    341   public String convert(ClosePopup button)
    342   {
    343     return "closeAllVisiblePopups()";
    344   }
    345 
    346 
    347   public Tag<?> convert(ActionLink pageLink, String formId, boolean localize)
    348   {
    349     String js = action2js(pageLink, formId);
    350     A tag = new A();
    351     tag.setHref(js);
    352     // Add the icon if any
    353     String icon = (String) iconSet.get(pageLink.getLabel());
    354     if (icon != null)
    355     {
    356       tag.newImg().setSrc(imagePath + icon);
    357     }
    358     String label = localize ? locale.get(pageLink.getLabel()) : pageLink
    359       .getLabel();
    360     tag.newCData(label);
    361     return tag;
    362   }
    363 
    364 
    365   /**
    366    * Converts an ActionLink such that each parameter of the ActionLink is a
    367    * call to the javascript method addField(formId, name, value) before adding
    368    * submitFormAs(formId, actionId)
    369    *
    370    * @param pageLink
    371    * @param formId
    372    * @return string of javascript code used in eg. href of a tags
    373    */
    374   private String action2js(ActionLink pageLink, String formId)
    375   {
    376     StringBuilder js = new StringBuilder();
    377     js.append("javascript:");
    378     List<Parameter> params = pageLink.getParameters();
    379     if (params != null)
    380     {
    381       for (Parameter param : params)
    382       {
    383         js.append("addField(");
    384         js.append("'");
    385         js.append(formId);
    386         js.append("','");
    387         js.append(param.name);
    388         js.append("','");
    389         js.append(param.value);
    390         js.append("');");
    391       }
    392     }
    393     js.append("submitFormAs('");
    394     js.append(formId);
    395     js.append("','");
    396     js.append(pageLink.getActionId());
    397     js.append("');");
    398     return js.toString();
    399   }
    400 
    401 
    402   public Tag convert(Scroller scroller, String formId)
    403   {
    404     Tag scrollBar = hf.newBar().addClass("scroller");
    405     // page links
    406     List<ActionLink> pageLinks = scroller.getPageLinks();
    407     for (int i = 0; i < pageLinks.size(); i++)
    408     {
    409       ActionLink pageLink = pageLinks.get(i);
    410       if (pageLink != null)
    411       {
    412         if (!pageLink.isSelected() && !pageLink.isDisabled())
    413         {
    414           // Link to back or forward page
    415           boolean localize = true;
    416           if (i > 1 && i < 7)
    417           {
    418             // Do not localize page numbers
    419             localize = false;
    420           }
    421           scrollBar.add(convert(pageLink, formId, false));
    422         }
    423         else
    424         {
    425           if (pageLink.isDisabled())
    426           {
    427             // Current page, text label only
    428             scrollBar.newSpan().setClass("disabled").newCData(
    429               pageLink.getLabel() + "&nbsp;");
    430           }
    431           else
    432           {
    433             scrollBar.newSpan().setClass("selected").newCData(
    434               pageLink.getLabel() + "&nbsp;");
    435           }
    436         }
    437       }
    438     }
    439     // Total number of items
    440     int total = scroller.getTotalCount();
    441     scrollBar.newBr();
    442     int from = scroller.getFrom();
    443     int to = from + scroller.getMax();
    444     if (to > total)
    445       to = total;
    446     from++; // As we start from 0
    447     scrollBar.newCData("Showing " + from + "-" + to + " of " + total);
    448     // Add rows/page field if table is controlled by ConfigureTableFactory2
    449     ActionLink configureTableAction = scroller.getTable()
    450       .getConfigureTableAction();
    451     if (configureTableAction != null && configureTableAction.getActionId()
    452       .equals("org.proteios.action.ConfigureTableFactory2"))
    453     {
    454       // Add number of rows per page field
    455       scrollBar.newCData("&nbsp;&nbsp;&nbsp;Rows/page ");
    456       scrollBar.newTh().newInput().setSize(3).setName(
    457         Scroller.VMAXRESULT.getName()).setValue(
    458         Integer.toString(scroller.getMax()));
    459     }
    460     // TODO gregory add Localizer to GUIConverter
    461     scrollBar.add(new CData("&nbsp;"));
    462     return scrollBar.getRoot();
    463   }
    464 
    465 
    466   /**
    467    * @param table to convert
    468    * @return root tag
    469    */
    470   public Tag convert(org.proteios.gui.table.Table table)
    471   {
    472     // <DIV class="layout"...
    473     Tag layout = hf.newLayoutDiv();
    474     // <FORM ...
    475     Scroller scroller = null;
    476     Toolbar toolbar = null;
    477     String formId = null;
    478     boolean outerForm = false;
    479     if (currentFormTag == null)
    480     {
    481       outerForm = true;
    482       formId = "formOf" + table.getId();
    483       currentFormId = formId;
    484       currentFormTag = layout.newForm().setId(formId).setMethod("POST")
    485         .setAction(contextPath);
    486       // Add hidden submit button
    487       currentFormTag.newInput().setType("submit").setClass("hidden");
    488       // Add hidden action field and set the default action
    489       toolbar = table.getToolbar();
    490       if (toolbar != null)
    491       {
    492         Input field = currentFormTag.newInput()
    493           .setId(formId + "action").setName("action").setType(
    494             "hidden");
    495         if (toolbar.getDefaultAction() != null)
    496         {
    497           AbstractLink defaultLink = toolbar.getDefaultAction();
    498           if (defaultLink != null && ActionLink.class
    499             .isAssignableFrom(defaultLink.getClass()))
    500           {
    501             field
    502               .setValue(((ActionLink) defaultLink).getActionId());
    503           }
    504         }
    505 
    506       }
    507       scroller = table.getScroller();
    508       List<TextField<?>> hiddenFields = table.getHiddenFields();
    509       if (hiddenFields != null && hiddenFields.size() > 0)
    510       {
    511         for (TextField<?> f : hiddenFields)
    512         {
    513           currentFormTag.add(convert(f));
    514         }
    515       }
    516     }
    517     else
    518     {
    519       formId = currentFormId;
    520       toolbar = table.getToolbar();
    521     }
    522     // <DIV class="table" ...
    523     Tag tableLayout = currentFormTag.newDiv().setClass("table");
    524     // Table title
    525     String title = table.getTitle();
    526     String subtitle = table.getSubtitle();
    527     Tag titleBar = hf.newBar();
    528     ActionLink configureTableAction = table.getConfigureTableAction();
    529     // Table configuration popup
    530     if (title != null)
    531     {
    532       if (configureTableAction != null && configureTableAction
    533         .getActionId().equals(
    534           "org.proteios.action.ConfigureTableFactory2"))
    535       {
    536         // Add the icon only if there is a GUI to display
    537         Img configIcon = new Img().setSrc(imagePath + "/columns.gif")
    538           .setClass("tableConfigIcon");
    539         String id = nextId();
    540     A options = new A();
    541     options.setStyle("float:right; font-size: 0.9em; text-decoration: none");
    542     options.newCData("Table Options");
    543     options.setHref("javascript:popup('" + id + "')");
    544         configIcon.setOnClick("popup('" + id + "')");
    545         // Insert the popup div inside the form tag
    546         Div popupLayout = currentFormTag.newDiv().setClass(
    547           "popupLayout").setId(id);
    548         TitledWindow tw = new TitledWindow("TableOptions");
    549         tw.setStatic(false);
    550         Tag popContent = convert(tw);
    551         popupLayout.add(popContent);
    552         // Header
    553         Tag tbl = popContent.newDiv().setClass("table").newDiv()
    554           .setClass("tableContent").newTable().setCellPadding(1)
    555           .setCellSpacing(0);
    556         Tag trh = tbl.newTr();
    557         trh.newTh().newCData(locale.get("Show"));
    558         trh.newTh().newCData(locale.get("ColumnDisplayOrder"));
    559         trh.newTh().newCData(locale.get("OrderBy"));
    560         trh.newTh().newCData(locale.get("ColumnSortPriority"));
    561         trh.newTh().newCData(locale.get("Column"));
    562         // Toolbar
    563         titleBar.add(configIcon);
    564         titleBar.add(options);
    565         // Table configuration updated flag set to "true"
    566         Input tableConfigurationUpdatedField = trh.newInput().
    567           setName("tableConfigurationUpdated").setType("hidden");
    568         tableConfigurationUpdatedField.setValue("true");
    569         // Get number of potential sort columns
    570         int nSortColumns = 0;
    571         for (Column col : table.getHeader())
    572         {
    573           AttributeDefinition ad = col.getAttributeDefinition();
    574           if (ad != null)
    575           {
    576             if (col.getDisplayFilter())
    577             {
    578               nSortColumns++;
    579             }
    580           }
    581         }
    582         // Add column selection here
    583     boolean firstColumnIsIdColumn = false; // Used below to indicate if 'Id' is part of the header
    584       int nColumns = table.getHeader().size();
    585         for (Column col : table.getHeader())
    586         {
    587           AttributeDefinition ad = col.getAttributeDefinition();
    588           if (ad != null)
    589           {
    590             Tr tr = tbl.newTr();
    591             // Show
    592             Input inputTag = tr.newTd().newInput().setType(
    593               "checkbox").setName("show" + ad.getKey());
    594             if (col.isVisible())
    595               inputTag.setAttribute(new Attribute("checked",
    596                 "checked"));
    597             // Column display order select box
    598             Integer colDisplayOrder = col.getDisplayOrder();
    599 
    600       if (ad.getKey().equals("Id"))
    601             {
    602               // Disable display order select box for "Id" column
    603               tr.newTd().newCData("" + colDisplayOrder + "&nbsp;");
    604        firstColumnIsIdColumn = true;
    605             }
    606             else
    607             {
    608               // Add display order select box for other columns
    609        Tag displayOrderSelectBox = new Select().setName("displayOrder" + ad.getKey());
    610        for (int i=0; i < nColumns; i++)
    611              {
    612                 int displayOrderValue = i + 1;
    613                 // If first column is "Id" column, reserve this position
    614                 if (!firstColumnIsIdColumn || displayOrderValue > 1)
    615                 {
    616                   String displayOrderValueStr = "" + displayOrderValue;
    617                   Option displayOrderOption = displayOrderSelectBox.newOption().setValue(displayOrderValueStr);
    618                   displayOrderOption.newCData(displayOrderValueStr);
    619                   if (colDisplayOrder != null && colDisplayOrder == displayOrderValue)
    620                   {
    621                     displayOrderOption.select();
    622                   }
    623                 }
    624              }
    625               tr.newTd().add(displayOrderSelectBox);
    626             }
    627            
    628            
    629             // Order by
    630             if (col.getDisplayFilter())
    631             {
    632               Tag s = new Select().setName("orderBy" + ad
    633                 .getKey());
    634               Option def = s.newOption().setValue("");
    635               def.newCData("&nbsp;");
    636               Option asc = s.newOption().setValue("asc");
    637               asc.newCData("asc");
    638               Option desc = s.newOption().setValue("desc");
    639               desc.newCData("desc");
    640               if (col.getOrder() == null)
    641               {
    642                 def.select();
    643               }
    644               else if (col.getOrder().equals(SortOrder.ASC))
    645               {
    646                 asc.select();
    647               }
    648               else if (col.getOrder().equals(SortOrder.DESC))
    649               {
    650                 desc.select();
    651               }
    652               tr.newTd().add(s);
    653             }
    654             else
    655             {
    656               tr.newTd().newCData("&nbsp;");
    657             }
    658             // Column sort priority
    659             if (col.getDisplayFilter())
    660             {
    661               // Sort priority select box
    662               Tag s = new Select().setName("sortPriority" + ad
    663                 .getKey());
    664               Option def = s.newOption().setValue("");
    665               def.newCData("&nbsp;");
    666               Integer colSortPriority = col.getSortPriority();
    667               if (colSortPriority == null)
    668               {
    669                 def.select();
    670               }
    671               for (int i=0; i < nSortColumns; i++)
    672               {
    673                 int sortPriorityValue = i + 1;
    674                 String sortPriorityValueStr = "" + sortPriorityValue;
    675                 Option sortPriorityOption = s.newOption().setValue(sortPriorityValueStr);
    676                 sortPriorityOption.newCData(sortPriorityValueStr);
    677                 if (colSortPriority != null && colSortPriority == sortPriorityValue)
    678                 {
    679                   sortPriorityOption.select();
    680                 }
    681               }
    682               tr.newTd().add(s);
    683             }
    684             else
    685             {
    686               tr.newTd().newCData("&nbsp;");
    687             }
    688             // Column name
    689             tr.newTd().setAttribute(new Attribute("width", "100%"))
    690               .newCData(locale.get(col.getValue()));
    691           }
    692         }
    693         Tag popToolbar = popContent.newDiv().setClass("toolbar");
    694         Tag ul = popToolbar.newUl();
    695         ul
    696           .newLi()
    697           .setOnClick(
    698             "submitFormAs('" + formId + "','org.proteios.action.ConfigureTableFactory2')")
    699           .newCData(locale.get("Apply"));
    700       }
    701     }
    702     // End table configuration
    703     if (title != null)
    704     {
    705       tableLayout.add(titleBar.addClass("title").add(
    706         new CData(locale.get(title) + "&nbsp;")));
    707       if (subtitle != null)
    708       {
    709         titleBar.newCData(" - ");
    710         titleBar.newSpan().setClass("subtitle").newCData(subtitle);
    711       }
    712     }
    713     // <DIV>
    714     Tag tableContent = tableLayout.newDiv().setClass("tableContent");
    715     // <TABLE ...
    716     Tag tbl = new Table().setId(table.getId()).setCellSpacing(0)
    717       .setCellPadding(1).setAttribute(new Attribute("border", "0"))
    718       .setAttribute(new Attribute("width", "100%"));
    719     tableContent.add(tbl);
    720     Tr header = tbl.newTr().setClass("header");
    721     Tr filter = tbl.newTr().setClass("filter").addClass("header");
    722     Iterator<Column> cols = table.getHeader().iterator();
    723     int colspan = 0;
    724     boolean useRowAction = true;
    725     Attribute selected = new Attribute("selected", "selected");
    726     while (cols.hasNext())
    727     {
    728       colspan++;
    729       Column c = cols.next();
    730       if (c.isVisible())
    731       {
    732         if (c.getAction() != null)
    733           useRowAction = false;
    734         Tag col = convert(c, table);
    735         String operator = "";
    736         String value = "";
    737         Filter f = c.getFilter();
    738         if (c.getDisplayFilter())
    739         {
    740           if (f != null)
    741           {
    742             operator = f.getOperator().getSymbol();
    743             value = f.getValue().toString();
    744           }
    745           AttributeDefinition ad = c.getAttributeDefinition();
    746           if (ad != null)
    747           {
    748             Class<?> valueType = ad.getAttributeType();
    749             String name = "where" + ad.getKey();
    750             String inputValue = operator + value;
    751             if (operator.equals(Operator.LIKE.getSymbol()))
    752               inputValue = Operator.EQ.getSymbol() + value;
    753             if (typeUtil.isBoolean(valueType))
    754             {
    755               Tag select = filter.newTh().newSelect().setName(
    756                 name);
    757               select.newOption().newCData("");
    758               Tag yesOption = select.newOption()
    759                 .setValue("=true");
    760               Tag noOption = select.newOption()
    761                 .setValue("=false");
    762               if (inputValue.equals("=true"))
    763                 yesOption.setAttribute(selected);
    764               else if (inputValue.equals("=false"))
    765                 noOption.setAttribute(selected);
    766               yesOption.newCData("yes");
    767               noOption.newCData("no");
    768             }
    769             else if (valueType.isEnum())
    770             {
    771               Tag select = filter.newTh().newSelect().setName(
    772                 name);
    773               select.newOption().newCData("");
    774               for (Object o : valueType.getEnumConstants())
    775               {
    776                 try
    777                 {
    778                   Method valueGetter = o.getClass()
    779                     .getMethod("getValue");
    780                   String enumValue = valueGetter.invoke(o
    781                     ).toString();
    782                   String label = o.toString();
    783                   Tag option = select.newOption().setValue(
    784                     enumValue);
    785                   option.newCData(label);
    786                   if (value.equals(enumValue))
    787                   {
    788                     option.setAttribute(selected);
    789                   }
    790                 }
    791                 catch (SecurityException e)
    792                 {
    793                   e.printStackTrace();
    794                 }
    795                 catch (NoSuchMethodException e)
    796                 {
    797                   e.printStackTrace();
    798                 }
    799                 catch (IllegalArgumentException e)
    800                 {
    801                   e.printStackTrace();
    802                 }
    803                 catch (IllegalAccessException e)
    804                 {
    805                   e.printStackTrace();
    806                 }
    807                 catch (InvocationTargetException e)
    808                 {
    809                   e.printStackTrace();
    810                 }
    811               }
    812             }
    813             else
    814             {
    815               filter.newTh().newInput().setClass("filter")
    816                 .setSize(7).setName(name).setValue(
    817                   inputValue.replace('%', '*'));
    818             }
    819           }
    820         }
    821         else
    822         {
    823           filter.newTh().newCData("&nbsp;");
    824         }
    825         if (!cols.hasNext())
    826           col.addClass("lastCol");
    827         // Add optional header action, e.g. for sorting
    828         AbstractLink link = c.getHeaderAction();
    829         if (link instanceof ActionLink)
    830         {
    831           ActionLink headerAction = (ActionLink) link;
    832           if (headerAction != null)
    833           {
    834             ActionLink hAction = new ActionLink(headerAction
    835               .getLabel(), headerAction.getActionId());
    836             List<Parameter> parameters = headerAction
    837               .getParameters();
    838             if (parameters != null)
    839             {
    840               // Add already defined parameters
    841               for (Parameter param : parameters)
    842               {
    843                 hAction.addParameter(param);
    844               }
    845             }
    846             col.setOnClick(action2js(hAction, formId));
    847             col.setClass("link");
    848           }
    849         }
    850         header.add(col);
    851       }
    852     }
    853     // Convert rows
    854     Iterator<Row> rows = table.getRows().iterator();
    855     boolean noRows = true;
    856     while (rows.hasNext())
    857     {
    858       noRows = false;
    859       Row row = rows.next();
    860       Tr tr = null;
    861       tr = convert(row);
    862       tbl.add(tr);
    863       if (!rows.hasNext())
    864       {
    865         /*
    866          * If last row is filter row, set noRows flag to display "Empty"
    867          * message for data content.
    868          */
    869         if (row.getId().equals("-1"))
    870         {
    871           noRows = true;
    872         }
    873         else
    874         {
    875           tr.addClass("lastRow");
    876         }
    877       }
    878       if (useRowAction)
    879       {
    880         ActionLink rowAction = row.getActionLink();
    881         if (rowAction != null)
    882         {
    883           tr.setOnClick(action2js(rowAction));
    884           tr.addClass("hand");
    885         }
    886         String jsAction = row.getJsAction();
    887         if (jsAction != null)
    888           tr.setOnClick(jsAction);
    889       }
    890       if (row.isRemoved())
    891         tr.addClass("removed");
    892     }
    893     if (noRows)
    894     {
    895       tbl.newTr().addClass("lastRow").newTd().addClass("lastCol")
    896         .setAttribute(new Attribute("colspan", colspan)).newCData(
    897           "Empty");
    898     }
    899     if (scroller != null)
    900       tableLayout.add(convert(scroller, currentFormId));
    901     if (toolbar != null)
    902       currentFormTag.add(convert(toolbar, currentFormId));
    903     layout.newScript().newCData("initTable('" + table.getId() + "');");
    904     if (outerForm)
    905     {
    906       // Clear the current form tag so that subsequent converters do not
    907       // use this form
    908       currentFormTag = null;
    909       currentFormId = null;
    910     }
    911     return layout.getRoot();
    912   }
    913 
    914 
    915   public Tag convert(org.proteios.gui.table.FolderTable table)
    916   {
    917     String formId = "tableForm" + table.getId();
    918     Tag layout = hf.newLayoutDiv();
    919     Tag form = layout.newForm().setId(formId).setMethod("POST").setAction(
    920       contextPath);
    921     Toolbar tb = table.getToolbar();
    922     if (tb != null)
    923     {
    924       Input field = form.newInput().setId(formId + "action").setName(
    925         "action").setType("hidden");
    926       if (tb.getDefaultAction() != null)
    927         field.setValue(((ActionLink) tb.getDefaultAction())
    928           .getActionId());
    929     }
    930     Tag tblDiv = form.newDiv().setClass("table");
    931     tblDiv.add(hf.newBar().addClass("title").add(
    932       new CData(table.getTitle())));
    933     Tag tbl = tblDiv.newTable().setId(table.getId()).setCellSpacing(0)
    934       .setCellPadding(1).setAttribute(new Attribute("border", "0"));
    935     Tr header = tbl.newTr().setClass("header");
    936     Iterator<Column> cols = table.getHeader().iterator();
    937     while (cols.hasNext())
    938     {
    939       Tag col = convert(cols.next());
    940       header.add(col);
    941       if (!cols.hasNext())
    942         col.addClass("lastCol");
    943     }
    944     Iterator<TreeRow> rows = table.getRows().iterator();
    945     while (rows.hasNext())
    946     {
    947       TreeRow row = rows.next();
    948       Tr tr = null;
    949       // Convert row
    950       tr = convert(row);
    951       tbl.add(tr);
    952       if (!rows.hasNext())
    953         tr.addClass("lastRow");
    954     }
    955     if (tb != null)
    956       form.add(convert(tb, formId));
    957     tblDiv.newScript()
    958       .newCData(
    959         "initTreeTable('" + table.getId() + "', " + table
    960           .getFoldColumn() + ");");
    961     tblDiv.newScript().newCData("initTable('" + table.getId() + "');");
    962     return layout.getRoot();
    963   }
    964 
    965 
    966   public Tr convert(Row row)
    967   {
    968     Tr tr = new Tr().setId(row.getId());
    969     Set<String> tags = row.getTags();
    970     if(tags != null && tags.contains("shared"))
    971     {
    972       tr.addClass("shared");     
    973     }
    974     Iterator<Cell<?>> cells = row.getCells().iterator();
    975     while (cells.hasNext())
    976     {
    977       Tag td = convert(cells.next());
    978       tr.add(td);
    979       if (!cells.hasNext())
    980         td.addClass("lastCol");
    981     }
    982     return tr;
    983   }
    984 
    985 
    986   public Tr convert(TreeRow row)
    987   {
    988     Tr tr = new Tr().setId(row.getId()).setClass("L" + row.getLevel());
    989     ActionLink rowAction = row.getActionLink();
    990     if (rowAction != null)
    991       tr.setOnClick(action2js(rowAction));
    992     String jsAction = row.getJsAction();
    993     if (jsAction != null)
    994       tr.setOnClick(jsAction);
    995     Iterator<Cell<?>> cells = row.getCells().iterator();
    996     boolean first = true;
    997     while (cells.hasNext())
    998     {
    999       Cell<?> cell = cells.next();
    1000       Tag td = convert(cell);
    1001       if (first)
    1002       {
    1003         td.addClass(row.getIcon());
    1004         first = false;
    1005       }
    1006       tr.add(td);
    1007       if (!cells.hasNext())
    1008         td.addClass("lastCol");
    1009     }
    1010     return tr;
    1011   }
    1012 
    1013 
    1014   public Tag convert(Separator sep)
    1015   {
    1016     return new Hr();
    1017   }
    1018 
    1019 
    1020   public <D extends Object> Tag convert(Cell<D> cell)
    1021   {
    1022     D value = cell.getValue();
    1023     if (value instanceof Checkbox)
    1024     {
    1025       Tag content = convert((Checkbox) value, false);
    1026       return new Td().add(content);
    1027     }
    1028     else if (value instanceof TextField)
    1029     {
    1030       TextField f = (TextField) value;
    1031       Input in = new Input().setName(f.getId()).setSize(10);
    1032       Object fvalue = f.getValue();
    1033       if (fvalue instanceof String)
    1034       {
    1035         in.setValue((String) fvalue);
    1036       }
    1037       else
    1038       {
    1039         in.setValue(fvalue.toString());
    1040       }
    1041       return new Td().add(in);
    1042     }
    1043     String strValue = "";
    1044     if (value instanceof Date)
    1045     {
    1046       // if hh:mm:ss is 00:00:00 then only display the date
    1047       strValue = formatter.format(cell.getValue());
    1048       strValue = strValue.replace(" 00:00:00", "");
    1049     }
    1050     else if (value instanceof Boolean)
    1051     {
    1052       strValue = ((Boolean) value) ? "yes" : "no";
    1053     }
    1054     else if (value != null)
    1055     {
    1056       strValue = String.valueOf(value);
    1057     }
    1058     // Fixes empty td tags displaying border
    1059     strValue = strValue + "&nbsp;";
    1060     Td td = new Td().add(new CData(strValue));
    1061     if (cell.isWrap())
    1062       td.addClass("nowrap");
    1063     // Action for this cell
    1064     AbstractLink cellAction = cell.getActionLink();
    1065     if (cellAction instanceof ActionLink)
    1066     {
    1067       if (cellAction != null)
    1068       {
    1069         td.setOnClick(action2js((ActionLink) cellAction));
    1070         td.setClass("link");
    1071       }
    1072       String jsAction = cell.getJsAction();
    1073       if (jsAction != null)
    1074       {
    1075         td.setOnClick(jsAction);
    1076         td.setClass("link");
    1077       }
    1078     }
    1079     else if (cellAction instanceof CrossLink)
    1080     {
    1081       CrossLink link = (CrossLink) cellAction;
    1082       ActionLink action = (ActionLink) link.getAction();
    1083       GUIElement gui = link.getGui();
    1084       if (gui instanceof org.proteios.gui.table.Table)
    1085       {
    1086         org.proteios.gui.table.Table table = (org.proteios.gui.table.Table) gui;
    1087         String formId = "formOf" + table.getId();
    1088         td.setOnClick(action2js(action, formId));
    1089         td.setClass("link");
    1090       }
    1091     }
    1092     return td;
    1093   }
    1094 
    1095 
    1096   public Tag convert(Column col)
    1097   {
    1098     Th th = new Th();
    1099     if (col.isBigText())
    1100       th.setAttribute(new Attribute("width", "100%"));
    1101     th.add(new CData(locale.get(col.getValue()) + "&nbsp;"));
    1102     return th;
    1103   }
    1104 
    1105 
    1106   public Tag convert(Column col, org.proteios.gui.table.Table table)
    1107   {
    1108     Th th = new Th();
    1109     if (col.isBigText())
    1110     {
    1111       th.setAttribute(new Attribute("width", "100%"));
    1112     }
    1113     if (col.isAsCheckBox())
    1114     {
    1115       Img icon = new Img();
    1116       icon.setSrc(imagePath + "/checkall.gif");
    1117       th.add(icon);
    1118       th.setOnClick("checkAllRowsInTable('formOf" + table.getId() + "')");
    1119     }
    1120     else
    1121     {
    1122       th.add(new CData(locale.get(col.getValue()) + "&nbsp;"));
    1123     }
    1124     return th;
    1125   }
    1126 
    1127 
    1128   public Tag convert(Text txt)
    1129   {
    1130     Tag layout = hf.newTextArea();
    1131     Tag cdata = new CData(txt.getContent());
    1132     layout.add(cdata);
    1133     return layout;
    1134   }
    1135 
    1136 
    1137   public Tag convert(TitledWindow win)
    1138   {
    1139     Tag window = new Div().setClass("titledWindow");
    1140     Tag title = new Div().addClass("title");
    1141     if (!win.isStatic())
    1142     {
    1143       window.addClass("popup");
    1144       window.newScript().newCData(
    1145         "Drag.init(getElement('" + getLastId() + "'));");
    1146       String id = getLastId();
    1147       title.newImg().setSrc(imagePath + (String) iconSet.get("Close"))
    1148         .setClass("close").setOnClick("closePopup('" + id + "')");
    1149     }
    1150     if (win.getTitle() != null)
    1151     {
    1152       title.add(new CData(
    1153         locale.get(win.getTitle().getTitle()) + "&nbsp;"));
    1154       String subtitle = win.getTitle().getSubtitle();
    1155       if (subtitle != null)
    1156       {
    1157         title.newCData(" - ");
    1158         title.newSpan().setClass("subtitle").newCData(subtitle);
    1159       }
    1160     }
    1161     window.add(title.getRoot());
    1162     GUIElement<?> contentG = win.getContent();
    1163     if (contentG != null)
    1164     {
    1165       // This is really not well designed but is necessary if the contentG
    1166       // is a table as the table converter puts the table inside any
    1167       // existing currentFormTag
    1168       Tag tmp = currentFormTag;
    1169       currentFormTag = window;
    1170       Tag content = contentG.convert(this);
    1171       currentFormTag.add(content.getRoot());
    1172       currentFormTag = tmp;
    1173     }
    1174     Toolbar tb = win.getToolbar();
    1175     if (tb != null)
    1176       window.add(convert(tb));
    1177     return window.getRoot();
    1178   }
    1179 
    1180 
    1181   @SuppressWarnings("unused")
    1182   public Tag convert(Space space)
    1183   {
    1184     return new Div().setClass("space");
    1185   }
    1186 
    1187 
    1188   public Tag convert(Message msg)
    1189   {
    1190     Tag layout = hf.newLayoutDiv().newDiv().setId("message");
    1191     layout.newCData(msg.getMessage());
    1192     return layout.getRoot();
    1193   }
    1194 
    1195   int idCounter = 0;
    1196   String lastId = "";
    1197 
    1198 
    1199   public String nextId()
    1200   {
    1201     idCounter++;
    1202     lastId = "id" + idCounter;
    1203     return lastId;
    1204   }
    1205 
    1206 
    1207   public String getLastId()
    1208   {
    1209     return lastId;
    1210   }
    1211 
    1212 
    1213   public Tag convert(org.proteios.gui.Error err)
    1214   {
    1215     Tag layout = hf.newLayoutDiv().newDiv().setId("error");
    1216     layout.newCData(err.getError());
    1217     return layout.getRoot();
    1218   }
    1219 
    1220 
    1221   public Tag convert(org.proteios.gui.form.Form w)
    1222   {
    1223   Tag layout;
    1224   boolean clearForm;
    1225   Toolbar tb;
    1226   Form form;
    1227   Input field;
    1228   AbstractLink defaultAction;
    1229 
    1230     layout = hf.newLayoutDiv();
    1231     clearForm = false;
    1232     if (currentFormTag == null)
    1233     {
    1234       clearForm = true;
    1235       currentFormTag = layout.newDiv().setClass("form").newForm().setId(
    1236         w.getId()).setMethod("POST").setAction(contextPath);
    1237       currentFormId = w.getId();
    1238       currentFormTag.add(new Input().setType("submit").setStyle(
    1239         "display: none"));
    1240     }
    1241     tb = w.getToolbar();
    1242     // This might cause a failure if the currentFormTag is not a Form
    1243     form = (Form) currentFormTag;
    1244     if (tb != null)
    1245     {
    1246       field = form.newInput().setId(w.getId() + "action").setName(
    1247         "action").setType("hidden");
    1248       if (tb.getDefaultAction() != null)
    1249       {
    1250         defaultAction = tb.getDefaultAction();
    1251         if (defaultAction instanceof ActionLink)
    1252           field.setValue(((ActionLink) defaultAction).getActionId());
    1253       }
    1254     }
    1255     List<org.proteios.gui.form.Fieldset> fieldsets = w.getFieldsets();
    1256     if (fieldsets != null)
    1257     {
    1258       for (org.proteios.gui.form.Fieldset fs : fieldsets)
    1259       {
    1260         Tag fieldset = convertFieldset(fs, form);
    1261         form.add(fieldset);
    1262       }
    1263     }
    1264     // Toolbar
    1265     if (tb != null)
    1266       layout.getRoot().add(convert(tb));
    1267     if (clearForm)
    1268     {
    1269       currentFormTag = null;
    1270       currentFormId = null;
    1271     }
    1272     return layout.getRoot();
    1273   }
    1274 
    1275 
    1276   public Tag convert(org.proteios.gui.form.Fieldset fs)
    1277   {
    1278     return convertFieldset(fs, null);
    1279   }
    1280 
    1281 
    1282   private Tag convertFieldset(org.proteios.gui.form.Fieldset fs, Form form)
    1283   {
    1284     Fieldset fieldset;
    1285   Tag legend, title, fields, table, row, helpC, input;
    1286   String subtitle;
    1287   org.proteios.gui.form.Field field;
    1288 
    1289   fieldset = new Fieldset();
    1290     // Fieldset legend
    1291     legend = fieldset.newDiv().setClass("legend");
    1292     title = new Div().addClass("title");
    1293     if (fs.getTitle()!= null)
    1294     {
    1295       title.add(new CData(
    1296         locale.get(fs.getTitle().getTitle()) + "&nbsp;"));
    1297       subtitle = fs.getTitle().getSubtitle();
    1298       if (subtitle != null)
    1299       {
    1300         title.newCData(" - ");
    1301         title.newSpan().setClass("subtitle").newCData(subtitle);
    1302       }
    1303     }
    1304     legend.add(title.getRoot());
    1305 
    1306     fields = fieldset.newDiv().setClass("fields");
    1307   table = fields.newTable();
    1308     for (org.proteios.gui.GUIElement f : fs.getFields())
    1309     {
    1310    row = table.newTr();
    1311    // Label cell
    1312    if(f instanceof org.proteios.gui.form.Field)
    1313    {
    1314     field = (org.proteios.gui.form.Field) f;
    1315     row.newTd().addClass("label").newCData(locale.get(field.getLabel()));
    1316     input = null;
    1317     // Field cell
    1318       if (f instanceof TextField)
    1319       {
    1320      input = convert((TextField<?>) f);
    1321      if(((TextField<?>)field).isHidden())
    1322      {
    1323       row.addClass("hidden");
    1324      }
    1325       }
    1326     else if (f instanceof PasswordField)
    1327       {
    1328         input = convert((PasswordField) f);
    1329       }
    1330       else if (f instanceof FileField)
    1331       {
    1332         if (form != null)
    1333       {
    1334           form.setMultipart();
    1335      }
    1336         input = convert((FileField) f);
    1337       }
    1338       else if (f instanceof TextArea)
    1339       {
    1340         input = convert((TextArea) f);
    1341       }
    1342       else if (f instanceof org.proteios.gui.form.Select)
    1343       {
    1344         input = convert((org.proteios.gui.form.Select) f);
    1345       }
    1346       else if (f instanceof org.proteios.gui.form.Checkbox)
    1347       {
    1348         input = convert((org.proteios.gui.form.Checkbox) f, false);
    1349       }
    1350    
    1351       if (field.getParam().isRequired() ||
    1352         (field.getParam() instanceof VString && ((VString) field.getParam()).getMinCharacterLength() > 0))
    1353       {
    1354       input.addClass("required");
    1355     }
    1356     if(input != null)
    1357     {
    1358      row.newTd().add(input);
    1359     }
    1360 
    1361     // Help and error field
    1362     helpC = row.newTd();
    1363     helpC.newDiv().addClass("error").add(hf.getFieldError(field));
    1364     helpC.newDiv().addClass("help").newCData(field.getHelp());
    1365    }
    1366       if (f instanceof org.proteios.gui.table.Table)
    1367       {
    1368         row.newTd().add(convert((org.proteios.gui.table.Table) f));
    1369       }
    1370    
    1371     }
    1372     return fieldset;
    1373   }
    1374 
    1375 
    1376   private Tag convert(FileField f)
    1377   {
    1378     Input in = new Input().setId(f.getId()).setName(f.getId()).setType(
    1379       "file");
    1380     if (f.getValue() != null)
    1381       in.setValue(f.getValue().toString());
    1382     if (f.isDisabled())
    1383       in.disable();
    1384     return in;
    1385   }
    1386 
    1387 
    1388 
    1389   public Tag convert(org.proteios.gui.form.Select<?> select)
    1390   {
    1391     Tag field = new CData("");
    1392     Select selectTag = field.newSelect().setId(select.getId()).setName(
    1393       select.getName());
    1394     // Use multiple selection box if isMultiple() == true
    1395     if (select.isMultiple() != null && select.isMultiple())
    1396     {
    1397       selectTag.setAttribute(new Attribute("multiple", ""));
    1398     }
    1399     // Set number of visible items if getSize() != null
    1400     if (select.getSize() != null)
    1401     {
    1402       selectTag.setAttribute(new Attribute("size", select.getSize()
    1403         .toString()));
    1404     }
    1405     if (select.isDisabled())
    1406     {
    1407       selectTag.setAttribute(new Attribute("disabled", "disabled"));
    1408       selectTag.addClass("disable");
    1409       Input hiddenF = field.newInput().setId(select.getId()).setName(
    1410         select.getName()).setType("hidden");
    1411       List<org.proteios.gui.form.Option> options = select.getOptions();
    1412       for (org.proteios.gui.form.Option o : options)
    1413       {
    1414         if (o.isSelected())
    1415         {
    1416           hiddenF.setValue(o.getValue());
    1417           break;
    1418         }
    1419       }
    1420     }
    1421     selectTag.setOnChange("setNameField(this)");
    1422     String indentString = "";
    1423     int indent = 0;
    1424     for (Iterator iter = select.getOptions().iterator(); iter.hasNext();)
    1425     {
    1426       org.proteios.gui.form.Option option = (org.proteios.gui.form.Option) iter
    1427         .next();
    1428       if (option.getIndent() > indent)
    1429       {
    1430         indentString = indentString.concat("&nbsp;");
    1431         indent++;
    1432       }
    1433       else if (option.getIndent() < indent)
    1434       {
    1435         indent--;
    1436         indentString.substring(0, indent);
    1437       }
    1438       Option optionTag = selectTag.newOption()
    1439         .setValue(option.getValue());
    1440       optionTag.newCData(indentString + option.getContent());
    1441       if (option.isSelected())
    1442         optionTag.select();
    1443     }
    1444     return field;
    1445   }
    1446 
    1447 
    1448   public Tag convert(ColumnContainer container)
    1449   {
    1450     Tag layout = hf.newLayoutDiv();
    1451     Tag tbl = layout.newTable()
    1452       .setAttribute(new Attribute("width", "100%")).setClass("grid")
    1453       .setCellPadding(0).setCellSpacing(0);
    1454     Tr tr = tbl.newTr();
    1455     Iterator<GUIElement<?>> iter = container.getElements().iterator();
    1456     int width = 100 / container.size();
    1457     while (iter.hasNext())
    1458     {
    1459       GUIElement<?> e = iter.next();
    1460       if (e != null)
    1461       {
    1462         Td td = tr.newTd().setAttribute(
    1463           new Attribute("width", width + "%")).add(e.convert(this));
    1464         if (!iter.hasNext())
    1465     {
    1466           td.addClass("last");
    1467     }
    1468       }
    1469     }
    1470     return layout;
    1471   }
    1472 
    1473  public Tag convert(org.proteios.gui.Empty empty)
    1474  {
    1475    return new Span().newCData("&nbsp;");
    1476  }
    1477 
    1478   public Tag convert(RowContainer container)
    1479   {
    1480     Tag span = new Span();
    1481     Iterator<GUIElement<?>> iter = container.getElements().iterator();
    1482     boolean first = true;
    1483     while (iter.hasNext())
    1484     {
    1485       GUIElement<?> e = iter.next();
    1486       if (e != null)
    1487       {
    1488         Tag layout = hf.newLayoutDiv();
    1489         if (first)
    1490         {
    1491           layout.addClass("first");
    1492           first = false;
    1493         }
    1494         layout.add(e.convert(this));
    1495         span.add(layout);
    1496       }
    1497     }
    1498     return span;
    1499   }
    1500 
    1501   private int treeLevel = 0;
    1502 
    1503 
    1504   public Tag convert(Node node)
    1505   {
    1506     Tag li = new Li();
    1507     ActionLink a = node.getActionLink();
    1508     Tag href = li.newA().setHref("javascript:var nothing=0;");
    1509     if (treeLevel == 0)
    1510       href.setClass("top_parent");
    1511     // Get node label with or without localization
    1512     String label = node.getLabel();
    1513     if (node.isLocalizationUsed())
    1514     {
    1515       label = locale.get(node.getLabel());
    1516     }
    1517     if (a != null)
    1518     {
    1519       // To enable selenium ide testing all clickable items should
    1520       // have an id
    1521       String nodeId = node.getId();
    1522       href.setId(nodeId);
    1523       // Add optional icon image
    1524       String icon = fetchSelectionIconPath(a.isSelected());
    1525       if (icon != null)
    1526       {
    1527         Img img = href.newImg();
    1528         img.setSrc(imagePath + icon);
    1529         img.setStyle("border: none;");
    1530         // Set size for "blankbutton.gif" 1x16 pixels spacer image
    1531         if (icon.equals("icons/blankbutton.gif"))
    1532         {
    1533           // Set spacer size to 10x14 pixels
    1534           img.setAttribute(new Attribute("width", "10"));
    1535           img.setAttribute(new Attribute("height", "14"));
    1536         }
    1537       }
    1538       if (a.isDisabled())
    1539       {
    1540         href.addClass("disabled");
    1541         if (label.equals(""))
    1542         {
    1543           href.newCData("<hr/>");
    1544           href.addClass("separator");
    1545         }
    1546       }
    1547       else
    1548       {
    1549         href.setOnClick("rightGo('" + a.toString() + "')");
    1550       }
    1551     }
    1552     href.newCData(label);
    1553     if (node.getChildNodes() != null)
    1554     {
    1555       if (treeLevel >= 1)
    1556         href.addClass("parent");
    1557       Ul next = li.newUl();
    1558       treeLevel++;
    1559       Iterator<Node> children = node.getChildNodes().iterator();
    1560       boolean first = true;
    1561       while (children.hasNext())
    1562       {
    1563         Node child = children.next();
    1564         Tag childLi = convert(child);
    1565         Tag childHref = (Tag) childLi.getElements().get(0);
    1566         if (first)
    1567         {
    1568           childHref.addClass("first");
    1569         }
    1570         if (!children.hasNext())
    1571         {
    1572           childHref.addClass("last");
    1573         }
    1574 
    1575         if (first)
    1576           first = false;
    1577         next.add(childLi);
    1578       }
    1579       treeLevel--;
    1580     }
    1581     return li;
    1582   }
    1583 
    1584 
    1585   /**
    1586    * Convenience method for getting path to a bullet/spacer image file marking
    1587    * selected or unselected menu items. If the input selection flag is null,
    1588    * null is also returned, indicating that no icon should be used.
    1589    *
    1590    * @param selected Boolean A flag indicating if the menu item is selected
    1591    *        (null = no icon).
    1592    * @return String A path string to a bullet/spacer image file.
    1593    */
    1594   private String fetchSelectionIconPath(Boolean selected)
    1595   {
    1596     String iconPath = null;
    1597     if (selected != null)
    1598     {
    1599       if (selected)
    1600       {
    1601         // If item is selected, start with a bullet
    1602         iconPath = "icons/checkedmenu.gif";
    1603       }
    1604       else
    1605       {
    1606         // Reserve blank space equal to bullet size for non-selected
    1607         // items
    1608         iconPath = "icons/blankbutton.gif";
    1609       }
    1610     }
    1611     return iconPath;
    1612   }
    1613 
    1614 
    1615   /**
    1616    * Converts a toolbar so that button clicks post the form referenced by
    1617    * parameter formId
    1618    *
    1619    * @param toolbar
    1620    * @param formId
    1621    */
    1622   private Tag convert(Toolbar toolbar, String formId)
    1623   {
    1624     if (toolbar != null)
    1625     {
    1626       Div layout = new Div().setClass("toolbar");
    1627       Ul ul = layout.newUl();
    1628       for (AbstractLink link : toolbar.list())
    1629       {
    1630         Tag li = ul.newLi();
    1631         if (link.isDisabled())
    1632         {
    1633           li.addClass("disabled");
    1634           li.newCData(locale.get(link.getLabel()));
    1635         }
    1636         else
    1637         {
    1638           Tag a = null;
    1639           if (link instanceof ActionLink)
    1640           {
    1641             a = convert((ActionLink) link, formId, true);
    1642             li.add(a);
    1643           }
    1644           else if (link instanceof PopupLink)
    1645           {
    1646             PopupLink pop = (PopupLink) link;
    1647             /*
    1648              * This id works only if the labels do not have any
    1649              * spaces, they should not have spaces as they are keys
    1650              * for localization. If there is a better way to
    1651              * generate the id please fix it. But remember that the
    1652              * id must be the same always so test procedures can
    1653              * identify the link.
    1654              */
    1655             String id = nextId();
    1656             String icon = (String) iconSet.get(link.getLabel());
    1657             if (icon != null)
    1658             {
    1659               li.newImg().setSrc(imagePath + icon);
    1660             }
    1661                 li.setOnClick("popup('" + id + "')").newCData(
    1662               locale.get(pop.getLabel()));
    1663             if (currentFormTag != null)
    1664             {
    1665               Tag tmp = currentFormTag;
    1666               Div content = currentFormTag.newDiv().setId(id)
    1667                 .setClass("popupLayout");
    1668               GUIElement<?> popContent = pop.getContent();
    1669               currentFormTag = content;
    1670               if (popContent != null)
    1671               {
    1672                 content.add(popContent.convert(this));
    1673               }
    1674               currentFormTag = tmp;
    1675             }
    1676           }
    1677         }
    1678       }
    1679       return layout.getRoot();
    1680     }
    1681     return new CData("");
    1682   }
    1683 
    1684 
    1685   public Tag convert(org.proteios.gui.TabSet set)
    1686   {
    1687     Tag layout = hf.newLayoutDiv();
    1688     Tag div = layout.newDiv().setClass("tabs");
    1689     Tag ul = div.newUl().setClass("tabList");
    1690     List<Tab> tabs = set.getTabs();
    1691     Tab selectedTab = null;
    1692     for (org.proteios.gui.Tab tab : tabs)
    1693     {
    1694       ul.add(convert(tab, false));
    1695       if (tab.isSelected())
    1696         selectedTab = tab;
    1697     }
    1698     for (org.proteios.gui.Tab tab : tabs)
    1699     {
    1700       layout.add(convert(tab, true));
    1701     }
    1702     if (selectedTab == null)
    1703     {
    1704       selectedTab = tabs.get(0);
    1705       selectedTab.setSelected(true);
    1706     }
    1707     layout
    1708       .newCData("<script>showTab('" + selectedTab.getId() + "');</script>");
    1709     return layout;
    1710   }
    1711 
    1712 
    1713   private Tag convert(org.proteios.gui.Tab tab, boolean convertTabContent)
    1714   {
    1715     String contentId = "contentOf" + tab.getId();
    1716     if (convertTabContent)
    1717     {
    1718       Div content = new Div().setClass("tabContent").setId(contentId);
    1719       GUIElement<?> tabContent = tab.getGuiElement();
    1720       if (tabContent != null)
    1721         content.add(tabContent.convert(this));
    1722       return content;
    1723     }
    1724     Li li = new Li().setClass("tab").setId(tab.getId()).setOnClick(
    1725       "showTab('" + tab.getId() + "')");
    1726     if (tab.isSelected())
    1727       li.addClass("here");
    1728     li.newCData(locale.get(tab.getLabel()));
    1729     return li;
    1730   }
    1731 
    1732 
    1733   private Tag convert(org.proteios.gui.form.TextArea f)
    1734   {
    1735     String value = f.getValue();
    1736     Tag in = null;
    1737     // Use input
    1738     in = new Textarea().setName(f.getId()).setId(f.getId()).setCols(25);
    1739     if (value != null)
    1740       in.newCData(value);
    1741     else
    1742       in.newCData("");
    1743     if (f.isDisabled())
    1744     {
    1745       in.addClass("disabled");
    1746     }
    1747     return in;
    1748   }
    1749 
    1750 
    1751  private String formatedValue(TextField<?> f)
    1752  {
    1753   String value;
    1754   value = null;
    1755     if (f != null && f.getValue() != null)
    1756     {
    1757       if (f.getValue() instanceof Date)
    1758         value = formatter.format(f.getValue());
    1759       else
    1760         value = f.getValue().toString();
    1761     }
    1762   return value;
    1763  }
    1764 
    1765 
    1766   private <D extends Object> Tag<?> convert(
    1767       org.proteios.gui.form.TextField<D> f)
    1768   {
    1769   String value, type;
    1770   Tag table, row, labelC, inC, helpC, container;
    1771   Input in;
    1772   Tag<?> field;
    1773 
    1774     // Format the value
    1775     value = formatedValue(f);
    1776   container = new CData("");
    1777 
    1778     in = null;
    1779     type = "text";
    1780     if (f.isHidden() || f.isDisabled())
    1781     {
    1782       type = "hidden";
    1783     }
    1784     in = new Input().setName(f.getId()).setType(type).setSize(25);
    1785   in.setSize(f.getCharWidth());
    1786     if (value == null)
    1787   {
    1788    value = "";
    1789   }
    1790     if (f.getParam().isRequired() ||
    1791    (f.getParam() instanceof VString && ((VString) f.getParam()).getMinCharacterLength() > 0))
    1792   {
    1793     in.addClass("required");
    1794   }
    1795     in.setValue(value);
    1796     in.setId(f.getId());
    1797   container.add(in);
    1798     if (f.isDisabled())
    1799     {
    1800    container.newCData(value);
    1801   }
    1802     return container;
    1803   }
    1804 
    1805 
    1806   private Tag<?> convert(org.proteios.gui.form.PasswordField f)
    1807   {
    1808     Input in = new Input().setId(f.getId()).setName(f.getId()).setType(
    1809       "password").setSize(f.getCharWidth());
    1810     if (f.getValue() != null)
    1811   {
    1812       in.setValue(f.getValue().toString());
    1813   }
    1814     return in;
    1815   }
    1816 
    1817 
    1818   public Tag<?> convert(org.proteios.gui.form.Checkbox<?> checkbox)
    1819   {
    1820     return convert(checkbox, false);
    1821   }
    1822 
    1823 
    1824   private Tag<?> convert(org.proteios.gui.form.Checkbox<?> checkbox,
    1825       boolean inForm)
    1826   {
    1827     Input cbF = new Input().setId(checkbox.getId()).setName(
    1828       checkbox.getId()).setType("checkbox");
    1829     if (checkbox.getValue() != null)
    1830       cbF.setValue(checkbox.getValue().toString());
    1831     if (checkbox.isChecked())
    1832       cbF.check();
    1833     if (checkbox.isDisabled())
    1834       cbF.disable();
    1835     if (inForm)
    1836     {
    1837       Tag<?> field = hf.newField(checkbox);
    1838       field.add(cbF);
    1839       field.add(hf.getFieldError(checkbox));
    1840       return field;
    1841     }
    1842     return cbF;
    1843   }
    1844 
    1845 
    1846   public Tag<?> convert(org.proteios.gui.Toolbar toolbar)
    1847   {
    1848     Div layout = new Div().setClass("toolbar");
    1849     Ul ul = layout.newUl();
    1850     for (AbstractLink actionLink : toolbar.list())
    1851     {
    1852       Li li = ul.newLi();
    1853       String icon = (String) iconSet.get(actionLink.getLabel());
    1854       if (icon != null)
    1855       {
    1856         li.newImg().setSrc(imagePath + icon);
    1857       }
    1858       if (actionLink.isDisabled())
    1859       {
    1860         li.addClass("disabled");
    1861       }
    1862       else
    1863       {
    1864         if (actionLink instanceof ClosePopup)
    1865         {
    1866           li.setOnClick(convert((ClosePopup) actionLink));
    1867         }
    1868         else if (actionLink instanceof PopupLink)
    1869         {
    1870           PopupLink pop = (PopupLink) actionLink;
    1871           /*
    1872            * This id works only if the labels do not have any spaces,
    1873            * they should not have spaces as they are keys for
    1874            * localization. If there is a better way to generate the id
    1875            * please fix it. But remember that the id must be the same
    1876            * always so test procedures can identify the link.
    1877            */
    1878           String id = nextId();
    1879           li.setOnClick("popup('" + id + "')");
    1880           if (currentFormTag != null)
    1881           {
    1882             Tag tmp = currentFormTag;
    1883             Div content = currentFormTag.newDiv().setId(id)
    1884               .setClass("popupLayout");
    1885             GUIElement<?> popContent = pop.getContent();
    1886             currentFormTag = content;
    1887             if (popContent != null)
    1888             {
    1889               content.add(popContent.convert(this));
    1890             }
    1891             currentFormTag = tmp;
    1892           }
    1893         }
    1894         else if (actionLink instanceof ActionLink)
    1895         {
    1896           if (currentFormId != null)
    1897           {
    1898             li.setOnClick(action2js((ActionLink) actionLink,
    1899               currentFormId));
    1900           }
    1901           else
    1902           {
    1903             li.setOnClick(action2js((ActionLink) actionLink));
    1904           }
    1905         }
    1906       }
    1907       li.newCData(locale.get(actionLink.getLabel()));
    1908     }
    1909     return layout.getRoot();
    1910   }
    1911 
    1912 
    1913   public Tag<?> convert(org.proteios.gui.Button button)
    1914   {
    1915     Div layout = new Div().setClass("button");
    1916   Span li = layout.newSpan();
    1917   AbstractLink actionLink = button.getLink();
    1918       String icon = (String) iconSet.get(actionLink.getLabel());
    1919       if (icon != null)
    1920       {
    1921         li.newImg().setSrc(imagePath + icon);
    1922       }
    1923    else
    1924    {
    1925     li.addClass("noicon");
    1926    }
    1927       if (actionLink.isDisabled())
    1928       {
    1929         li.addClass("disabled");
    1930       }
    1931       else
    1932       {
    1933         if (actionLink instanceof ClosePopup)
    1934         {
    1935           li.setOnClick(convert((ClosePopup) actionLink));
    1936         }
    1937         else if (actionLink instanceof PopupLink)
    1938         {
    1939           PopupLink pop = (PopupLink) actionLink;
    1940           /*
    1941            * This id works only if the labels do not have any spaces,
    1942            * they should not have spaces as they are keys for
    1943            * localization. If there is a better way to generate the id
    1944            * please fix it. But remember that the id must be the same
    1945            * always so test procedures can identify the link.
    1946            */
    1947           String id = nextId();
    1948           li.setOnClick("popup('" + id + "')");
    1949           if (currentFormTag != null)
    1950           {
    1951             Tag tmp = currentFormTag;
    1952             Div content = currentFormTag.newDiv().setId(id)
    1953               .setClass("popupLayout");
    1954             GUIElement<?> popContent = pop.getContent();
    1955             currentFormTag = content;
    1956             if (popContent != null)
    1957             {
    1958               content.add(popContent.convert(this));
    1959             }
    1960             currentFormTag = tmp;
    1961           }
    1962         }
    1963         else if (actionLink instanceof ActionLink)
    1964         {
    1965           if (currentFormId != null)
    1966           {
    1967             li.setOnClick(action2js((ActionLink) actionLink,
    1968               currentFormId));
    1969           }
    1970           else
    1971           {
    1972             li.setOnClick(action2js((ActionLink) actionLink));
    1973           }
    1974         }
    1975       }
    1976       li.newCData(locale.get(actionLink.getLabel()));
    1977     return layout.getRoot();
    1978   }
    1979 
    1980 
    1981   public Tag<?> convert(org.proteios.gui.ButtonSet toolbar)
    1982   {
    1983     Div layout = hf.newLayoutDiv();
    1984     layout.ins(convert((org.proteios.gui.Toolbar) toolbar));
    1985     return layout;
    1986   }
    1987 
    1988 
    1989   public Tag<?> convert(org.proteios.gui.Title title)
    1990   {
    1991     Tag<?> hx;
    1992     switch (title.getSize())
    1993     {
    1994       default:
    1995         hx = new H1();
    1996         break;
    1997     }
    1998     String titleLoc = locale.get(title.getTitle());
    1999     hx.newCData(titleLoc);
    2000     String subtitle = title.getSubtitle();
    2001     if (subtitle != null)
    2002     {
    2003       hx.newCData(" - ");
    2004       hx.newSpan().setClass("subtitle").newCData(subtitle);
    2005     }
    2006     return hx.getRoot();
    2007   }
    2008 
    2009 
    2010   @Override
    2011   public Tag missingConverter(ConvertableElement obj)
    2012   {
    2013     Div div = new Div().add(new CData(
    2014       "Missing convert() method for class " + obj.getClass()
    2015         .getSimpleName() + " in " + this.getClass().getSimpleName()));
    2016     div.newBr();
    2017     return div;
    2018   }
    2019 
    2020 
    2021   public void setLocale(Localizer locale)
    2022   {
    2023     if (this.locale == null)
    2024     {
    2025       this.locale = locale;
    2026       // Propagate the locale down to the HtmlFactory
    2027       hf.setLocalizer(locale);
    2028     }
    2029   }
    2030 
    2031 
    2032   public void setIconSet(Properties iconSet)
    2033   {
    2034     if (this.iconSet == null)
    2035       this.iconSet = iconSet;
    2036   }
     1269        if (fs.getTitle()!= null)
     1270        {
     1271            title.add(new CData(
     1272            locale.get(fs.getTitle().getTitle()) + "&nbsp;"));
     1273            subtitle = fs.getTitle().getSubtitle();
     1274            if (subtitle != null)
     1275            {
     1276                title.newCData(" - ");
     1277                title.newSpan().setClass("subtitle").newCData(subtitle);
     1278            }
     1279        }
     1280        legend.add(title.getRoot());
     1281       
     1282        fields = fieldset.newDiv().setClass("fields");
     1283    fields.setId(id);
     1284    fields.setStyle("display: " + (fs.isOpen() ? "block" : "none"));
     1285        table = fields.newTable();
     1286        for (org.proteios.gui.GUIElement f : fs.getFields())
     1287        {
     1288            row = table.newTr();
     1289            // Label cell
     1290            if(f instanceof org.proteios.gui.form.Field)
     1291            {
     1292                field = (org.proteios.gui.form.Field) f;
     1293                row.newTd().addClass("label").newCData(locale.get(field.getLabel()));
     1294                input = null;
     1295                // Field cell
     1296                if (f instanceof TextField)
     1297                {
     1298                    input = convert((TextField<?>) f);
     1299                    if(((TextField<?>)field).isHidden())
     1300                    {
     1301                        row.addClass("hidden");
     1302                    }
     1303                }
     1304                else if (f instanceof PasswordField)
     1305                {
     1306                    input = convert((PasswordField) f);
     1307                }
     1308                else if (f instanceof FileField)
     1309                {
     1310                    if (form != null)
     1311                    {
     1312                        form.setMultipart();
     1313                    }
     1314                    input = convert((FileField) f);
     1315                }
     1316                else if (f instanceof TextArea)
     1317                {
     1318                    input = convert((TextArea) f);
     1319                }
     1320                else if (f instanceof org.proteios.gui.form.Select)
     1321                {
     1322                    input = convert((org.proteios.gui.form.Select) f);
     1323                }
     1324                else if (f instanceof org.proteios.gui.form.Checkbox)
     1325                {
     1326                    input = convert((org.proteios.gui.form.Checkbox) f, false);
     1327                }
     1328                   
     1329                if (field.getParam().isRequired() ||
     1330                (field.getParam() instanceof VString && ((VString) field.getParam()).getMinCharacterLength() > 0))
     1331                {
     1332                    input.addClass("required");
     1333                }
     1334                if(input != null)
     1335                {
     1336                    row.newTd().add(input);
     1337                }
     1338               
     1339                // Help and error field
     1340                helpC = row.newTd();
     1341                helpC.newDiv().addClass("error").add(hf.getFieldError(field));
     1342                helpC.newDiv().addClass("help").newCData(field.getHelp());
     1343            }
     1344            if (f instanceof org.proteios.gui.table.Table)
     1345            {
     1346                row.newTd().add(convert((org.proteios.gui.table.Table) f));
     1347            }
     1348               
     1349        }
     1350        return fieldset;
     1351    }
     1352   
     1353    private Tag convert(FileField f)
     1354    {
     1355        Input in = new Input().setId(f.getId()).setName(f.getId()).setType(
     1356        "file");
     1357        if (f.getValue() != null)
     1358        in.setValue(f.getValue().toString());
     1359        if (f.isDisabled())
     1360        in.disable();
     1361        return in;
     1362    }
     1363   
     1364    public Tag convert(org.proteios.gui.form.Select<?> select)
     1365    {
     1366        Tag field = new CData("");
     1367        Select selectTag = field.newSelect().setId(select.getId()).setName(
     1368        select.getName());
     1369        // Use multiple selection box if isMultiple() == true
     1370        if (select.isMultiple() != null && select.isMultiple())
     1371        {
     1372            selectTag.setAttribute(new Attribute("multiple", ""));
     1373        }
     1374        // Set number of visible items if getSize() != null
     1375        if (select.getSize() != null)
     1376        {
     1377            selectTag.setAttribute(new Attribute("size", select.getSize()
     1378            .toString()));
     1379        }
     1380        if (select.isDisabled())
     1381        {
     1382            selectTag.setAttribute(new Attribute("disabled", "disabled"));
     1383            selectTag.addClass("disable");
     1384            Input hiddenF = field.newInput().setId(select.getId()).setName(
     1385            select.getName()).setType("hidden");
     1386            List<org.proteios.gui.form.Option> options = select.getOptions();
     1387            for (org.proteios.gui.form.Option o : options)
     1388            {
     1389                if (o.isSelected())
     1390                {
     1391                    hiddenF.setValue(o.getValue());
     1392                    break;
     1393                }
     1394            }
     1395        }
     1396        selectTag.setOnChange("setNameField(this)");
     1397        String indentString = "";
     1398        int indent = 0;
     1399        for (Iterator iter = select.getOptions().iterator(); iter.hasNext();)
     1400        {
     1401            org.proteios.gui.form.Option option = (org.proteios.gui.form.Option) iter
     1402            .next();
     1403            if (option.getIndent() > indent)
     1404            {
     1405                indentString = indentString.concat("&nbsp;");
     1406                indent++;
     1407            }
     1408            else if (option.getIndent() < indent)
     1409            {
     1410                indent--;
     1411                indentString.substring(0, indent);
     1412            }
     1413            Option optionTag = selectTag.newOption()
     1414            .setValue(option.getValue());
     1415            optionTag.newCData(indentString + option.getContent());
     1416            if (option.isSelected())
     1417            optionTag.select();
     1418        }
     1419        return field;
     1420    }
     1421   
     1422    public Tag convert(ColumnContainer container)
     1423    {
     1424        Tag layout = hf.newLayoutDiv();
     1425        Tag tbl = layout.newTable()
     1426        .setAttribute(new Attribute("width", "100%")).setClass("grid")
     1427        .setCellPadding(0).setCellSpacing(0);
     1428        Tr tr = tbl.newTr();
     1429        Iterator<GUIElement<?>> iter = container.getElements().iterator();
     1430        int width = 100 / container.size();
     1431        while (iter.hasNext())
     1432        {
     1433            GUIElement<?> e = iter.next();
     1434            if (e != null)
     1435            {
     1436                Td td = tr.newTd().setAttribute(
     1437                new Attribute("width", width + "%")).add(e.convert(this));
     1438                if (!iter.hasNext())
     1439                {
     1440                    td.addClass("last");
     1441                }
     1442            }
     1443        }
     1444        return layout;
     1445    }
     1446   
     1447    public Tag convert(org.proteios.gui.Empty empty)
     1448    {
     1449        return new Span().newCData("&nbsp;");
     1450    }
     1451   
     1452    public Tag convert(RowContainer container)
     1453    {
     1454        Tag span = new Span();
     1455        Iterator<GUIElement<?>> iter = container.getElements().iterator();
     1456        boolean first = true;
     1457        while (iter.hasNext())
     1458        {
     1459            GUIElement<?> e = iter.next();
     1460            if (e != null)
     1461            {
     1462                Tag layout = hf.newLayoutDiv();
     1463                if (first)
     1464                {
     1465                    layout.addClass("first");
     1466                    first = false;
     1467                }
     1468                layout.add(e.convert(this));
     1469                span.add(layout);
     1470            }
     1471        }
     1472        return span;
     1473    }
     1474   
     1475    private int treeLevel = 0;
     1476   
     1477    public Tag convert(Node node)
     1478    {
     1479        Tag li = new Li();
     1480        ActionLink a = node.getActionLink();
     1481        Tag href = li.newA().setHref("javascript:var nothing=0;");
     1482        if (treeLevel == 0)
     1483        href.setClass("top_parent");
     1484        // Get node label with or without localization
     1485        String label = node.getLabel();
     1486        if (node.isLocalizationUsed())
     1487        {
     1488            label = locale.get(node.getLabel());
     1489        }
     1490        if (a != null)
     1491        {
     1492            // To enable selenium ide testing all clickable items should
     1493            // have an id
     1494            String nodeId = node.getId();
     1495            href.setId(nodeId);
     1496            // Add optional icon image
     1497            String icon = fetchSelectionIconPath(a.isSelected());
     1498            if (icon != null)
     1499            {
     1500                Img img = href.newImg();
     1501                img.setSrc(imagePath + icon);
     1502                img.setStyle("border: none;");
     1503                // Set size for "blankbutton.gif" 1x16 pixels spacer image
     1504                if (icon.equals("icons/blankbutton.gif"))
     1505                {
     1506                    // Set spacer size to 10x14 pixels
     1507                    img.setAttribute(new Attribute("width", "10"));
     1508                    img.setAttribute(new Attribute("height", "14"));
     1509                }
     1510            }
     1511            if (a.isDisabled())
     1512            {
     1513                href.addClass("disabled");
     1514                if (label.equals(""))
     1515                {
     1516                    href.newCData("<hr/>");
     1517                    href.addClass("separator");
     1518                }
     1519            }
     1520            else
     1521            {
     1522                href.setOnClick("rightGo('" + a.toString() + "')");
     1523            }
     1524        }
     1525        href.newCData(label);
     1526        if (node.getChildNodes() != null)
     1527        {
     1528            if (treeLevel >= 1)
     1529            href.addClass("parent");
     1530            Ul next = li.newUl();
     1531            treeLevel++;
     1532            Iterator<Node> children = node.getChildNodes().iterator();
     1533            boolean first = true;
     1534            while (children.hasNext())
     1535            {
     1536                Node child = children.next();
     1537                Tag childLi = convert(child);
     1538                Tag childHref = (Tag) childLi.getElements().get(0);
     1539                if (first)
     1540                {
     1541                    childHref.addClass("first");
     1542                }
     1543                if (!children.hasNext())
     1544                {
     1545                    childHref.addClass("last");
     1546                }
     1547               
     1548                if (first)
     1549                first = false;
     1550                next.add(childLi);
     1551            }
     1552            treeLevel--;
     1553        }
     1554        return li;
     1555    }
     1556   
     1557    /**
     1558        * Convenience method for getting path to a bullet/spacer image file marking
     1559        * selected or unselected menu items. If the input selection flag is null,
     1560        * null is also returned, indicating that no icon should be used.
     1561        *
     1562        * @param selected Boolean A flag indicating if the menu item is selected
     1563        *        (null = no icon).
     1564        * @return String A path string to a bullet/spacer image file.
     1565    */
     1566    private String fetchSelectionIconPath(Boolean selected)
     1567    {
     1568        String iconPath = null;
     1569        if (selected != null)
     1570        {
     1571            if (selected)
     1572            {
     1573                // If item is selected, start with a bullet
     1574                iconPath = "icons/checkedmenu.gif";
     1575            }
     1576            else
     1577            {
     1578                // Reserve blank space equal to bullet size for non-selected
     1579                // items
     1580                iconPath = "icons/blankbutton.gif";
     1581            }
     1582        }
     1583        return iconPath;
     1584    }
     1585   
     1586    /**
     1587        * Converts a toolbar so that button clicks post the form referenced by
     1588        * parameter formId
     1589        *
     1590        * @param toolbar
     1591        * @param formId
     1592    */
     1593    private Tag convert(Toolbar toolbar, String formId)
     1594    {
     1595        if (toolbar != null)
     1596        {
     1597            Div layout = new Div().setClass("toolbar");
     1598            Ul ul = layout.newUl();
     1599            for (AbstractLink link : toolbar.list())
     1600            {
     1601                Tag li = ul.newLi();
     1602                if (link.isDisabled())
     1603                {
     1604                    li.addClass("disabled");
     1605                    li.newCData(locale.get(link.getLabel()));
     1606                }
     1607                else
     1608                {
     1609                    Tag a = null;
     1610                    if (link instanceof ActionLink)
     1611                    {
     1612                        a = convert((ActionLink) link, formId, true);
     1613                        li.add(a);
     1614                    }
     1615                    else if (link instanceof PopupLink)
     1616                    {
     1617                        PopupLink pop = (PopupLink) link;
     1618                        /*
     1619                            * This id works only if the labels do not have any
     1620                            * spaces, they should not have spaces as they are keys
     1621                            * for localization. If there is a better way to
     1622                            * generate the id please fix it. But remember that the
     1623                            * id must be the same always so test procedures can
     1624                            * identify the link.
     1625                        */
     1626                        String id = nextId();
     1627                        String icon = (String) iconSet.get(link.getLabel());
     1628                        if (icon != null)
     1629                        {
     1630                            li.newImg().setSrc(imagePath + icon);
     1631                        }
     1632                        li.setOnClick("popup('" + id + "')").newCData(
     1633                        locale.get(pop.getLabel()));
     1634                        if (currentFormTag != null)
     1635                        {
     1636                            Tag tmp = currentFormTag;
     1637                            Div content = currentFormTag.newDiv().setId(id)
     1638                            .setClass("popupLayout");
     1639                            GUIElement<?> popContent = pop.getContent();
     1640                            currentFormTag = content;
     1641                            if (popContent != null)
     1642                            {
     1643                                content.add(popContent.convert(this));
     1644                            }
     1645                            currentFormTag = tmp;
     1646                        }
     1647                    }
     1648                }
     1649            }
     1650            return layout.getRoot();
     1651        }
     1652        return new CData("");
     1653    }
     1654   
     1655    public Tag convert(org.proteios.gui.TabSet set)
     1656    {
     1657        Tag layout = hf.newLayoutDiv();
     1658        Tag div = layout.newDiv().setClass("tabs");
     1659        Tag ul = div.newUl().setClass("tabList");
     1660        List<Tab> tabs = set.getTabs();
     1661        Tab selectedTab = null;
     1662        for (org.proteios.gui.Tab tab : tabs)
     1663        {
     1664            ul.add(convert(tab, false));
     1665            if (tab.isSelected())
     1666            selectedTab = tab;
     1667        }
     1668        for (org.proteios.gui.Tab tab : tabs)
     1669        {
     1670            layout.add(convert(tab, true));
     1671        }
     1672        if (selectedTab == null)
     1673        {
     1674            selectedTab = tabs.get(0);
     1675            selectedTab.setSelected(true);
     1676        }
     1677        layout
     1678        .newCData("<script>showTab('" + selectedTab.getId() + "');</script>");
     1679        return layout;
     1680    }
     1681   
     1682    private Tag convert(org.proteios.gui.Tab tab, boolean convertTabContent)
     1683    {
     1684        String contentId = "contentOf" + tab.getId();
     1685        if (convertTabContent)
     1686        {
     1687            Div content = new Div().setClass("tabContent").setId(contentId);
     1688            GUIElement<?> tabContent = tab.getGuiElement();
     1689            if (tabContent != null)
     1690            content.add(tabContent.convert(this));
     1691            return content;
     1692        }
     1693        Li li = new Li().setClass("tab").setId(tab.getId()).setOnClick(
     1694        "showTab('" + tab.getId() + "')");
     1695        if (tab.isSelected())
     1696        li.addClass("here");
     1697        li.newCData(locale.get(tab.getLabel()));
     1698        return li;
     1699    }
     1700   
     1701    private Tag convert(org.proteios.gui.form.TextArea f)
     1702    {
     1703        String value = f.getValue();
     1704        Tag in = null;
     1705        // Use input
     1706        in = new Textarea().setName(f.getId()).setId(f.getId()).setCols(25);
     1707        if (value != null)
     1708        in.newCData(value);
     1709        else
     1710        in.newCData("");
     1711        if (f.isDisabled())
     1712        {
     1713            in.addClass("disabled");
     1714        }
     1715        return in;
     1716    }
     1717   
     1718    private String formatedValue(TextField<?> f)
     1719    {
     1720        String value;
     1721        value = null;
     1722        if (f != null && f.getValue() != null)
     1723        {
     1724            if (f.getValue() instanceof Date)
     1725            value = formatter.format(f.getValue());
     1726            else
     1727            value = f.getValue().toString();
     1728        }
     1729        return value;
     1730    }
     1731   
     1732    private <D extends Object> Tag<?> convert(
     1733    org.proteios.gui.form.TextField<D> f)
     1734    {
     1735        String value, type;
     1736        Tag table, row, labelC, inC, helpC, container;
     1737        Input in;
     1738        Tag<?> field;
     1739       
     1740        // Format the value
     1741        value = formatedValue(f);
     1742        container = new CData("");
     1743       
     1744        in = null;
     1745        type = "text";
     1746        if (f.isHidden() || f.isDisabled())
     1747        {
     1748            type = "hidden";
     1749        }
     1750        in = new Input().setName(f.getId()).setType(type).setSize(25);
     1751        in.setSize(f.getCharWidth());
     1752        if (value == null)
     1753        {
     1754            value = "";
     1755        }
     1756        if (f.getParam().isRequired() ||
     1757        (f.getParam() instanceof VString && ((VString) f.getParam()).getMinCharacterLength() > 0))
     1758        {
     1759            in.addClass("required");
     1760        }
     1761        in.setValue(value);
     1762        in.setId(f.getId());
     1763        container.add(in);
     1764        if (f.isDisabled())
     1765        {
     1766            container.newCData(value);
     1767        }
     1768        return container;
     1769    }
     1770   
     1771    private Tag<?> convert(org.proteios.gui.form.PasswordField f)
     1772    {
     1773        Input in = new Input().setId(f.getId()).setName(f.getId()).setType(
     1774        "password").setSize(f.getCharWidth());
     1775        if (f.getValue() != null)
     1776        {
     1777            in.setValue(f.getValue().toString());
     1778        }
     1779        return in;
     1780    }
     1781   
     1782    public Tag<?> convert(org.proteios.gui.form.Checkbox<?> checkbox)
     1783    {
     1784        return convert(checkbox, false);
     1785    }
     1786   
     1787    private Tag<?> convert(org.proteios.gui.form.Checkbox<?> checkbox,
     1788    boolean inForm)
     1789    {
     1790        Input cbF = new Input().setId(checkbox.getId()).setName(
     1791        checkbox.getId()).setType("checkbox");
     1792        if (checkbox.getValue() != null)
     1793        cbF.setValue(checkbox.getValue().toString());
     1794        if (checkbox.isChecked())
     1795        cbF.check();
     1796        if (checkbox.isDisabled())
     1797        cbF.disable();
     1798        if (inForm)
     1799        {
     1800            Tag<?> field = hf.newField(checkbox);
     1801            field.add(cbF);
     1802            field.add(hf.getFieldError(checkbox));
     1803            return field;
     1804        }
     1805        return cbF;
     1806    }
     1807   
     1808    public Tag<?> convert(org.proteios.gui.Toolbar toolbar)
     1809    {
     1810        Div layout = new Div().setClass("toolbar");
     1811        Ul ul = layout.newUl();
     1812        for (AbstractLink actionLink : toolbar.list())
     1813        {
     1814            Li li = ul.newLi();
     1815            String icon = (String) iconSet.get(actionLink.getLabel());
     1816            if (icon != null)
     1817            {
     1818                li.newImg().setSrc(imagePath + icon);
     1819            }
     1820            if (actionLink.isDisabled())
     1821            {
     1822                li.addClass("disabled");
     1823            }
     1824            else
     1825            {
     1826                if (actionLink instanceof ClosePopup)
     1827                {
     1828                    li.setOnClick(convert((ClosePopup) actionLink));
     1829                }
     1830                else if (actionLink instanceof PopupLink)
     1831                {
     1832                    PopupLink pop = (PopupLink) actionLink;
     1833                    /*
     1834                        * This id works only if the labels do not have any spaces,
     1835                        * they should not have spaces as they are keys for
     1836                        * localization. If there is a better way to generate the id
     1837                        * please fix it. But remember that the id must be the same
     1838                        * always so test procedures can identify the link.
     1839                    */
     1840                    String id = nextId();
     1841                    li.setOnClick("popup('" + id + "')");
     1842                    if (currentFormTag != null)
     1843                    {
     1844                        Tag tmp = currentFormTag;
     1845                        Div content = currentFormTag.newDiv().setId(id)
     1846                        .setClass("popupLayout");
     1847                        GUIElement<?> popContent = pop.getContent();
     1848                        currentFormTag = content;
     1849                        if (popContent != null)
     1850                        {
     1851                            content.add(popContent.convert(this));
     1852                        }
     1853                        currentFormTag = tmp;
     1854                    }
     1855                }
     1856                else if (actionLink instanceof ActionLink)
     1857                {
     1858                    if (currentFormId != null)
     1859                    {
     1860                        li.setOnClick(action2js((ActionLink) actionLink,
     1861                        currentFormId));
     1862                    }
     1863                    else
     1864                    {
     1865                        li.setOnClick(action2js((ActionLink) actionLink));
     1866                    }
     1867                }
     1868            }
     1869            li.newCData(locale.get(actionLink.getLabel()));
     1870        }
     1871        return layout.getRoot();
     1872    }
     1873   
     1874    public Tag<?> convert(org.proteios.gui.Button button)
     1875    {
     1876        Div layout = new Div().setClass("button");
     1877        Span li = layout.newSpan();
     1878        AbstractLink actionLink = button.getLink();
     1879        String icon = (String) iconSet.get(actionLink.getLabel());
     1880        if (icon != null)
     1881        {
     1882            li.newImg().setSrc(imagePath + icon);
     1883        }
     1884        else
     1885        {
     1886            li.addClass("noicon");
     1887        }
     1888        if (actionLink.isDisabled())
     1889        {
     1890            li.addClass("disabled");
     1891        }
     1892        else
     1893        {
     1894            if (actionLink instanceof ClosePopup)
     1895            {
     1896                li.setOnClick(convert((ClosePopup) actionLink));
     1897            }
     1898            else if (actionLink instanceof PopupLink)
     1899            {
     1900                PopupLink pop = (PopupLink) actionLink;
     1901                /*
     1902                    * This id works only if the labels do not have any spaces,
     1903                    * they should not have spaces as they are keys for
     1904                    * localization. If there is a better way to generate the id
     1905                    * please fix it. But remember that the id must be the same
     1906                    * always so test procedures can identify the link.
     1907                */
     1908                String id = nextId();
     1909                li.setOnClick("popup('" + id + "')");
     1910                if (currentFormTag != null)
     1911                {
     1912                    Tag tmp = currentFormTag;
     1913                    Div content = currentFormTag.newDiv().setId(id)
     1914                    .setClass("popupLayout");
     1915                    GUIElement<?> popContent = pop.getContent();
     1916                    currentFormTag = content;
     1917                    if (popContent != null)
     1918                    {
     1919                        content.add(popContent.convert(this));
     1920                    }
     1921                    currentFormTag = tmp;
     1922                }
     1923            }
     1924            else if (actionLink instanceof ActionLink)
     1925            {
     1926                if (currentFormId != null)
     1927                {
     1928                    li.setOnClick(action2js((ActionLink) actionLink,
     1929                    currentFormId));
     1930                }
     1931                else
     1932                {
     1933                    li.setOnClick(action2js((ActionLink) actionLink));
     1934                }
     1935            }
     1936        }
     1937        li.newCData(locale.get(actionLink.getLabel()));
     1938        return layout.getRoot();
     1939    }
     1940   
     1941    public Tag<?> convert(org.proteios.gui.ButtonSet toolbar)
     1942    {
     1943        Div layout = hf.newLayoutDiv();
     1944        layout.ins(convert((org.proteios.gui.Toolbar) toolbar));
     1945        return layout;
     1946    }
     1947   
     1948    public Tag<?> convert(org.proteios.gui.Title title)
     1949    {
     1950        Tag<?> hx;
     1951        switch (title.getSize())
     1952        {
     1953            default:
     1954            hx = new H1();
     1955            break;
     1956        }
     1957        String titleLoc = locale.get(title.getTitle());
     1958        hx.newCData(titleLoc);
     1959        String subtitle = title.getSubtitle();
     1960        if (subtitle != null)
     1961        {
     1962            hx.newCData(" - ");
     1963            hx.newSpan().setClass("subtitle").newCData(subtitle);
     1964        }
     1965        return hx.getRoot();
     1966    }
     1967   
     1968    @Override
     1969    public Tag missingConverter(ConvertableElement obj)
     1970    {
     1971        Div div = new Div().add(new CData(
     1972        "Missing convert() method for class " + obj.getClass()
     1973        .getSimpleName() + " in " + this.getClass().getSimpleName()));
     1974        div.newBr();
     1975        return div;
     1976    }
     1977   
     1978    public void setLocale(Localizer locale)
     1979    {
     1980        if (this.locale == null)
     1981        {
     1982            this.locale = locale;
     1983            // Propagate the locale down to the HtmlFactory
     1984            hf.setLocalizer(locale);
     1985        }
     1986    }
     1987   
     1988    public void setIconSet(Properties iconSet)
     1989    {
     1990        if (this.iconSet == null)
     1991        this.iconSet = iconSet;
     1992    }
    20371993}
  • trunk/client/servlet/test/src/org/proteios/gui/form/NewUserFormTest.java

    r3797 r3894  
    11package org.proteios.gui.web;
    22
     3import java.io.IOException;
     4import java.util.Properties;
    35import org.junit.Before;
    46import org.junit.Test;
     
    810import org.proteios.gui.form.*;
    911import org.proteios.gui.layout.RowLayout;
    10 
    1112import se.lu.thep.waf.dom.html.Tag;
    12 
    13 import java.io.IOException;
    14 import java.util.Properties;
    1513
    1614public class NewUserFormTest
    1715{
    18   HtmlOutputUtil out = null;
    19   Localizer locale = null;
    20   Properties iconSet = null;
    21 
    22   @Before
    23   public void setup()
    24   {
    25     out = new HtmlOutputUtil();
    26     try
    27     {
    28       locale = new Localizer("en");
    29       iconSet = new Properties();
    30       iconSet.load(ActionFactory.class
    31         .getResourceAsStream("/icons/default"));
    32     }
    33     catch (IOException e)
    34     {
    35       e.printStackTrace();
    36     }
    37   }
    38 
    39 
    40   @Test
    41   public void testWebGUI()
    42   {
    43     RowLayout layout;
    44   Form form = new NewUserForm(null); // We skip the roles by not providing a DbControl
    45   LayoutConverter lconverter;
    46   Tag html;
    47   layout = new RowLayout();
    48     layout.add(form);
    49     lconverter = new LayoutConverter(".", null);
    50     lconverter.setLocalizer(locale);
    51     lconverter.setIconSet(iconSet);
    52     layout.setConverter(lconverter);
    53     html = layout.getHtml(".", null);
    54     out.printToFile(html, "TEST_NewUserForm.html");
    55   }
     16    HtmlOutputUtil out = null;
     17    Localizer locale = null;
     18    Properties iconSet = null;
     19   
     20    @Before
     21    public void setup()
     22    {
     23        out = new HtmlOutputUtil();
     24        try
     25        {
     26            locale = new Localizer("en");
     27            iconSet = new Properties();
     28            iconSet.load(ActionFactory.class
     29            .getResourceAsStream("/icons/default"));
     30        }
     31        catch (IOException e)
     32        {
     33            e.printStackTrace();
     34        }
     35    }
     36   
     37    @Test
     38    public void testWebGUI()
     39    {
     40        RowLayout layout;
     41        NewUserForm form = new NewUserForm(null); // We skip the roles by not providing a DbControl
     42        form.pwdFS.setOpen(false);
     43        LayoutConverter lconverter;
     44        Tag html;
     45        layout = new RowLayout();
     46        layout.add(form);
     47        lconverter = new LayoutConverter(".", null);
     48        lconverter.setLocalizer(locale);
     49        lconverter.setIconSet(iconSet);
     50        layout.setConverter(lconverter);
     51        html = layout.getHtml(".", null);
     52        out.printToFile(html, "TEST_NewUserForm.html");
     53    }
    5654}
  • trunk/client/servlet/www/static/css/layout2.jsp

    r3762 r3894  
    221221}
    222222
     223
    223224div.form form div.legend
    224225{
     
    226227  border-style: solid;
    227228  border-color: #fff;
     229  cursor: default;
     230}
     231
     232div.form form div.legend div.toggle
     233{
     234    float: left;
     235    width: 10px;
     236    border: 0px;
    228237}
    229238
     
    233242  padding: 10px 10px;
    234243}
     244
     245
    235246
    236247div.form form fieldset div.fields table.field
  • trunk/client/servlet/www/static/js/script.js

    r3628 r3894  
    55var CONTEXT = "/proteios/app?action=";
    66
     7function empty() { return true; }
    78function rightGo(action)
    89{
     
    116117  {
    117118    div.style.display = "block";
     119  }
     120}
     121
     122/* Toggles visibility of a fieldset */
     123function toggleFieldset(id)
     124{
     125  var node = getElement(id);
     126  var icon = getElement("btn" + id);
     127  if(node.style.display == "block")
     128  {
     129    node.style.display = "none";
     130    icon.innerHTML = "+";
     131  }
     132  else
     133  {
     134    node.style.display = "block";
     135    icon.innerHTML = "-";
    118136  }
    119137}
Note: See TracChangeset for help on using the changeset viewer.