source: trunk/www/filemanager/directories/list_directories.jsp @ 5953

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

References #1655: GUI improvements

Select file/directory and "save as" dialogs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 12.7 KB
Line 
1<%-- $Id: list_directories.jsp 5953 2012-02-10 13:35:22Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg
4
5  This file is part of BASE - BioArray Software Environment.
6  Available at http://base.thep.lu.se/
7
8  BASE is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License
10  as published by the Free Software Foundation; either version 3
11  of the License, or (at your option) any later version.
12
13  BASE is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with BASE. If not, see <http://www.gnu.org/licenses/>.
20  ------------------------------------------------------------------
21
22  @author Nicklas
23  @version 2.0
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.SystemItems"
29  import="net.sf.basedb.core.Item"
30  import="net.sf.basedb.core.ItemContext"
31  import="net.sf.basedb.core.Directory"
32  import="net.sf.basedb.core.Experiment"
33  import="net.sf.basedb.core.User"
34  import="net.sf.basedb.core.ItemQuery"
35  import="net.sf.basedb.core.ItemResultIterator"
36  import="net.sf.basedb.core.Permission"
37  import="net.sf.basedb.core.query.Restrictions"
38  import="net.sf.basedb.core.query.Expressions"
39  import="net.sf.basedb.core.query.Orders"
40  import="net.sf.basedb.core.query.Hql"
41  import="net.sf.basedb.util.FileUtil"
42  import="net.sf.basedb.clients.web.Base"
43  import="net.sf.basedb.clients.web.util.HTML"
44  import="net.sf.basedb.util.Values"
45  import="java.util.Map"
46  import="java.util.Set"
47  import="java.util.HashSet"
48  import="java.util.List"
49%>
50<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
51<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
52<%!
53String generateSubTree(Map<Directory, List<Directory>> tree, Set<Directory> ignore, Directory parent, String ID, String parentId)
54{
55  if (ignore.contains(parent)) return "";
56  ignore.add(parent);
57  StringBuilder sb = new StringBuilder();
58  if (parentId == null) parentId = "dir"+parent.getId();
59  List<Directory> children = tree.get(parent);
60  if (children == null) return "";
61  for (Directory child : children)
62  {
63    if (ignore.contains(child)) continue;
64    String folderIcon = "Folder";
65    if (child.isHomeDirectory())
66    {
67      folderIcon = "UserHome";
68    }
69    else if (child.isRemoved())
70    {
71      folderIcon = "FolderDeleted";
72    }
73    else if (child.getAutoCompress())
74    {
75      folderIcon = "FolderCompressed";
76    }
77    sb.append("var dir").append(child.getId()).append(" = JoustMenu.addLazyChildItem(").append(parentId);
78    sb.append(",'").append(folderIcon).append("'");
79    sb.append(",'").append(HTML.javaScriptEncode(child.getName())).append("'");
80    sb.append(",'directoryOnClick(").append(child.getId()).append(",");
81    sb.append(" \"").append(HTML.javaScriptEncode(child.getPath().toString())).append("\")'");
82    sb.append(",'', 'D").append(child.getId()).append("',");
83    sb.append("'lazyInitSubdir(").append(child.getId()).append(")')\n");
84    sb.append(generateSubTree(tree, ignore, child, ID, null));
85  }
86  return sb.toString();
87}
88%>
89<%
90final Item itemType = Item.DIRECTORY;
91final SessionControl sc = Base.getExistingSessionControl(pageContext, Permission.DENIED, itemType);
92final String ID = sc.getId();
93final DbControl dc = sc.newDbControl();
94final String mode = request.getParameter("mode");
95final String callback = request.getParameter("callback");
96final float scale = Base.getScale(sc);
97final String requestTitle = request.getParameter("title");
98final boolean syncWithDirectory = Values.getBoolean(request.getParameter("sync"));
99final ItemContext cc = sc.getCurrentContext(itemType);
100int directoryId = cc.getId();
101try
102{
103  final User user = User.getById(dc, sc.getLoggedInUserId());
104  final Directory userHome = user.getHomeDirectory();
105  final boolean readDirectories = sc.hasPermission(Permission.READ, Item.DIRECTORY);
106  final Directory root = Directory.getById(dc, SystemItems.getId(readDirectories ? Directory.ROOT : Directory.HOME));
107 
108  Directory current = null;
109  // Try to get current/last visited directory. If not successful, use default directory.
110  try
111  {
112    current = directoryId != 0 ? Directory.getById(dc, directoryId) : null;
113  }
114  catch (Throwable ex){} 
115  if (current == null) current = userHome;
116  if (current == null) current = root;
117 
118  final String rootIcon;
119  final String rootTitle;
120  if (root.isRootDirectory())
121  {
122    rootIcon = "Root";
123    rootTitle = "Root";
124  }
125  else
126  {
127    rootIcon = "Home";
128    rootTitle = "Other users";
129  }
130  Map<Directory, List<Directory>> tree = FileUtil.loadMinimalDirectoryTree(dc, root, userHome, current);
131  Set<Directory> ignore = new HashSet<Directory>();
132  %>
133  <base:page title="<%=requestTitle != null ? requestTitle : ""%>" 
134    type="<%="selectonedirectory".equals(mode) ? "popup" : "iframe"%>">
135  <base:head scripts="newjoust.js,table.js,ajax.js,json2.js" styles="newjoust.css,toolbar.css">
136  <script language="JavaScript">
137  var isInitialised = false;
138  function initialise()
139  {
140    IconStore.init();
141    var path = getRoot()+'images/joust/';
142    IconStore.addIcon('Search', path + 'search.png', 18, 16);
143    IconStore.addIcon('SearchSelected', path + 'searchselected.png', 18, 16);
144    <%
145    // Root entry for the user's Home directory
146    if (userHome != null)
147    {
148      %>
149      var userHome = JoustMenu.addMenuItem(-1, 'Home', 'My home', 'directoryOnClick(<%=userHome.getId()%>, "<%=HTML.javaScriptEncode(userHome.getPath().toString())%>")', '', 'D<%=userHome.getId()%>');
150      JoustMenu.menuItems[userHome].noOutlineIcon = true;
151      JoustMenu.menuItems[userHome].isOpen = true;
152      <%=generateSubTree(tree, ignore, userHome, ID, "userHome")%>
153      <%
154    }
155    // Root entry for entire directory tree
156    %>
157    var search = JoustMenu.addMenuItem(-1, 'Search', 'Search results', 'searchOnClick()', 'The latest search results', 'search');
158    JoustMenu.menuItems[search].noOutlineIcon = true;
159    JoustMenu.menuItems[search].style = 'display:none; font-style: italic; border-bottom: 1px solid #cccccc; margin-bottom: 2px; padding-bottom: 2px;';
160    var root = JoustMenu.addMenuItem(-1, '<%=rootIcon%>', '<%=HTML.javaScriptEncode(rootTitle)%>', 'directoryOnClick(<%=root.getId()%>, "<%=HTML.javaScriptEncode(root.getPath().toString())%>")', '', 'D<%=root.getId()%>');
161    JoustMenu.menuItems[root].noOutlineIcon = true;
162    JoustMenu.menuItems[root].isOpen = true;
163    <%=generateSubTree(tree, ignore, root, ID, "root")%>
164
165    <%
166    // Add 'current' as root entry if we have not seen it before
167    if (!ignore.contains(current))
168    {
169      // but... move up as far as the user has 'read' permission...
170      Directory currentRoot = current;
171      try
172      {
173        while (currentRoot != null && !ignore.contains(currentRoot.getParent()))
174        {
175          currentRoot = currentRoot.getParent();
176        }
177      }
178      catch (Throwable t)
179      {}
180      if (currentRoot == null) currentRoot = current;
181      %>
182      var currentRoot = JoustMenu.addMenuItem(-1, 'Folder', '<%=HTML.javaScriptEncode(currentRoot.getPath().toString())%>', 'directoryOnClick(<%=currentRoot.getId()%>, "<%=HTML.javaScriptEncode(currentRoot.getPath().toString())%>")', '', 'D<%=currentRoot.getId()%>');
183      JoustMenu.menuItems[currentRoot].noOutlineIcon = true;
184      JoustMenu.menuItems[currentRoot].isOpen = true;
185      <%=generateSubTree(tree, ignore, currentRoot, ID, "currentRoot")%>
186      <%
187    }
188    %>
189    JoustMenu.draw('joust');
190    var lastDirectory = JoustMenu.menuItems['D<%=current.getId()%>'];
191    JoustMenu.select(lastDirectory.index);
192    JoustMenu.alwaysSendOnClickToSelected = true;
193    isInitialised = true;
194  }
195 
196  function lazyInitSubdir(directoryId)
197  {
198    var request = Ajax.getXmlHttpRequest();
199    var url = 'ajax.jsp?ID=<%=ID%>&cmd=GetSubdirectories&item_id=' + directoryId;
200    request.open("GET", url, false);
201    // NOTE! 'false' causes code to wait for the response. aka. 'Synchronous AJAX' or SJAX.
202    request.send(null);
203    var response = Ajax.parseJsonResponse(request.responseText);
204    if (response.status != 'ok')
205    {
206      alert(response.message);
207      return false;
208    }
209   
210    var subdirs = response.subdirs;
211    var numAdded = 0;
212    var parent = JoustMenu.menuItems['D'+directoryId];
213    for (var i = 0; i < subdirs.length; i++)
214    {
215      var subdir = subdirs[i];
216      var id = subdir.id;
217      var folderIcon = 'Folder';
218      if (subdir.isHome)
219      {
220        folderIcon = 'UserHome';
221      }
222      else if (subdir.isRemoved)
223      {
224        folderIcon = 'FolderDeleted';
225      }
226      else if (subdir.isAutoCompress == 1)
227      {
228        folderIcon = 'FolderCompressed';
229      }
230      numAdded++;
231      JoustMenu.addLazyChildItem(parent.index, folderIcon, subdir.name, 'directoryOnClick('+id+',\''+subdir.path+'\')', '', 'D'+id, 'lazyInitSubdir('+id+')');
232    }
233    return numAdded > 0;
234  }
235  <%
236  if ("selectonedirectory".equals(mode))
237  {
238    %>
239    var lastDirectoryId;
240    function directoryOnClick(directoryId, path)
241    {
242      var frm = document.forms['directory'];
243      frm.directory_id.value = directoryId;
244      frm.path.value = path;
245      lastDirectoryId = directoryId;
246    }
247    function returnSelected()
248    {
249      var frm = document.forms['directory'];
250      top.window.opener.<%=callback%>(frm.directory_id.value, frm.path.value);
251      top.window.close();
252    }
253    function newDirectory()
254    {
255      Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', 0, true, '&parent_id='+lastDirectoryId);
256    }
257    <%
258  }
259  else
260  {
261    %>
262    function directoryOnClick(directoryId, path)
263    {
264      if (!isInitialised && <%=!syncWithDirectory%>) return;
265      parent.lastOpenDirectoryId = directoryId;
266      parent.frames.files.location.href = '../files/index.jsp?ID=<%=ID%>&cmd=List&directory_id='+directoryId+'&mode=<%=mode%>';
267      if (window.top.setSelected)
268      {
269        //window.top.setSelected('', path);
270      }
271    }
272    <%
273  }
274  %>
275  function searchOnClick()
276  {
277    parent.frames.files.location.href = '../files/index.jsp?ID=<%=ID%>&cmd=Search&subcontext=search&mode=<%=mode%>';
278  }
279  function searchButtonOnClick()
280  {
281    var searchResults = JoustMenu.menuItems['search'];
282    Main.show('menuItem'+searchResults.index);
283    JoustMenu.select(searchResults.index, null, false);
284  }
285  function updateSearchResults(files, directories)
286  {
287    var searchResults = JoustMenu.menuItems['search'];
288    if (searchResults)
289    {
290      var text = document.getElementById('text'+searchResults.index);
291      text.innerHTML = 'Search results (' + (files + directories) + ')';
292    }
293  }
294  function synchronizeTo(directoryId, parentId)
295  {
296    var item = JoustMenu.menuItems['D'+directoryId];
297    if (!item)
298    {
299      if (!parentId) parentId = parent.lastOpenDirectoryId;
300      if (parentId)
301      {
302        var parentDir = JoustMenu.menuItems['D'+parentId];
303        if (parentDir.lazyInit)
304        {
305          JoustMenu.toggle(parentDir.index);
306          item = JoustMenu.menuItems['D'+directoryId];
307        }
308      }
309    }
310    if (item)
311    {
312      JoustMenu.select(item.index);
313    }
314    else
315    {
316      parent.parent.location.href = '../directories/index.jsp?ID=<%=ID%>&cmd=ViewItem&item_id=' + directoryId+'&mode=<%=mode%>';
317    }
318  }
319  function refresh()
320  {
321    location.reload();
322  }
323  </script>
324  </base:head>
325 
326  <%
327  if ("selectonedirectory".equals(mode))
328  {
329    %>
330    <base:body onload="initialise()">
331      <h1><%=requestTitle == null ? "Select one directory" : requestTitle%></h1>
332     
333      <form name="directory">
334      <input type="hidden" name="directory_id" value="">
335
336      <div class="content bottomborder">
337        <div id="main" class="absolutefull" style="bottom: 3em;">
338          <tbl:toolbar subclass="bottomborder">
339            <tbl:button 
340              image="directory_new.png" 
341              onclick="newDirectory()" 
342              title="New&hellip;" 
343              tooltip="Create a new directory" 
344            />
345          </tbl:toolbar>
346          <div id="joust" class="absolutefull joust" style="top: 1.8em; overflow:auto;">
347          </div>
348        </div>
349     
350        <div class="absolutefull topborder" style="top: auto; height: 3em;">
351          <table class="fullform input100">
352            <tr>
353              <th><%=requestTitle == null ? "Path" : requestTitle%></th>
354              <td><input type="text" class="text" readonly name="path"></td>
355            </tr>
356          </table>
357        </div>
358      </div>
359      </form>
360
361      <base:buttongroup subclass="dialogbuttons">
362        <base:button onclick="returnSelected()" title="Ok" />
363        <base:button onclick="window.close()" title="Cancel" />
364      </base:buttongroup>
365     
366    </base:body>
367    <%
368  }
369  else
370  {
371    %>
372    <base:body onload="initialise()">
373    <div id="main" class="absolutefull joust" 
374      onmousemove="parent.DragDrop.drag(event)" onmouseup="parent.DragDrop.endDrag(event)">
375      <tbl:toolbar subclass="bottomborder">
376        <tbl:button 
377          image="refresh.png" 
378          onclick="refresh()" 
379          title="Refresh" 
380          tooltip="Refresh the directory tree" 
381        />
382        <tbl:button 
383          image="search.png" 
384          onclick="searchButtonOnClick()" 
385          title="Search" 
386          tooltip="Search for files and directories" 
387        />
388      </tbl:toolbar>
389      <div id="joust" style="overflow: auto;"></div>
390    </div>
391    </base:body>
392    <%
393  }
394  %>
395  </base:page>
396  <%
397}
398finally
399{
400  if (dc != null) dc.close();
401}
402%>
Note: See TracBrowser for help on using the repository browser.