source: trunk/www/common/datafiles/select_files.jsp @ 5915

Last change on this file since 5915 was 5915, checked in by Nicklas Nordborg, 10 years ago

References #1655: GUI improvements

  • Physical, derived and raw bioassay edit dialogs
  • Data files dialog tab
  • Spotimages and raw data dialogs
  • Some other minor size adjustments
  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 17.5 KB
Line 
1<%-- $Id:select_files.jsp 3820 2007-10-12 10:03:18Z 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--%>
25<%@ page pageEncoding="UTF-8" session="false"
26  import="net.sf.basedb.core.SessionControl"
27  import="net.sf.basedb.core.DbControl"
28  import="net.sf.basedb.core.Item"
29  import="net.sf.basedb.core.ItemContext"
30  import="net.sf.basedb.core.Type"
31  import="net.sf.basedb.core.BasicItem"
32  import="net.sf.basedb.core.Permission"
33  import="net.sf.basedb.core.Nameable"
34  import="net.sf.basedb.core.FileStoreEnabled"
35  import="net.sf.basedb.core.FileSet"
36  import="net.sf.basedb.core.FileSetMember"
37  import="net.sf.basedb.core.File"
38  import="net.sf.basedb.core.Platform"
39  import="net.sf.basedb.core.PlatformVariant"
40  import="net.sf.basedb.core.PlatformFileType"
41  import="net.sf.basedb.core.UsableDataFileType"
42  import="net.sf.basedb.core.DataFileType"
43  import="net.sf.basedb.core.Subtypable"
44  import="net.sf.basedb.core.ItemSubtype"
45  import="net.sf.basedb.core.ItemQuery"
46  import="net.sf.basedb.core.Include"
47  import="net.sf.basedb.core.ItemResultList"
48  import="net.sf.basedb.core.PermissionDeniedException"
49  import="net.sf.basedb.core.query.Expressions"
50  import="net.sf.basedb.core.query.Restrictions"
51  import="net.sf.basedb.core.query.Hql"
52  import="net.sf.basedb.core.query.Orders"
53  import="net.sf.basedb.clients.web.Base"
54  import="net.sf.basedb.clients.web.util.HTML"
55  import="net.sf.basedb.util.formatter.Formatter"
56  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
57  import="net.sf.basedb.clients.web.formatter.FormatterSettings"
58  import="net.sf.basedb.util.Values"
59  import="java.util.ArrayList"
60  import="java.util.List"
61  import="java.util.Date"
62  import="java.util.Map"
63  import="java.util.HashMap"
64%>
65<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
66<%
67final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
68final String ID = sc.getId();
69final float scale = Base.getScale(sc);
70final Item itemType = Item.valueOf(request.getParameter("item_type"));
71final int itemId = Values.getInt(request.getParameter("item_id"));
72final int platformId = Values.getInt(request.getParameter("platform_id"), -1);
73final int variantId = Values.getInt(request.getParameter("variant_id"), -1);
74final int itemSubtypeId = Values.getInt(request.getParameter("itemsubtype_id"), -1);
75final ItemContext cc = sc.getCurrentContext(itemType);
76
77final DbControl dc = sc.newDbControl();
78try
79{
80
81  // Get the current item; null if we are editing a new item
82  final FileStoreEnabled item = itemId == 0 ? null : (FileStoreEnabled)itemType.getById(dc, itemId);
83  FileSet fileSet = null;
84  // Get the current files organized per data file type
85  Map<DataFileType, List<FileSetMember>> members = new HashMap<DataFileType, List<FileSetMember>>();
86  if (item != null && item.hasFileSet())
87  {
88    fileSet = item.getFileSet();
89    ItemQuery<FileSetMember> query = fileSet.getMembers();
90    query.order(Orders.asc(Hql.property("dataFileType.name")));
91    query.order(Orders.asc(Hql.property("file.name")));
92    List<FileSetMember> all = query.list(dc);
93    for (FileSetMember m : all)
94    {
95      DataFileType dft = m.getDataFileType();
96      List<FileSetMember> tmp = members.get(dft);
97      if (tmp == null)
98      {
99        tmp = new ArrayList<FileSetMember>();
100        members.put(dft, tmp);
101      }
102      tmp.add(m);
103    }
104  }
105
106  // Get the current platform/variant/itemsubtype
107  // -- if not submitted in URL use values from current item
108  PlatformVariant variant = null;
109  Platform platform = null;
110  ItemSubtype itemSubtype = null;
111  boolean deniedPlatform = false;
112  try
113  {
114    if (itemSubtypeId > 0)
115    {
116      itemSubtype = ItemSubtype.getById(dc, itemSubtypeId);
117    }
118    else if (item instanceof Subtypable)
119    {
120      itemSubtype = ((Subtypable)item).getItemSubtype();
121    }
122    if (variantId > 0)
123    {
124      variant = PlatformVariant.getById(dc, variantId);
125      platform = variant.getPlatform();
126    }
127    else if (platformId > 0)
128    {
129      platform = Platform.getById(dc, platformId);
130    }
131    else if (item != null)
132    {
133      variant = item.getVariant();
134      platform = item.getPlatform();
135    }
136  }
137  catch (PermissionDeniedException ex)
138  {
139    deniedPlatform = true; 
140  }
141 
142  // Query to load data file types for specific itemType/platform/variant
143  final ItemQuery<DataFileType> fileTypeQuery = 
144    Base.getDataFileTypes(itemType, item, platform, variant, itemSubtype);
145  List<DataFileType> fileTypes = fileTypeQuery.list(dc);
146  String title = "Select data files for " + 
147    HTML.encodeTags((item instanceof Nameable ? ((Nameable)item).getName() : 
148      (item == null ? " new item" : item.toString())));
149
150  final String clazz = "class=\"text\"";
151  final String requiredClazz = "class=\"text required\"";
152  %>
153  <base:page type="popup" title="<%=title%>">
154  <base:head >
155 
156  <script language="JavaScript">
157  function init()
158  {
159    if (document.body.addEventListener)
160    {
161      // Mozilla
162      document.body.addEventListener('click', hideVisibleRecentFilesDiv, false);
163    }
164    else
165    {
166      // IE.
167      document.body.onclick = hideVisibleRecentFilesDiv;
168    }
169  }
170 
171  var lastFileTypeId;
172  var lastHasValidator = false;
173  function addFilesOnClick(event, fileTypeId, extension, hasValidator)
174  {
175    var frm = document.forms['datafiles'];
176    var url = '../../filemanager/index.jsp?ID=<%=ID%>&cmd=SelectMultiple&callback=addFileCallback';
177    if (extension)
178    {
179      url += '&resetTemporary=1&tmpfilter:STRING:name='+escape('%.' + extension);
180    }
181    else
182    {
183      url += '&resetTemporary=1&filter:STRING:name=';
184    }
185    lastFileTypeId = fileTypeId;
186    lastHasValidator = hasValidator;
187    Main.openPopup(url, 'SelectFile', 1000, 700);
188    if (event.stopPropagation)
189    {
190      event.stopPropagation();
191    }
192    else
193    {
194      event.cancelBubble = true;
195    }
196  }
197  function addFileCallback(fileId, path)
198  {
199    addFile(lastFileTypeId, fileId, path, lastHasValidator);
200  }
201 
202  function browseOnClick(event, fileTypeId, extension, hasValidator)
203  {
204    var frm = document.forms['datafiles'];
205    var url = '../../filemanager/index.jsp?ID=<%=ID%>&cmd=SelectOne&callback=setFileCallback';
206    if (extension)
207    {
208      url += '&resetTemporary=1&tmpfilter:STRING:name='+escape('%.' + extension);
209    }
210    else
211    {
212      url += '&resetTemporary=1&filter:STRING:name=';
213    }
214    lastFileTypeId = fileTypeId;
215    lastHasValidator = hasValidator;
216    Main.openPopup(url, 'SelectFile', 1000, 700);
217    if (event.stopPropagation)
218    {
219      event.stopPropagation();
220    }
221    else
222    {
223      event.cancelBubble = true;
224    }
225  }
226  function setFileCallback(fileId, path)
227  {
228    setFile(lastFileTypeId, fileId, path, lastHasValidator);
229  }
230  function setFile(fileTypeId, fileId, path, hasValidator)
231  {
232    var frm = document.forms['datafiles'];
233    var fileDiv = document.getElementById('filelist.'+fileTypeId);
234    if (fileId)
235    {
236      fileDiv.innerHTML = '<div id="filelist.'+fileTypeId+'.'+fileId+'" class="file">'+path+'</div>';
237    }
238    else
239    {
240      fileDiv.innerHTML = '';
241    }
242    if (hasValidator) frm['datafiles.validate'].checked = true;
243    new FileAction('setfile', fileTypeId, fileId);
244  }
245  function addFile(fileTypeId, fileId, path, hasValidator)
246  {
247    var frm = document.forms['datafiles'];
248    var fileDiv = document.getElementById('filelist.'+fileTypeId+'.'+fileId);
249    if (fileDiv) return;
250   
251    fileDiv = document.createElement('div');
252    fileDiv.id = 'filelist.'+fileTypeId+'.'+fileId;
253    var html = path + ' <span  class="icon link" title="Remove this file"';
254    html += ' onclick="removeFileOnClick(event,'+fileTypeId + ',' + fileId + ',' + hasValidator +')">';
255    html += '<img src="' + getRoot() + 'images/remove.png"></span>';
256    fileDiv.innerHTML = html;
257    document.getElementById('filelist.'+fileTypeId).appendChild(fileDiv);
258    if (hasValidator) frm['datafiles.validate'].checked = true;
259    new FileAction('addfile', fileTypeId, fileId);
260  }
261  function removeFileOnClick(event, fileTypeId, fileId, hasValidator)
262  {
263    var frm = document.forms['datafiles'];
264    var fileDiv = document.getElementById('filelist.'+fileTypeId+'.'+fileId);
265    document.getElementById('filelist.'+fileTypeId).removeChild(fileDiv);
266    if (hasValidator) frm['datafiles.validate'].checked = true;
267    new FileAction('removefile', fileTypeId, fileId);
268    if (event.stopPropagation)
269    {
270      event.stopPropagation();
271    }
272    else
273    {
274      event.cancelBubble = true;
275    }
276  }
277 
278  var fileActions = new Array();
279  function FileAction(action, fileTypeId, fileId)
280  {
281    this.action = action;
282    this.fileTypeId = fileTypeId;
283    this.fileId = fileId;
284
285    for (var i = fileActions.length-1; i >= 0; i--)
286    {
287      var other = fileActions[i];
288      var remove = false;
289      if (action == 'setfile')
290      {
291        // Remove all other actions for the given file type
292        remove = other.fileTypeId == this.fileTypeId;
293      }
294      else
295      {
296        // Remove all other actions for the given file type+file
297        remove = other.fileTypeId == this.fileTypeId && other.fileId == this.fileId;
298      }
299      if (remove) fileActions.splice(i, 1);
300    }
301    fileActions[fileActions.length] = this;
302  }
303 
304  function writeFileActionsToForm(toForm)
305  {
306    var frm = document.forms['datafiles'];
307    if (frm['datafiles.validate'])
308    {
309      Forms.createHidden(toForm, 'datafiles.validate', frm['datafiles.validate'].checked ? 1 : 0);
310    }
311    for (var i = 0; i < fileActions.length; i++)
312    {
313      var action = fileActions[i];
314      Forms.createHidden(toForm, action.action + '.' + action.fileTypeId, action.fileId);
315    }
316  }
317 
318  var visibleRecentFilesDiv = null;
319  function recentFilesOnClick(event, fileTypeId)
320  {
321    var recentDiv = document.getElementById('recentfiles.'+fileTypeId);
322    var currentDiv = visibleRecentFilesDiv;
323    hideVisibleRecentFilesDiv();
324    if (currentDiv == recentDiv) return;
325   
326    var fileContainer = document.getElementById('container.'+fileTypeId);
327    var pos = Main.getElementPosition(fileContainer, true);
328    Main.show('recentfiles.'+fileTypeId);
329   
330    recentDiv.style.top = (pos.bottom-2) + 'px';
331    recentDiv.style.left = (pos.left) + 'px';
332    recentDiv.style.width = (pos.width-2) + 'px';
333
334    visibleRecentFilesDiv = recentDiv;
335    if (event.stopPropagation)
336    {
337      event.stopPropagation();
338    }
339    else
340    {
341      event.cancelBubble = true;
342    }
343  }
344
345  function selectRecentFile(fileTypeId, fileId, allowMultiple, hasValidator)
346  {
347    var path = document.getElementById('recentfile.'+fileTypeId+'.'+fileId).innerHTML;
348    if (allowMultiple)
349    {
350      addFile(fileTypeId, fileId, path, hasValidator);
351    }
352    else
353    {
354      setFile(fileTypeId, fileId, path, hasValidator);
355    }
356  }
357 
358  function hideVisibleRecentFilesDiv()
359  {
360    if (visibleRecentFilesDiv)
361    {
362      visibleRecentFilesDiv.style.display = 'none';
363      visibleRecentFilesDiv = null;
364    }
365  }
366  </script>
367  <style>
368  .filelist
369  {
370    margin-top: 1px;
371    border: 1px dotted #A0A0A0;
372    border-radius: 4px;
373    -moz-border-radius: 3px;
374    padding: 1px 2px 1px 2px;
375  }
376
377  .filelist:hover
378  {
379    border: 1px solid #2288AA;
380  }
381
382  .fileaction
383  {
384    width: 20px;
385    text-align: center;
386  }
387
388  .recentfiles
389  {
390    position: absolute;
391    top: 0px;
392    left: 0px;
393    border: 1px solid #A0A0A0;
394    border-radius: 0px 0px 4px 4px;
395    -moz-border-radius: 0px 0px 3px 3px;
396    background-color: #F0F0F0;
397    text-align: left;
398  }
399  .recentfiles .recentfile
400  {
401    padding: 2px;
402    border-top: 1px dotted #A0A0A0;
403  }
404 
405  .recentfiles .recentfile:first-child
406  {
407    border-top: 1px solid transparent;
408  }
409 
410  .recentfiles .recentfile:hover
411  {
412    cursor: pointer;
413    padding: 1px 0px 0px 0px;
414    border: 2px solid #2288AA;
415    border-radius: 4px;
416    -moz-border-radius: 3px;
417  }
418  </style>
419  </base:head>
420  <base:body onload="init()">
421
422    <div class="absolutefull filled">
423    <%
424    boolean hasNonPlatformFiles = false;     
425    boolean activateCheckBoxes = false;
426    boolean validationSupport = false;
427    if (fileTypes.size() == 0)
428    {
429      String what = "";
430      if (platform != null)
431      {
432        what = "'" + HTML.encodeTags(platform.getName()) + "' platform";
433      }
434      else if (itemSubtype != null)
435      {
436        what = "'" + HTML.encodeTags(itemSubtype.getName()) + "' subtype";
437      }
438      %>
439      <div class="messagecontainer error">
440        The <%=what%> doesn't define any file types for
441        <%=itemType.toString() %> items.
442      </div>
443      <%
444    }
445    else if (deniedPlatform)
446    {
447      %>
448      <div class="messagecontainer error">Denied</div>
449      <%
450    }
451    else
452    {
453      %>
454      <table class="fullform larger">
455      <%
456      for (DataFileType dft : fileTypes)
457      {
458        String dftId = Integer.toString(dft.getId());
459        String fullLabel = dft.getName();
460        String label = Values.trimString(fullLabel, 25);
461       
462        UsableDataFileType usable = null;
463        if (platform != null) 
464        {
465          usable = platform.getFileType(dft, variant, false);
466          if (usable == null && variant != null)
467          {
468            // If file type is not registered with a variant, also check if it is inherited from platform
469            usable = platform.getFileType(dft, null, false);
470          }
471        }
472        else if (itemSubtype != null)
473        {
474          usable = itemSubtype.getAssociatedDataFileType(dft, false);
475        }
476       
477        boolean isPartOfPlatform = usable != null;
478        boolean isRequired = usable == null ? false : usable.isRequired();
479        boolean allowMultiple = usable == null ? false : usable.getAllowMultiple();
480        String extension = dft.getExtension();
481        boolean hasValidator = dft.hasActiveValidator(dc);
482        validationSupport |= hasValidator;
483        List<FileSetMember> files = members.get(dft);
484        List<File> recentFiles = (List<File>)cc.getRecent(dc, Item.FILE, dft.getExternalId());
485        %>
486        <tr>
487          <th title="<%=HTML.encodeTags(fullLabel)%>">
488            <%
489            if (!isPartOfPlatform && !deniedPlatform)
490            {
491              hasNonPlatformFiles = true;
492              %>
493              <base:icon image="warning.gif" 
494                tooltip="This file is not part of the platform/subtype" 
495                style="float: left; margin-right: 2px; vertical-align: top;"
496                />
497              <%
498            }
499            %>
500            <%=HTML.encodeTags(label)%>
501          </th>
502          <td onclick="<%="recentFilesOnClick(event, " + dftId + ")"%>">
503            <div class="filelist <%=isRequired ? "required" : "" %>" id="container.<%=dftId%>">
504            <table style="width: 100%;">
505            <tr><td id="filelist.<%=dftId%>">
506              <%
507              if (files != null && files.size() > 0)
508              {
509                for (FileSetMember fm : files)
510                {
511                  File file = fm.getFile();
512                  %>
513                  <div id="filelist.<%=dftId%>.<%=file.getId()%>" class="file">
514                  <%=file.getPath() %>
515                  <base:icon image="remove.png" visible="<%=allowMultiple %>"
516                    tooltip="Remove this file"
517                    onclick="<%="removeFileOnClick(event, " + dftId + "," + file.getId() + "," + hasValidator + ")" %>"
518                  />
519                  </div>
520                  <%
521                }
522              }
523              %>
524              </td>
525              <td class="fileaction">
526                <base:icon image="mini_scroll_down.png" 
527                  visible="<%=recentFiles.size() >= 0 %>"
528                  tooltip="Select a recently used file"
529                  onclick="<%="recentFilesOnClick(event, " + dftId + ")"%>"
530                />
531              </td>
532              <td class="fileaction">
533                <base:icon image="add.png" 
534                  onclick="<%="addFilesOnClick(event, "+dftId+", '" + HTML.javaScriptEncode(extension) + "', "+ hasValidator + ")"%>"
535                  visible="<%=allowMultiple %>"
536                />
537                <base:icon image="browse.png" 
538                  onclick="<%="browseOnClick(event, "+dftId+", '" + HTML.javaScriptEncode(extension) + "', "+ hasValidator + ")"%>"
539                  visible="<%=!allowMultiple%>"
540                />
541              </td>
542            </tr>
543            </table>
544            </div>
545
546            <div id="recentfiles.<%=dftId%>" style="display: none;" class="recentfiles">
547              <div class="recentfile"
548                onclick="selectRecentFile(<%=dftId%>, 0, false, <%=hasValidator%>)"
549                id="recentfile.<%=dftId%>.0"
550                ><i>- clear -</i></div>
551              <%
552              for (File recent : recentFiles)
553              {
554                %>
555                <div class="recentfile"
556                  onclick="selectRecentFile(<%=dftId%>, <%=recent.getId()%>, <%=allowMultiple ? 1 : 0 %>, <%=hasValidator%>)"
557                  id="recentfile.<%=dftId%>.<%=recent.getId()%>"
558                  ><%=HTML.encodeTags(recent.getPath().toString())%></div>
559                <%
560              }
561              %>
562            </div>
563
564          </td>
565        </tr>
566        <%
567      }
568      %>
569      <tr class="dynamic">
570        <th></th>
571        <td></td>
572      </tr>
573      </table>
574      <%
575    }
576    %>
577    </div>
578
579      <form name="datafiles">
580      <table width="100%">
581      <tr>
582        <td>
583          <%
584          if (validationSupport)
585          {
586            %>
587            <span title="Enabled this check box to validate and extract metadata from selected files">
588            <label for="validateFiles"><b>Validate files</b></label>
589            <input type="checkbox" value="1" name="datafiles.validate" id="validateFiles">
590            </span>
591            <%
592          }
593          %>
594        </td>
595        <td>
596          <%
597          if (hasNonPlatformFiles)
598          {
599            if (platform != null)
600            {
601              %>
602              <div align="right">
603              <base:icon image="warning.gif" /> 
604              = The file type is not part of the <i><%=HTML.encodeTags(platform.getName())%></i> platform
605              </div>
606              <%
607            }
608            else if (itemSubtype != null)
609            {
610              %>
611              <div align="right">
612              <base:icon image="warning.gif" /> 
613              = The file type is not part of the <i><%=HTML.encodeTags(itemSubtype.getName())%></i> subtype
614              </div>
615              <%
616            }
617          }
618          %>
619        </td>
620      </table>
621    </form>
622  </base:body>
623  </base:page>
624  <%
625}
626finally
627{
628  if (dc != null) dc.close();
629}
630%>
Note: See TracBrowser for help on using the repository browser.