source: trunk/www/common/annotations/annotate.jsp @ 6946

Last change on this file since 6946 was 6946, checked in by Nicklas Nordborg, 6 years ago

References #1941: Store experimental factor values as part experiments

Adding 'check all' icons to the annotations list and put some operations in a submenu to save space.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 26.4 KB
Line 
1<%-- $Id: annotate.jsp 6946 2015-09-07 07:08:13Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2005 Nicklas Nordborg
4  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg
5  Copyright (C) 2007 Nicklas Nordborg
6
7  This file is part of BASE - BioArray Software Environment.
8  Available at http://base.thep.lu.se/
9
10  BASE is free software; you can redistribute it and/or
11  modify it under the terms of the GNU General Public License
12  as published by the Free Software Foundation; either version 3
13  of the License, or (at your option) any later version.
14
15  BASE is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with BASE. If not, see <http://www.gnu.org/licenses/>.
22  ------------------------------------------------------------------
23 
24  @author Nicklas
25  @version 2.0
26--%>
27<%@ page pageEncoding="UTF-8" session="false"
28  import="net.sf.basedb.core.SessionControl"
29  import="net.sf.basedb.core.DbControl"
30  import="net.sf.basedb.core.Item"
31  import="net.sf.basedb.core.Type"
32  import="net.sf.basedb.core.BasicItem"
33  import="net.sf.basedb.core.Permission"
34  import="net.sf.basedb.core.Annotatable"
35  import="net.sf.basedb.core.Nameable"
36  import="net.sf.basedb.core.Protocol"
37  import="net.sf.basedb.core.Subtypable"
38  import="net.sf.basedb.core.ItemSubtype"
39  import="net.sf.basedb.core.BioPlateType"
40  import="net.sf.basedb.core.BioPlate"
41  import="net.sf.basedb.core.AnnotationSet"
42  import="net.sf.basedb.core.Annotation"
43  import="net.sf.basedb.core.Unit"
44  import="net.sf.basedb.core.Quantity"
45  import="net.sf.basedb.core.AnnotatableProxy"
46  import="net.sf.basedb.core.ItemQuery"
47  import="net.sf.basedb.core.Include"
48  import="net.sf.basedb.core.ItemResultList"
49  import="net.sf.basedb.core.AnnotationType"
50  import="net.sf.basedb.core.AnnotationTypeCategory"
51  import="net.sf.basedb.core.PermissionDeniedException"
52  import="net.sf.basedb.core.query.Expressions"
53  import="net.sf.basedb.core.query.Restrictions"
54  import="net.sf.basedb.core.query.Hql"
55  import="net.sf.basedb.core.query.Orders"
56  import="net.sf.basedb.util.NameableComparator"
57  import="net.sf.basedb.clients.web.Base"
58  import="net.sf.basedb.clients.web.util.HTML"
59  import="net.sf.basedb.util.formatter.Formatter"
60  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
61  import="net.sf.basedb.clients.web.formatter.FormatterSettings"
62  import="net.sf.basedb.util.Values"
63  import="org.json.simple.JSONObject"
64  import="org.json.simple.JSONArray"
65  import="java.util.ArrayList"
66  import="java.util.List"
67  import="java.util.Date"
68  import="java.util.Set"
69  import="java.util.HashSet"
70  import="java.util.TreeSet"
71  import="java.util.Map"
72  import="java.util.HashMap"
73%>
74<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
75<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
76<%@ taglib prefix="m" uri="/WEB-INF/menu.tld" %>
77<%!
78private JSONObject makeJSON(DbControl dc, AnnotationType at, Annotation a, boolean isProtocolParameter, Set<AnnotationTypeCategory> allCategories)
79{
80  // Create the JSON objects for holding all info
81  // The base object has 'id', 'source', 'annotationType' and 'annotation'
82  JSONObject json = new JSONObject();
83  json.put("id", ""+at.getId() + (a!=null ? "-" + a.getId() : ""));
84  // If 'a' is null this is a primary annotation that has no current values
85  json.put("source", a == null ? "PRIMARY" : a.getSource().name());
86
87  JSONObject jsonAt = new JSONObject();
88  json.put("annotationType", jsonAt);
89  JSONObject jsonA = new JSONObject();
90  json.put("annotation", jsonA);
91  JSONArray jsonValues = new JSONArray();
92  jsonA.put("values", jsonValues);
93
94  // Load annotation type information
95  Type valueType = at.getValueType();
96  Formatter formatter = FormatterFactory.getTypeFormatter(dc.getSessionControl(), valueType);
97 
98  jsonAt.put("id", at.getId());
99  jsonAt.put("name", at.getName());
100  jsonAt.put("valueType", valueType.name());
101  jsonAt.put("multiplicity", at.getMultiplicity());
102  jsonAt.put("description", HTML.encodeTags(at.getDescription()));
103  jsonAt.put("removed", at.isRemoved());
104  jsonAt.put("protocolParameter", isProtocolParameter);
105
106  if (valueType == Type.STRING)
107  {
108    jsonAt.put("maxLength", at.getMaxLength());
109  }
110  else if (valueType == Type.INT || valueType == Type.LONG)
111  {
112    jsonAt.put("minValue", at.getMinValueLong());
113    jsonAt.put("maxValue", at.getMaxValueLong());
114  }
115  else if (valueType == Type.FLOAT || valueType == Type.DOUBLE)
116  {
117    jsonAt.put("minValue", at.getMinValueDouble());
118    jsonAt.put("maxValue", at.getMaxValueDouble());
119  }
120 
121  // Enumeration
122  if (at.isEnumeration())
123  {
124    List<?> values = at.getValues();
125    JSONArray jsonEnum = new JSONArray();
126    for (Object val : values)
127    {
128      jsonEnum.add(formatter.format(val));
129    }
130    jsonAt.put("enumeration", jsonEnum);
131    jsonAt.put("displayAsList", at.getDisplayAsList());
132  }
133 
134  // Units
135  if (at.supportUnits())
136  {
137    Unit defaultUnit = at.getDefaultUnit();
138    jsonAt.put("defaultUnit", defaultUnit.getId());
139    jsonAt.put("defaultSymbol", defaultUnit.getDisplaySymbol());
140   
141    if (!at.isEnumeration())
142    {
143      ItemQuery<Unit> unitQuery = at.getUsableUnits();
144      if (unitQuery.count(dc) == 0)
145      {
146        unitQuery = at.getQuantity().getUnits();
147      }
148      else
149      {
150        unitQuery.reset();
151      }
152      unitQuery.order(Orders.desc(Hql.property("referenceFactor")));
153      unitQuery.order(Orders.asc(Hql.property("displaySymbol")));
154      List<Unit> units = new ArrayList<Unit>(unitQuery.list(dc));
155      if (!units.contains(defaultUnit)) units.add(defaultUnit);
156     
157      Unit currentUnit = a != null ? a.getUnit() : null;
158      if (currentUnit != null && !units.contains(currentUnit)) units.add(currentUnit);
159     
160      JSONArray jsonUnits = new JSONArray();
161      for (Unit unit : units)
162      {
163        JSONObject jsonUnit = new JSONObject();
164        jsonUnit.put("id", unit.getId());
165        jsonUnit.put("description", HTML.encodeTags(unit.getName() + " - " + unit.getDescription()));
166        jsonUnit.put("symbol", HTML.encodeTags(unit.getDisplaySymbol()));
167        jsonUnits.add(jsonUnit);
168      }
169      jsonAt.put("units", jsonUnits);
170    }
171  }
172 
173  // Categories
174  JSONArray jsonCategories = new JSONArray();
175  ItemQuery<AnnotationTypeCategory> categoryQuery = at.getCategories();
176  categoryQuery.include(Include.MINE, Include.OTHERS, Include.SHARED, Include.IN_PROJECT);
177  categoryQuery.join(Hql.innerJoin("annotationTypes", "atp"));
178  categoryQuery.restrict(Restrictions.eq(Hql.alias("atp"), Hql.entity(at)));
179  for (AnnotationTypeCategory category : categoryQuery.list(dc))
180  {
181    allCategories.add(category);
182    jsonCategories.add(category.getId());
183  }
184  jsonAt.put("categories", jsonCategories);
185
186 
187  if (a != null)
188  {
189    createJSON(jsonA, dc, a, formatter, false);
190   
191    if (a.getSource() != Annotation.Source.PRIMARY)
192    {
193      Annotation inherited = a.getInheritedFrom();
194      if (inherited != null)
195      {
196        JSONObject jsonInherited = new JSONObject();
197        createJSON(jsonInherited, dc, inherited, formatter, true);
198        Annotatable inheritedFrom = inherited.getAnnotationSet().getItem(dc);
199        JSONObject jsonFrom = new JSONObject();
200        jsonFrom.put("id", inheritedFrom.getId());
201        jsonFrom.put("name", ((Nameable)inheritedFrom).getName());
202        jsonFrom.put("type", inheritedFrom.getType().name());
203        jsonInherited.put("from", jsonFrom);
204        json.put("inherited", jsonInherited);
205      }
206    }
207
208  }
209
210  return json;
211}
212
213private void createJSON(JSONObject json, DbControl dc, Annotation a, Formatter formatter, boolean formatAll)
214{
215  json.put("id", a.getId());
216  Date lastUpdate = a.getLastUpdate();
217  if (lastUpdate != null) json.put("lastUpdate",  lastUpdate.getTime());
218 
219  Unit currentUnit = a.getUnit();
220  if (currentUnit != null) 
221  {
222    json.put("unit", currentUnit.getId());
223    json.put("unitSymbol", currentUnit.getDisplaySymbol());
224  }
225 
226  // Populate the values array
227  List values = a.getValues(null);
228  if (values != null)
229  {
230    JSONArray jsonValues = new JSONArray();
231    json.put("values", jsonValues);
232   
233    for (Object value : values)
234    {
235      // Dates should be formatted to strings using the current date(time) format
236      if (formatAll || value instanceof Date) 
237      {
238        value = formatter.format(value);
239      }
240      jsonValues.add(value.toString());
241    }
242  }
243 
244}
245
246%>
247<%
248final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
249final String ID = sc.getId();
250final float scale = Base.getScale(sc);
251final Item itemType = Item.valueOf(request.getParameter("item_type"));
252final int itemId = Values.getInt(request.getParameter("item_id"));
253final int protocolId = Values.getInt(request.getParameter("protocol_id"), -1);
254final int subtypeId = Values.getInt(request.getParameter("subtype_id"), -1);
255final int annotationId = Values.getInt(request.getParameter("annotation_id"));
256int annotationTypeId = Values.getInt(request.getParameter("annotationtype_id"));
257final boolean standalone = Values.getBoolean(request.getParameter("standalone"));
258
259final DbControl dc = sc.newDbControl();
260try
261{
262  // Date and time formats
263  String dateFormat = FormatterSettings.getDateFormat(sc);
264  String htmlDateFormat = HTML.encodeTags(dateFormat);
265  String dateTimeFormat = FormatterSettings.getDateTimeFormat(sc);
266  String htmlDateTimeFormat = HTML.encodeTags(dateTimeFormat);
267 
268  Annotatable item = null;
269 
270  if (annotationId != 0)
271  {
272    Annotation a = Annotation.getById(dc, annotationId);
273    item = a.getAnnotationSet().getItem();
274    annotationTypeId = a.getAnnotationType().getId();
275  }
276  else if (itemId != 0)
277  {
278    item = (Annotatable)itemType.getById(dc, itemId);
279  }
280  final boolean writePermission = item == null ? true : item.hasPermission(Permission.WRITE);
281 
282  // Load the current item and it's protocol
283  // NOTE! User may have selected a different protocol in the form than what is
284  // currently saved so if a protocol_id is sent in the request we use that
285  Protocol protocol = null;
286  boolean readProtocol = true;
287  try
288  {
289    if (protocolId == - 1 && item != null)
290    {
291      protocol = item.getProtocol();
292    }
293    else if (protocolId > 0)
294    {
295      protocol = Protocol.getById(dc, protocolId);
296    }
297  }
298  catch (PermissionDeniedException ex)
299  {
300    readProtocol = false;
301  }
302 
303  // Load the current subtype
304  // NOTE! User may have selected a different subtype in the form than what is
305  // currently saved so if a subtype_id is sent in the request we use that
306  String selectedCategoryName = null;
307  try
308  {
309    ItemSubtype subtype = null;
310    if (subtypeId > 0)
311    {
312      subtype = ItemSubtype.getById(dc, subtypeId);
313    }
314    else if (item instanceof Subtypable)
315    {
316      subtype = ((Subtypable)item).getItemSubtype();
317    }
318    else if (item instanceof BioPlate)
319    {
320      BioPlateType bpt = ((BioPlate)item).getBioPlateType();
321      subtype = bpt.getItemSubtype();
322      if (subtype == null) selectedCategoryName = bpt.getName();
323    }
324    if (subtype != null) selectedCategoryName = subtype.getName();
325  }
326  catch (PermissionDeniedException ex)
327  {}
328 
329  //selectedCategoryName = "Test"; // DEBUG!!
330 
331  if (standalone)
332  {
333    sc.getCurrentContext(itemType).setObject("item", item); 
334  }
335
336  String title = "Annotate " + 
337    HTML.encodeTags((item instanceof Nameable ? ((Nameable)item).getName() : 
338      (item == null ? " new item" : item.toString())));
339
340  // Queries to retrieve annotation types and protocol parameters
341  ItemQuery<AnnotationType> annotationTypeQuery = null;
342  String message = null;
343  if (item instanceof AnnotatableProxy)
344  {
345    AnnotatableProxy proxy = (AnnotatableProxy)item;
346    annotationTypeQuery = Base.getAnnotationTypesQuery(proxy);
347    message = proxy.getAnnotationMessage();
348  }
349  else
350  {
351    annotationTypeQuery = Base.getAnnotationTypesQuery(itemType, false);
352  }
353  final ItemQuery<AnnotationType> parameterQuery = Base.getProtocolParametersQuery(protocol);
354
355  // Holds all categories that we have found
356  final Set<AnnotationTypeCategory> allCategories = 
357    new TreeSet<AnnotationTypeCategory>(new NameableComparator(false));
358 
359  // Load existing annotations
360  AnnotationSet as = null;
361  Map<AnnotationType, Annotation> primary = new HashMap<AnnotationType, Annotation>();
362  List<Annotation> inherited = new ArrayList<Annotation>();
363  if (item != null && item.isAnnotated())
364  {
365    // Load the existing annotations
366    as = item.getAnnotationSet();
367    ItemQuery<Annotation> aQuery = as.getAnnotations(null);
368    aQuery.order(Orders.asc(Hql.property("annotationType.name")));
369    List<Annotation> annotations = aQuery.list(dc);
370    for (Annotation a : annotations)
371    {
372      try
373      {
374        if (a.getSource() == Annotation.Source.PRIMARY)
375        {
376          primary.put(a.getAnnotationType(), a);
377        }
378        else
379        {
380          inherited.add(a);
381        }
382      }
383      catch (PermissionDeniedException ex)
384      {}
385    }
386  }
387 
388  // Load all annotation types that available from multiple sources:
389  // * As defined by the server admin for the current item type
390  // * Existing on the current item
391  // * Defined as protocol parameters for the current protocol
392  Set<AnnotationType> annotationTypes = new TreeSet<AnnotationType>(new NameableComparator(false));
393  Set<AnnotationType> protocolParameters = new HashSet<AnnotationType>();
394  annotationTypes.addAll(annotationTypeQuery.list(dc));
395  annotationTypes.addAll(primary.keySet());
396  if (parameterQuery != null) 
397  {
398    protocolParameters.addAll(parameterQuery.list(dc));
399    annotationTypes.addAll(protocolParameters);
400  }
401
402  // Build JSON objects for all annotation types, the current values and annotation type categories
403  JSONArray jsonAnnotations = new JSONArray();
404  for (AnnotationType at : annotationTypes)
405  {
406    Annotation a = primary.get(at);
407    if (at.isRemoved() && a == null) continue;
408    JSONObject json = makeJSON(dc, at, a, protocolParameters.contains(at), allCategories);
409    jsonAnnotations.add(json);
410  }
411  for (Annotation a : inherited)
412  {
413    AnnotationType at = a.getAnnotationType();
414    JSONObject json = makeJSON(dc, at, a, false, allCategories);
415    jsonAnnotations.add(json);
416  }
417  %>
418  <base:page type="<%=standalone ? "popup" : "iframe"%>" title="<%=title%>">
419  <base:head scripts="~annotate.js,menu.js" styles="parameters.css,toolbar.css,menu.css">
420  <style>
421  .first-primary:before
422  {
423    content: '― Primary Annotations ―';
424    font-variant: small-caps;
425    font-size: 80%;
426    font-weight: bold;
427    color: #999999;
428  }
429 
430  .first-inherited:before
431  {
432    content: '― Inherited & Cloned ―';
433    font-variant: small-caps;
434    font-size: 80%;
435    font-weight: bold;
436    color: #999999;
437  }
438 
439 
440  .parameterlist .param
441  {
442    padding-right: 20px;
443  }
444  .parameterlist .param.selected
445  {
446    padding-right: 20px;
447  }
448  .parameterlist .param:hover
449  {
450    padding-right: 18px;
451  }
452 
453  .parameterlist .param input, .parameterlist .check-all
454  {
455    position: absolute;
456    right: 1px;
457    margin-top: 1px;
458  }
459  .parameterlist .check-all
460  {
461    padding-right: 2px;
462  }
463 
464  #selected-name
465  {
466    font-weight: bold;
467  }
468 
469  #selected-description
470  {
471    margin-left: 0px;
472    margin-right: 0px;
473    display: none;
474  }
475 
476  #none-selected
477  {
478    display: none;
479    margin-top: 2em;
480  }
481 
482  #selected-container > div
483  {
484    display: none;
485  }
486 
487  #selected-container.none-selected #none-selected
488  {
489    display: block;
490  }
491  #selected-container.none-selected.no-annotations #none-selected
492  {
493    display: none;
494  }
495 
496  #selected-container.has-selected #info-container
497  {
498    display: block;
499  }
500 
501  #selected-container.has-description #selected-description
502  {
503    display: block;
504  }
505
506  #selected-container.INHERITED #inherited-container,
507  #selected-container.CLONED #inherited-container
508  {
509    display: block;
510    border-left-width: 2px;
511    padding: 2px 5px;
512    margin: 0.5em 0;
513  }
514
515  #selected-container.inherited-missing #inherited-missing
516  {
517    display: block;
518    border-left-width: 2px;
519    padding: 2px 5px;
520    margin: 0.5em 0;
521  }
522  #selected-container.inherited-missing #inherited-container
523  {
524    display: none;
525  }
526 
527  #inherited-item
528  {
529    font-style: italic;
530  }
531 
532  #inherited-modified, #inherited-clone
533  {
534    display: none;
535  }
536
537  #selected-container.modified #inherited-modified
538  {
539    display: inline;
540  }
541 
542  #selected-container.INHERITED #inherited-clone
543  {
544    display: inline;
545  }
546 
547  #selected-container.PRIMARY #input-container,
548  #selected-container.CLONED #input-container
549  {
550    display: block;
551  }
552 
553  #input-container > div
554  {
555    display: none;
556  }
557 
558  #selected-container.ENUM-SINGLE #ENUM-SINGLE
559  {
560    display: block;
561  }
562  #selected-container.ENUM-MULTIPLE #ENUM-MULTIPLE
563  {
564    display: block;
565  }
566  #selected-container.ENUM-RADIO-CHECKBOX #ENUM-RADIO-CHECKBOX
567  {
568    display: block;
569  }
570  #selected-container.STRING #STRING-container
571  {
572    display: block;
573  }
574  #selected-container.TEXT #TEXT-container
575  {
576    display: block;
577  }
578  #selected-container.INT #INT-container
579  {
580    display: block;
581  }
582  #selected-container.LONG #LONG-container
583  {
584    display: block;
585  }
586  #selected-container.FLOAT #FLOAT-container
587  {
588    display: block;
589  }
590  #selected-container.DOUBLE #DOUBLE-container
591  {
592    display: block;
593  }
594  #selected-container.BOOLEAN #BOOLEAN-container
595  {
596    display: block;
597  }
598  #selected-container.DATE #DATE-container
599  {
600    display: block;
601  }
602  #selected-container.TIMESTAMP #TIMESTAMP-container
603  {
604    display: block;
605  }
606  #selected-container.has-unit .numeric
607  {
608    float: left;
609    margin-right: 0.25em;
610  }
611  #selected-container.has-unit #unit-container
612  {
613    display: block;
614  }
615  .not-specified
616  {
617    font-style: italic;
618  }
619  </style>
620  </base:head>
621  <base:body>
622    <%
623    if (standalone)
624    {
625      %>
626      <h1><%=title%> <base:help helpid="annotations.edit" /></h1>
627      <div class="content">
628      <%
629    }
630    %>
631    <div id="page-data" class="datacontainer"
632      data-annotations="<%=HTML.encodeTags(jsonAnnotations.toJSONString()) %>"
633      data-annotation-type-id="<%=annotationTypeId%>"
634      data-annotation-id="<%=annotationId %>"
635      data-date-format="<%=htmlDateFormat%>"
636      data-datetime-format="<%=htmlDateTimeFormat%>"
637      ></div>
638    <form name="annotations">
639   
640    <m:menu
641      id="more-actions"
642      style="display: none;"> 
643      <m:menuitem id="btnSync" title="Sync" icon="cloned-outofsync.png" 
644        tooltip="Synchronize the selected annotation"
645      />
646      <m:menuitem id="btnClone" title="Clone" icon="cloned.png" 
647        tooltip="Clone the selected annotations"
648      />
649      <m:menuitem id="btnUnclone" title="Unclone" icon="inherited.png" 
650        tooltip="Revert cloned annotations to inherited"
651      />
652    </m:menu>
653   
654   
655    <div class="absolutefull">
656      <div class="absolutefull bg-filled-100 rightborder" style="width: 18em;">
657        <div class="absolutefull" style="height: 2em;">
658          <table style="margin: auto; height: 100%;"><tr><td>
659          <base:icon image="filter.png" />
660          <select name="categories" id="categories" style="width: 15em;">
661          <option value="-1">- all -
662          <%
663          if (protocol != null)
664          {
665            %>
666            <option value="-2">- protocol parameters -
667            <%
668          }
669          %>
670          <option value="0">- uncategorized -
671          <%
672          for (AnnotationTypeCategory category : allCategories)
673          {
674            boolean selected = category.getName().equals(selectedCategoryName);
675            %>
676            <option value="<%=category.getId()%>"
677              title="<%=HTML.encodeTags(category.getDescription())%>"
678              <%=selected ? "selected" : "" %>
679            ><%=HTML.encodeTags(category.getName())%>
680            <%
681          }
682          %>
683          </select>
684          </td></tr></table>
685        </div>
686       
687        <div id="annotation-list" class="absolutefull parameterlist topborder" 
688          style="top: 2em; bottom: 3em;">
689          <tbl:toolbar subclass="bottomborder">
690            <tbl:button id="btnAdd" title="Inherit&hellip;" image="add.png" 
691              tooltip="Inherit more annotations..."
692            />
693            <tbl:button id="btnDelete" title="Delete" image="remove.png" 
694              tooltip="Delete annotations"
695            />
696            <tbl:button id="btnMore" 
697              subclass="auto-init"
698              data-auto-init="menu-anchor"
699              data-menu-id="more-actions"
700              title="<img src=\"../../images/mini_scroll_down.png\">" image="menu.png"
701              tooltip="More actions..."
702              />
703          </tbl:toolbar>
704          <div id="primary-list">
705            <div class="first-primary">
706              <base:icon id="check-all-primary" image="check_uncheck.png" subclass="check-all" 
707                tooltip="Toggle all (use CTRL, ALT or SHIFT to check/uncheck)"
708              />
709            </div>
710            <%
711            if (annotationTypes.size() == 0 && inherited.size() == 0)
712            {
713              %>
714              <div class="messagecontainer error">
715                There are no annotation types defined for this kind of item.
716              </div>
717              <%
718            }
719            %>
720          </div>
721          <div id="inherited-list">
722            <div class="first-inherited">
723              <base:icon id="check-all-inherited" image="check_uncheck.png" subclass="check-all" 
724                tooltip="Toggle all (use CTRL, ALT or SHIFT to check/uncheck)"
725              />
726            </div>
727          </div>
728        </div>
729       
730        <div class="absolutefull topborder" style="top: auto; bottom: 0em; height: 3em;">
731          <table style="height: 100%; margin:auto;"><tr><td>
732          <base:icon image="hasvalues.png" /> = has value(s)<br>
733          <base:icon image="parameter.png" /> = protocol parameter
734          </td></tr></table>
735        </div>
736      </div>
737     
738      <div class="absolutefull input100" style="left: 18em; padding: 8px;">
739        <%
740        if (message != null)
741        {
742          %>
743          <div class="messagecontainer help" style="margin-top: 0.2em;"><%=message%></div>
744          <%
745        }
746        if (!writePermission)
747        {
748          %>
749          <div class="messagecontainer error">You do not have permission to change this information</div>
750          <%
751        }
752        %>
753        <div id="valuecontainer" style="display: none;">
754          <b>Values</b> <span id="multiplicity"></span><br>
755          <select name="multi-values" id="multi-values" size="5" style="width: 100%;">
756          </select>
757          <table>
758          <tr>
759            <td><base:button id="btnMultiAdd" title="Add" tooltip="Add a new value" /></td>
760            <td><base:button id="btnMultiRemove" title="Remove" tooltip="Remove the selected values"/></td>
761          </tr>
762          </table>
763        <br>
764        </div>
765       
766        <div id="selected-container">
767          <div id="none-selected" class="messagecontainer note">
768            <base:icon image="goback.png" /> Select an annotation.
769          </div>
770
771          <div id="info-container">
772            <span id="selected-name">Name</span>
773            (<span id="selected-type">type</span>)
774          </div>
775         
776          <div id="inherited-container" class="bg-filled-100">
777            <span id="inherited-item"></span><br>
778            <span id="inherited-values"></span>
779            <span id="inherited-modified">(modified; <span id="sync-modified" class="link" title="Synchronize the annotation values with the parent item">sync</span>)</span>
780            <span id="inherited-clone">(<span id="convert-to-cloned" class="link" title="Clone the annotation values from the parent">clone</span>)</span>
781          </div>
782                   
783          <div id="inherited-missing" class="bg-filled-100">
784            Cloned from an unknown item.
785          </div>
786       
787          <div id="input-container">
788         
789            <div id="ENUM-SINGLE">
790              <select name="ENUM-SINGLE-input" id="ENUM-SINGLE-input" 
791                style="min-width: 5em;">
792              </select>
793            </div>
794             
795            <div id="ENUM-MULTIPLE">
796              <select name="ENUM-MULTIPLE-input" id="ENUM-MULTIPLE-input" 
797                multiple size="10" style="min-width: 5em;">
798              </select>
799            </div>
800             
801            <div id="ENUM-RADIO-CHECKBOX">
802              radios/checkboxes
803            </div>
804       
805            <div id="STRING-container">
806              <input name="STRING-input" id="STRING-input" 
807                type="text" class="text"
808                maxlength="255" value="">
809            </div>
810           
811            <div id="TEXT-container">
812              <table style="width: 100%;">
813              <tr>
814                <td>
815                <textarea name="TEXT-input" id="TEXT-input" 
816                  class="text" rows="5"></textarea>
817                </td>
818                <td style="width: 20px;">
819                  <base:icon
820                    id="TEXT-zoom"
821                    image="zoom.png"
822                    tooltip="Edit in larger window" 
823                  />
824                </td>
825              </tr>
826              </table>
827            </div>
828           
829            <div id="INT-container" class="numeric">
830              <input 
831                name="INT-input" id="INT-input"
832                class="text" type="text" 
833                value="" style="width: 12em;" maxlength="20">
834            </div>
835
836            <div id="LONG-container" class="numeric">
837              <input 
838                name="LONG-input" id="LONG-input"
839                class="text" type="text" 
840                value="" style="width: 12em;" maxlength="20">
841            </div>
842           
843            <div id="FLOAT-container" class="numeric">
844              <input 
845                name="FLOAT-input" id="FLOAT-input"
846                class="text" type="text"
847                value="" style="width: 12em;" maxlength="20">
848            </div>
849
850            <div id="DOUBLE-container" class="numeric">
851              <input 
852                name="DOUBLE-input" id="DOUBLE-input"
853                class="text" type="text" 
854                value="" style="width: 12em;" maxlength="20">
855            </div>
856         
857            <div id="unit-container">
858              <select name="unit" id="unit" style="min-width: 5em;"></select>
859            </div>
860           
861            <div id="DATE-container">
862              <table>
863              <tr>
864              <td>
865                <input 
866                  name="DATE-input" id="DATE-input"
867                  class="text" type="text" 
868                  value="" style="width: 15em;" maxlength="20" 
869                  title="Enter date in format: <%=htmlDateFormat%>">
870              </td>
871              <td>
872                <base:button 
873                  id="DATE-calendar"
874                  image="calendar.png"
875                  title="Calendar&hellip;" 
876                  tooltip="Select a date from a calendar"
877                />
878              </td>
879              </tr>
880              </table>
881            </div>
882           
883            <div id="TIMESTAMP-container">
884              <table>
885              <tr>
886              <td>
887                <input 
888                  name="TIMESTAMP-input" id="TIMESTAMP-input"
889                  class="text" type="text" 
890                  value="" style="width: 15em;" maxlength="20" 
891                  title="Enter date + time in format: <%=htmlDateTimeFormat%>">
892              </td>
893              <td>
894                <base:button 
895                  id="TIMESTAMP-calendar"
896                  image="calendar.png"
897                  title="Calendar&hellip;" 
898                  tooltip="Select date and time from a calendar"
899                />
900              </td>
901              </tr>
902              </table>
903            </div>
904         
905            <div id="BOOLEAN-container">
906              <label class="not-specified"><input type="radio" name="BOOLEAN-input" id="BOOLEAN-input-NULL" 
907                value="" checked>- not specified -</label><br>
908              <label><input type="radio" name="BOOLEAN-input" id="BOOLEAN-input-TRUE" 
909                value="true">true</label><br>
910              <label><input type="radio" name="BOOLEAN-input" id="BOOLEAN-input-FALSE"
911                value="false">false</label>
912            </div>
913          </div>
914         
915          <div id="selected-description" class="messagecontainer help">
916          </div>
917        </div>
918 
919      </div>
920    </div>
921    </form>
922    <%
923    if (standalone)
924    {
925      %>
926      </div>
927      <base:buttongroup subclass="dialogbuttons topborder">
928        <base:button id="btnSave" title="Save" visible="<%=writePermission%>" />
929        <base:button id="close" title="Cancel"  visible="<%=writePermission%>" />
930        <base:button id="close" title="Close" visible="<%=!writePermission%>" />
931      </base:buttongroup>
932      <form name="modified" method="post" action="index.jsp?ID=<%=ID%>">
933        <input type="hidden" name="cmd" value="SaveAnnotations">
934        <input type="hidden" name="item_type" value="<%=itemType.name()%>">
935        <input type="hidden" name="item_id" value="<%=itemId%>">
936      </form>
937      <%
938    }
939    %>
940  </base:body>
941  </base:page>
942  <%
943}
944finally
945{
946  if (dc != null) dc.close();
947}
948%>
Note: See TracBrowser for help on using the repository browser.