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

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

References #1655: GUI improvements

Fixes image alignment in several places.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 17.9 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    cursor: pointer;
372  }
373
374  .files
375  {
376    border: 1px solid #A0A0A0;
377    border-right: 0px;
378    border-radius: 4px 0px 0px 4px;
379    -moz-border-radius: 3px 0px 0px 3px;
380    padding: 1px 2px 1px 2px;
381  }
382 
383  .filelist td
384  {
385    padding: 1px;
386  }
387
388  .fileaction
389  {
390    width: 40px;
391    text-align: center;
392    white-space: nowrap;
393    background-color: #E8E8E8;
394    border: 1px solid #A0A0A0;
395    border-radius: 0px 4px 4px 0px;
396    -moz-border-radius: 0px 3px 3px 0px;
397  }
398 
399  .filelist img
400  {
401    vertical-align: middle;
402  }
403 
404  .filelist:hover .files
405  {
406    border-color: #2288AA;
407  }
408 
409   .filelist:hover .fileaction, .filelist.required .fileaction
410   {
411    border-color: #2288AA;
412    border-left-color: #A0A0A0;
413   }
414 
415  .filelist.required .files
416  {
417    background: #D0F0FF;
418    border-color: #2288AA;
419  }
420 
421  .recentfiles
422  {
423    position: absolute;
424    top: 0px;
425    left: 0px;
426    border: 1px solid #A0A0A0;
427    border-radius: 0px 0px 4px 4px;
428    -moz-border-radius: 0px 0px 3px 3px;
429    background-color: #F0F0F0;
430    text-align: left;
431  }
432  .recentfiles .recentfile
433  {
434    padding: 2px;
435    border-top: 1px dotted #A0A0A0;
436  }
437 
438  .recentfiles .recentfile:first-child
439  {
440    border-top: 1px solid transparent;
441  }
442 
443  .recentfiles .recentfile:hover
444  {
445    cursor: pointer;
446    padding: 1px 0px 0px 0px;
447    border: 2px solid #2288AA;
448    border-radius: 4px;
449    -moz-border-radius: 3px;
450  }
451  </style>
452  </base:head>
453  <base:body onload="init()">
454
455    <form name="datafiles">
456    <div class="absolutefull filled">
457    <%
458    boolean hasNonPlatformFiles = false;     
459    boolean activateCheckBoxes = false;
460    boolean validationSupport = false;
461    if (fileTypes.size() == 0)
462    {
463      String what = "";
464      if (platform != null)
465      {
466        what = "'" + HTML.encodeTags(platform.getName()) + "' platform";
467      }
468      else if (itemSubtype != null)
469      {
470        what = "'" + HTML.encodeTags(itemSubtype.getName()) + "' subtype";
471      }
472      %>
473      <div class="messagecontainer error">
474        The <%=what%> doesn't define any file types for
475        <%=itemType.toString() %> items.
476      </div>
477      <%
478    }
479    else if (deniedPlatform)
480    {
481      %>
482      <div class="messagecontainer error">Denied</div>
483      <%
484    }
485    else
486    {
487      %>
488      <table class="fullform larger">
489      <%
490      for (DataFileType dft : fileTypes)
491      {
492        String dftId = Integer.toString(dft.getId());
493        String fullLabel = dft.getName();
494        String label = Values.trimString(fullLabel, 25);
495       
496        UsableDataFileType usable = null;
497        if (platform != null) 
498        {
499          usable = platform.getFileType(dft, variant, false);
500          if (usable == null && variant != null)
501          {
502            // If file type is not registered with a variant, also check if it is inherited from platform
503            usable = platform.getFileType(dft, null, false);
504          }
505        }
506        else if (itemSubtype != null)
507        {
508          usable = itemSubtype.getAssociatedDataFileType(dft, false);
509        }
510       
511        boolean isPartOfPlatform = usable != null;
512        boolean isRequired = usable == null ? false : usable.isRequired();
513        boolean allowMultiple = usable == null ? false : usable.getAllowMultiple();
514        String extension = dft.getExtension();
515        boolean hasValidator = dft.hasActiveValidator(dc);
516        validationSupport |= hasValidator;
517        List<FileSetMember> files = members.get(dft);
518        List<File> recentFiles = (List<File>)cc.getRecent(dc, Item.FILE, dft.getExternalId());
519        %>
520        <tr>
521          <th title="<%=HTML.encodeTags(fullLabel)%>">
522            <%
523            if (!isPartOfPlatform && !deniedPlatform)
524            {
525              hasNonPlatformFiles = true;
526              %>
527              <base:icon image="warning.gif" 
528                tooltip="This file is not part of the platform/subtype" 
529                style="float: left; margin-right: 2px; vertical-align: top;"
530                />
531              <%
532            }
533            %>
534            <%=HTML.encodeTags(label)%>
535          </th>
536          <td onclick="<%="recentFilesOnClick(event, " + dftId + ")"%>">
537            <div class="filelist <%=isRequired ? "required" : "" %>" id="container.<%=dftId%>">
538            <table style="width: 100%;">
539            <tr><td id="filelist.<%=dftId%>" class="files">
540              <%
541              if (files != null && files.size() > 0)
542              {
543                for (FileSetMember fm : files)
544                {
545                  File file = fm.getFile();
546                  %>
547                  <div id="filelist.<%=dftId%>.<%=file.getId()%>" class="file">
548                  <%=file.getPath() %>
549                  <base:icon image="remove.png" visible="<%=allowMultiple %>"
550                    tooltip="Remove this file"
551                    onclick="<%="removeFileOnClick(event, " + dftId + "," + file.getId() + "," + hasValidator + ")" %>"
552                  />
553                  </div>
554                  <%
555                }
556              }
557              %>
558              </td>
559              <td class="fileaction">
560                <base:icon image="mini_scroll_down.png" 
561                  visible="<%=recentFiles.size() >= 0 %>"
562                  tooltip="Select a recently used file"
563                  onclick="<%="recentFilesOnClick(event, " + dftId + ")"%>"
564                />
565                <base:icon image="add.png" 
566                  onclick="<%="addFilesOnClick(event, "+dftId+", '" + HTML.javaScriptEncode(extension) + "', "+ hasValidator + ")"%>"
567                  visible="<%=allowMultiple %>"
568                />
569                <base:icon image="browse.png" 
570                  onclick="<%="browseOnClick(event, "+dftId+", '" + HTML.javaScriptEncode(extension) + "', "+ hasValidator + ")"%>"
571                  visible="<%=!allowMultiple%>"
572                />
573              </td>
574            </tr>
575            </table>
576            </div>
577
578            <div id="recentfiles.<%=dftId%>" style="display: none;" class="recentfiles">
579              <div class="recentfile"
580                onclick="selectRecentFile(<%=dftId%>, 0, false, <%=hasValidator%>)"
581                id="recentfile.<%=dftId%>.0"
582                ><i>- clear -</i></div>
583              <%
584              for (File recent : recentFiles)
585              {
586                %>
587                <div class="recentfile"
588                  onclick="selectRecentFile(<%=dftId%>, <%=recent.getId()%>, <%=allowMultiple ? 1 : 0 %>, <%=hasValidator%>)"
589                  id="recentfile.<%=dftId%>.<%=recent.getId()%>"
590                  ><%=HTML.encodeTags(recent.getPath().toString())%></div>
591                <%
592              }
593              %>
594            </div>
595          </td>
596        </tr>
597        <%
598      }
599      %>
600      <%
601      if (validationSupport)
602      {
603        %>
604        <tr>
605          <th><label for="validateFiles"><b>Validate files</b></label></th>
606          <td>
607          <span title="Enabled this check box to validate and extract metadata from selected files">
608          <input type="checkbox" value="1" name="datafiles.validate" id="validateFiles">
609          </span>
610          </td>
611        </tr>
612        <%
613      }
614      %>
615      <tr class="dynamic">
616        <th></th>
617        <td></td>
618      </tr>
619      <%
620      if (hasNonPlatformFiles)
621      {
622        if (platform != null)
623        {
624          %>
625          <div class="legend">
626          <base:icon image="warning.gif" /> 
627          = the file type is not part of the <i><%=HTML.encodeTags(platform.getName())%></i> platform
628          </div>
629          <%
630        }
631        else if (itemSubtype != null)
632        {
633          %>
634          <div class="legend">
635          <base:icon image="warning.gif" /> 
636          = the file type is not part of the <i><%=HTML.encodeTags(itemSubtype.getName())%></i> subtype
637          </div>
638          <%
639        }
640      }
641      %>
642      </table>
643      <%
644    }
645    %>
646    </div>
647    </form>
648
649  </base:body>
650  </base:page>
651  <%
652}
653finally
654{
655  if (dc != null) dc.close();
656}
657%>
Note: See TracBrowser for help on using the repository browser.