2 * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
\r
4 * This file is part of GSS.
\r
6 * GSS is free software: you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation, either version 3 of the License, or
\r
9 * (at your option) any later version.
\r
11 * GSS is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with GSS. If not, see <http://www.gnu.org/licenses/>.
\r
19 package gr.ebs.gss.client;
\r
21 import gr.ebs.gss.client.dnd.DnDSimpleFocusPanel;
\r
22 import gr.ebs.gss.client.dnd.DnDTreeItem;
\r
23 import gr.ebs.gss.client.rest.GetCommand;
\r
24 import gr.ebs.gss.client.rest.MultipleHeadCommand;
\r
25 import gr.ebs.gss.client.rest.RestCommand;
\r
26 import gr.ebs.gss.client.rest.RestException;
\r
27 import gr.ebs.gss.client.rest.resource.FileResource;
\r
28 import gr.ebs.gss.client.rest.resource.FolderResource;
\r
29 import gr.ebs.gss.client.rest.resource.OtherUserResource;
\r
30 import gr.ebs.gss.client.rest.resource.SharedResource;
\r
31 import gr.ebs.gss.client.rest.resource.TrashResource;
\r
32 import gr.ebs.gss.client.rest.resource.UserResource;
\r
34 import java.util.ArrayList;
\r
35 import java.util.Collections;
\r
36 import java.util.Comparator;
\r
37 import java.util.List;
\r
39 import com.google.gwt.core.client.GWT;
\r
40 import com.google.gwt.dom.client.NativeEvent;
\r
41 import com.google.gwt.event.dom.client.ClickEvent;
\r
42 import com.google.gwt.event.dom.client.ClickHandler;
\r
43 import com.google.gwt.http.client.URL;
\r
44 import com.google.gwt.i18n.client.DateTimeFormat;
\r
45 import com.google.gwt.resources.client.ClientBundle;
\r
46 import com.google.gwt.resources.client.ImageResource;
\r
47 import com.google.gwt.user.client.DOM;
\r
48 import com.google.gwt.user.client.DeferredCommand;
\r
49 import com.google.gwt.user.client.Event;
\r
50 import com.google.gwt.user.client.IncrementalCommand;
\r
51 import com.google.gwt.user.client.Window;
\r
52 import com.google.gwt.user.client.ui.AbstractImagePrototype;
\r
53 import com.google.gwt.user.client.ui.Composite;
\r
54 import com.google.gwt.user.client.ui.Grid;
\r
55 import com.google.gwt.user.client.ui.HTML;
\r
56 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
\r
57 import com.google.gwt.user.client.ui.HorizontalPanel;
\r
58 import com.google.gwt.user.client.ui.TreeItem;
\r
59 import com.google.gwt.user.client.ui.Widget;
\r
60 import com.google.gwt.user.client.ui.HTMLTable.Cell;
\r
63 * A composite that displays the list of files in a particular folder.
\r
65 public class FileList extends Composite implements ClickHandler {
\r
67 private HTML prevButton = new HTML("<a href='javascript:;'>< Previous</a>", true);
\r
69 private HTML nextButton = new HTML("<a href='javascript:;'>Next ></a>", true);
\r
71 private String showingStats = "";
\r
73 private int startIndex = 0;
\r
76 * A constant that denotes the completion of an IncrementalCommand.
\r
78 public static final boolean DONE = false;
\r
80 private boolean clickControl = false;
\r
82 private boolean clickShift = false;
\r
84 private int firstShift = -1;
\r
86 private ArrayList<Integer> selectedRows = new ArrayList<Integer>();
\r
89 * The context menu for the selected file.
\r
91 final DnDSimpleFocusPanel contextMenu;
\r
94 * Specifies that the images available for this composite will be the ones
\r
95 * available in FileContextMenu.
\r
97 public interface Images extends ClientBundle,FileContextMenu.Images, Folders.Images {
\r
99 @Source("gr/ebs/gss/resources/blank.gif")
\r
100 ImageResource blank();
\r
102 @Source("gr/ebs/gss/resources/asc.png")
\r
103 ImageResource asc();
\r
105 @Source("gr/ebs/gss/resources/desc.png")
\r
106 ImageResource desc();
\r
108 @Source("gr/ebs/gss/resources/mimetypes/document_shared.png")
\r
109 ImageResource documentShared();
\r
111 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst.png")
\r
112 ImageResource wordprocessor();
\r
114 @Source("gr/ebs/gss/resources/mimetypes/log.png")
\r
115 ImageResource spreadsheet();
\r
117 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr.png")
\r
118 ImageResource presentation();
\r
120 @Source("gr/ebs/gss/resources/mimetypes/acroread.png")
\r
121 ImageResource pdf();
\r
123 @Source("gr/ebs/gss/resources/mimetypes/image.png")
\r
124 ImageResource image();
\r
126 @Source("gr/ebs/gss/resources/mimetypes/video2.png")
\r
127 ImageResource video();
\r
129 @Source("gr/ebs/gss/resources/mimetypes/knotify.png")
\r
130 ImageResource audio();
\r
132 @Source("gr/ebs/gss/resources/mimetypes/html.png")
\r
133 ImageResource html();
\r
135 @Source("gr/ebs/gss/resources/mimetypes/txt.png")
\r
136 ImageResource txt();
\r
138 @Source("gr/ebs/gss/resources/mimetypes/ark2.png")
\r
139 ImageResource zip();
\r
141 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst_shared.png")
\r
142 ImageResource wordprocessorShared();
\r
144 @Source("gr/ebs/gss/resources/mimetypes/log_shared.png")
\r
145 ImageResource spreadsheetShared();
\r
147 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr_shared.png")
\r
148 ImageResource presentationShared();
\r
150 @Source("gr/ebs/gss/resources/mimetypes/acroread_shared.png")
\r
151 ImageResource pdfShared();
\r
153 @Source("gr/ebs/gss/resources/mimetypes/image_shared.png")
\r
154 ImageResource imageShared();
\r
156 @Source("gr/ebs/gss/resources/mimetypes/video2_shared.png")
\r
157 ImageResource videoShared();
\r
159 @Source("gr/ebs/gss/resources/mimetypes/knotify_shared.png")
\r
160 ImageResource audioShared();
\r
162 @Source("gr/ebs/gss/resources/mimetypes/html_shared.png")
\r
163 ImageResource htmlShared();
\r
165 @Source("gr/ebs/gss/resources/mimetypes/txt_shared.png")
\r
166 ImageResource txtShared();
\r
168 @Source("gr/ebs/gss/resources/mimetypes/ark2_shared.png")
\r
169 ImageResource zipShared();
\r
174 * A label with the number of files in this folder.
\r
176 private HTML countLabel = new HTML();
\r
179 * The table widget with the file list.
\r
181 private FileTable table = new FileTable(GSS.VISIBLE_FILE_COUNT + 1, 8);
\r
184 * The navigation bar for paginating the results.
\r
186 private HorizontalPanel navBar = new HorizontalPanel();
\r
189 * The number of files in this folder.
\r
191 int folderFileCount;
\r
194 * Total folder size
\r
196 long folderTotalSize;
\r
199 * A cache of the files in the list.
\r
201 private List<FileResource> files;
\r
204 * The widget's image bundle.
\r
206 private final Images images;
\r
208 private String sortingProperty = "name";
\r
210 private boolean sortingType = true;
\r
212 private HTML nameLabel;
\r
214 private HTML versionLabel;
\r
216 private HTML sizeLabel;
\r
218 private HTML dateLabel;
\r
220 private HTML ownerLabel;
\r
222 private HTML pathLabel;
\r
225 * Construct the file list widget. This entails setting up the widget
\r
226 * layout, fetching the number of files in the current folder from the
\r
227 * server and filling the local file cache of displayed files with data from
\r
228 * the server, as well.
\r
232 public FileList(Images _images) {
\r
235 prevButton.addClickHandler(this);
\r
236 nextButton.addClickHandler(this);
\r
238 contextMenu = new DnDSimpleFocusPanel(new HTML(AbstractImagePrototype.create(images.fileContextMenu()).getHTML()));
\r
239 GSS.get().getDragController().makeDraggable(contextMenu);
\r
241 // Setup the table.
\r
242 table.setCellSpacing(0);
\r
243 table.setCellPadding(2);
\r
244 table.setWidth("100%");
\r
245 table.addClickHandler(new ClickHandler() {
\r
248 public void onClick(ClickEvent event) {
\r
249 Cell cell = table.getCellForEvent(event);
\r
250 GWT.log("row clicked:"+cell.getRowIndex(), null);
\r
251 onRowClicked(cell.getRowIndex(), true);
\r
254 // Create the 'navigation' bar at the upper-right.
\r
255 HorizontalPanel innerNavBar = new HorizontalPanel();
\r
256 innerNavBar.setStyleName("gss-ListNavBar");
\r
257 innerNavBar.setSpacing(8);
\r
258 innerNavBar.add(prevButton);
\r
259 innerNavBar.add(countLabel);
\r
260 innerNavBar.add(nextButton);
\r
261 navBar.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
\r
262 navBar.add(innerNavBar);
\r
263 navBar.setWidth("100%");
\r
266 setStyleName("gss-List");
\r
269 DeferredCommand.addCommand(new IncrementalCommand() {
\r
271 public boolean execute() {
\r
272 return fetchRootFolder();
\r
275 sinkEvents(Event.ONCONTEXTMENU);
\r
276 sinkEvents(Event.ONMOUSEUP);
\r
277 sinkEvents(Event.ONMOUSEDOWN);
\r
278 sinkEvents(Event.ONCLICK);
\r
279 sinkEvents(Event.ONKEYDOWN);
\r
280 sinkEvents(Event.ONDBLCLICK);
\r
281 GSS.preventIESelection();
\r
285 public void onClick(ClickEvent event) {
\r
286 if(event.getSource() == nextButton){
\r
287 // Move forward a page.
\r
288 clearSelectedRows();
\r
289 startIndex += GSS.VISIBLE_FILE_COUNT;
\r
290 if (startIndex >= folderFileCount)
\r
291 startIndex -= GSS.VISIBLE_FILE_COUNT;
\r
294 } else if (event.getSource() == prevButton) {
\r
295 clearSelectedRows();
\r
296 // Move back a page.
\r
297 startIndex -= GSS.VISIBLE_FILE_COUNT;
\r
298 if (startIndex < 0)
\r
307 public void onBrowserEvent(Event event) {
\r
308 if (DOM.eventGetType(event) == Event.ONMOUSEDOWN && DOM.eventGetButton(event) == NativeEvent.BUTTON_RIGHT){
\r
309 if (DOM.eventGetCtrlKey(event))
\r
310 clickControl = true;
\r
312 clickControl = false;
\r
313 if (DOM.eventGetShiftKey(event)) {
\r
315 if (selectedRows.size() == 1)
\r
316 firstShift = selectedRows.get(0) - startIndex;
\r
317 //event.preventDefault();
\r
319 clickShift = false;
\r
321 //event.preventDefault();
\r
323 int ri = table.getRowForEvent2(event);
\r
325 if(!selectedRows.contains(ri-1))
\r
326 onRowClicked(ri, false);
\r
329 if (files == null || files.size() == 0) {
\r
330 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() == 0) {
\r
331 FileContextMenu fm = new FileContextMenu(images, false, true);
\r
332 fm.onEmptyEvent(event);
\r
336 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() != 0) {
\r
337 FileContextMenu fm = new FileContextMenu(images, false, false);
\r
339 } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() == 0) {
\r
340 FileContextMenu fm = new FileContextMenu(images, false, true);
\r
341 fm.onEmptyEvent(event);
\r
342 } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
\r
343 if (getSelectedFiles().size() == 1) {
\r
344 GSS app = GSS.get();
\r
345 FileResource file = getSelectedFiles().get(0);
\r
346 String dateString = RestCommand.getDate();
\r
347 String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());
\r
348 String sig = app.getCurrentUserResource().getUsername() + " " +
\r
349 RestCommand.calculateSig("GET", dateString, resource,
\r
350 RestCommand.base64decode(app.getToken()));
\r
351 Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");
\r
352 event.preventDefault();
\r
355 if (DOM.eventGetType(event) == Event.ONCLICK) {
\r
356 if (DOM.eventGetCtrlKey(event))
\r
357 clickControl = true;
\r
359 clickControl = false;
\r
360 if (DOM.eventGetShiftKey(event)) {
\r
362 if (selectedRows.size() == 1)
\r
363 firstShift = selectedRows.get(0) - startIndex;
\r
364 //event.preventDefault();
\r
366 clickShift = false;
\r
368 //event.preventDefault();
\r
371 super.onBrowserEvent(event);
\r
375 * Retrieve the root folder for the current user.
\r
377 * @return true if the retrieval was successful
\r
379 protected boolean fetchRootFolder() {
\r
380 UserResource user = GSS.get().getCurrentUserResource();
\r
383 // Update cache and clear selection.
\r
384 updateFileCache(true);
\r
388 private void onRowClicked(int row, boolean toggleSelection) {
\r
389 // Select the row that was clicked (-1 to account for header row).
\r
390 if (row > folderFileCount)
\r
393 GWT.log("Row is: " + row + " fs: " + firstShift, null);
\r
394 if (firstShift == -1)
\r
396 else if (row > firstShift) {
\r
397 clearSelectedRows();
\r
398 for (int i = firstShift; i < row; i++) {
\r
399 selectedRows.add(startIndex + i);
\r
402 GSS.get().setCurrentSelection(getSelectedFiles());
\r
403 contextMenu.setFiles(getSelectedFiles());
\r
404 makeRowDraggable(row);
\r
405 } else if (row != -1 && row == firstShift) {
\r
406 selectedRows.add(row - 1);
\r
407 styleRow(row, true);
\r
408 styleRow(row - 1, true);
\r
409 GSS.get().setCurrentSelection(getSelectedFiles());
\r
410 contextMenu.setFiles(getSelectedFiles());
\r
411 makeRowDraggable(row);
\r
412 } else if (row < firstShift) {
\r
413 GWT.log("Row is:" + row + " fs:" + firstShift, null);
\r
414 clearSelectedRows();
\r
416 for (int i = firstShift; i >= row - 1; i--) {
\r
417 selectedRows.add(startIndex + i);
\r
420 GSS.get().setCurrentSelection(getSelectedFiles());
\r
421 makeRowDraggable(row);
\r
422 contextMenu.setFiles(getSelectedFiles());
\r
424 } else if (row > 0)
\r
425 selectRow(row - 1, toggleSelection);
\r
429 * Initializes the table so that it contains enough rows for a full page of
\r
432 private void initTable() {
\r
433 nameLabel = new HTML("Name");
\r
434 nameLabel.addClickHandler(new ClickHandler() {
\r
437 public void onClick(ClickEvent event) {
\r
443 versionLabel = new HTML("Version");
\r
444 versionLabel.addClickHandler(new ClickHandler() {
\r
447 public void onClick(ClickEvent event) {
\r
448 sortFiles("version");
\r
452 sizeLabel = new HTML("Size");
\r
453 sizeLabel.addClickHandler(new ClickHandler() {
\r
456 public void onClick(ClickEvent event) {
\r
461 dateLabel = new HTML("Last modified");
\r
462 dateLabel.addClickHandler(new ClickHandler() {
\r
465 public void onClick(ClickEvent event) {
\r
470 ownerLabel = new HTML("Owner");
\r
471 ownerLabel.addClickHandler(new ClickHandler() {
\r
474 public void onClick(ClickEvent event) {
\r
475 sortFiles("owner");
\r
479 pathLabel = new HTML("Path");
\r
480 pathLabel.addClickHandler(new ClickHandler() {
\r
483 public void onClick(ClickEvent event) {
\r
488 // Create the header row.
\r
489 table.setText(0, 0, "");
\r
490 table.setWidget(0, 1, nameLabel);
\r
491 table.setWidget(0, 2, ownerLabel);
\r
492 table.setWidget(0, 3, pathLabel);
\r
493 table.setWidget(0, 4, versionLabel);
\r
494 table.setWidget(0, 5, sizeLabel);
\r
495 table.setWidget(0, 6, dateLabel);
\r
496 table.setWidget(0, 7, navBar);
\r
497 table.getRowFormatter().setStyleName(0, "gss-ListHeader");
\r
499 // Initialize the rest of the rows.
\r
500 for (int i = 1; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
\r
501 table.setText(i, 0, "");
\r
502 table.setText(i, 1, "");
\r
503 table.setText(i, 2, "");
\r
504 table.setText(i, 3, "");
\r
505 table.setText(i, 4, "");
\r
506 table.setText(i, 5, "");
\r
507 table.setText(i, 6, "");
\r
508 table.setText(i, 7, "");
\r
509 table.getCellFormatter().setWordWrap(i, 0, false);
\r
510 table.getCellFormatter().setWordWrap(i, 1, false);
\r
511 table.getCellFormatter().setWordWrap(i, 2, false);
\r
512 table.getCellFormatter().setWordWrap(i, 3, false);
\r
513 table.getCellFormatter().setWordWrap(i, 4, false);
\r
514 table.getCellFormatter().setWordWrap(i, 5, false);
\r
515 table.getCellFormatter().setWordWrap(i, 6, false);
\r
516 table.getCellFormatter().setWordWrap(i, 7, false);
\r
517 table.getCellFormatter().setHorizontalAlignment(i, 4, HasHorizontalAlignment.ALIGN_CENTER);
\r
519 prevButton.setVisible(false);
\r
520 nextButton.setVisible(false);
\r
524 * Selects the given row (relative to the current page).
\r
526 * @param row the row to be selected
\r
528 private void selectRow(final int row, boolean toggleSelection) {
\r
529 if (row < folderFileCount) {
\r
531 if (selectedRows.contains(row) && toggleSelection) {
\r
532 int i = selectedRows.indexOf(startIndex + row);
\r
533 selectedRows.remove(i);
\r
534 styleRow(row, false);
\r
536 selectedRows.add(startIndex + row);
\r
537 styleRow(row, true);
\r
539 else if (selectedRows.size() == 1 && selectedRows.contains(row) && toggleSelection){
\r
540 clearSelectedRows();
\r
544 clearSelectedRows();
\r
545 selectedRows.add(startIndex + row);
\r
546 styleRow(row, true);
\r
548 if (selectedRows.size() == 1)
\r
549 GSS.get().setCurrentSelection(files.get(selectedRows.get(0)));
\r
550 else if(selectedRows.size() == 0)
\r
551 GSS.get().setCurrentSelection(null);
\r
553 GSS.get().setCurrentSelection(getSelectedFiles());
\r
554 contextMenu.setFiles(getSelectedFiles());
\r
555 makeRowDraggable(row+1);
\r
559 public List<FileResource> getSelectedFiles() {
\r
560 List<FileResource> result = new ArrayList();
\r
561 for (int i : selectedRows)
\r
562 result.add(files.get(i));
\r
567 * Make the specified row look like selected or not, according to the
\r
568 * <code>selected</code> flag.
\r
573 void styleRow(final int row, final boolean selected) {
\r
574 if (row != -1 && row >= 0)
\r
576 table.getRowFormatter().addStyleName(row + 1, "gss-SelectedRow");
\r
578 table.getRowFormatter().removeStyleName(row + 1, "gss-SelectedRow");
\r
582 * Update the display of the file list.
\r
584 void update(boolean sort) {
\r
585 int count = folderFileCount;
\r
586 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
\r
589 folderTotalSize = 0;
\r
591 if (sort && files != null && files.size() != 0) {
\r
593 clearSelectedRows();
\r
595 Collections.sort(files, new Comparator<FileResource>() {
\r
597 public int compare(FileResource arg0, FileResource arg1) {
\r
598 AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
\r
599 AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
\r
601 if (sortingProperty.equals("version")) {
\r
602 versionLabel.setHTML("Version " + descPrototype.getHTML());
\r
603 return arg0.getVersion().compareTo(arg1.getVersion());
\r
604 } else if (sortingProperty.equals("owner")) {
\r
605 ownerLabel.setHTML("Owner " + descPrototype.getHTML());
\r
606 return arg0.getOwner().compareTo(arg1.getOwner());
\r
607 } else if (sortingProperty.equals("date")) {
\r
608 dateLabel.setHTML("Date modified " + descPrototype.getHTML());
\r
609 return arg0.getModificationDate().compareTo(arg1.getModificationDate());
\r
610 } else if (sortingProperty.equals("size")) {
\r
611 sizeLabel.setHTML("Size " + descPrototype.getHTML());
\r
612 return arg0.getContentLength().compareTo(arg1.getContentLength());
\r
613 } else if (sortingProperty.equals("name")) {
\r
614 nameLabel.setHTML("Name " + descPrototype.getHTML());
\r
615 return arg0.getName().compareTo(arg1.getName());
\r
616 } else if (sortingProperty.equals("path")) {
\r
617 pathLabel.setHTML("Path " + descPrototype.getHTML());
\r
618 return arg0.getUri().compareTo(arg1.getUri());
\r
620 nameLabel.setHTML("Name " + descPrototype.getHTML());
\r
621 return arg0.getName().compareTo(arg1.getName());
\r
623 else if (sortingProperty.equals("version")) {
\r
624 versionLabel.setHTML("Version " + ascPrototype.getHTML());
\r
625 return arg1.getVersion().compareTo(arg0.getVersion());
\r
626 } else if (sortingProperty.equals("owner")) {
\r
627 ownerLabel.setHTML("Owner " + ascPrototype.getHTML());
\r
628 return arg1.getOwner().compareTo(arg0.getOwner());
\r
629 } else if (sortingProperty.equals("date")) {
\r
630 dateLabel.setHTML("Date modified " + ascPrototype.getHTML());
\r
631 return arg1.getModificationDate().compareTo(arg0.getModificationDate());
\r
632 } else if (sortingProperty.equals("size")) {
\r
633 sizeLabel.setHTML("Size " + ascPrototype.getHTML());
\r
634 return arg1.getContentLength().compareTo(arg0.getContentLength());
\r
635 } else if (sortingProperty.equals("name")) {
\r
636 nameLabel.setHTML("Name " + ascPrototype.getHTML());
\r
637 return arg1.getName().compareTo(arg0.getName());
\r
638 } else if (sortingProperty.equals("path")) {
\r
639 pathLabel.setHTML("Path " + ascPrototype.getHTML());
\r
640 return arg1.getUri().compareTo(arg0.getUri());
\r
642 nameLabel.setHTML("Name " + ascPrototype.getHTML());
\r
643 return arg1.getName().compareTo(arg0.getName());
\r
651 // Show the selected files.
\r
653 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
\r
654 // Don't read past the end.
\r
655 // if (i > folderFileCount)
\r
657 if (startIndex + i > folderFileCount)
\r
659 // Add a new row to the table, then set each of its columns to the
\r
661 FileResource file = files.get(startIndex + i - 1);
\r
662 table.setWidget(i, 0, getFileIcon(file).createImage());
\r
663 table.getRowFormatter().addStyleName(i, "gss-fileRow");
\r
665 //add view image link for image files
\r
666 String contentType = file.getContentType();
\r
667 if (contentType.endsWith("png") || contentType.endsWith("gif") || contentType.endsWith("jpeg") )
\r
668 table.setHTML(i, 1, file.getName() + " <a href='" +
\r
669 GSS.get().getTopPanel().getFileMenu().getDownloadURL(file) +
\r
670 "' title='" + file.getName() + "' rel='lytebox[p]' " +
\r
671 "onclick='myLytebox.start(this, false, false)'>" +
\r
672 "(view)" + "</a>");
\r
674 table.setHTML(i, 1, file.getName());
\r
675 table.setText(i, 2, file.getOwner());
\r
676 table.setText(i, 3, file.getPath());
\r
677 table.setText(i, 4, String.valueOf(file.getVersion()));
\r
678 table.setText(i, 5, String.valueOf(file.getFileSizeAsString()));
\r
679 final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
\r
680 table.setText(i, 6, formatter.format(file.getModificationDate()));
\r
681 folderTotalSize += file.getContentLength();
\r
684 // Clear any remaining slots.
\r
685 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
\r
686 table.setHTML(i, 0, " ");
\r
687 table.setHTML(i, 1, " ");
\r
688 table.setHTML(i, 2, " ");
\r
689 table.setHTML(i, 3, " ");
\r
690 table.setHTML(i, 4, " ");
\r
691 table.setHTML(i, 5, " ");
\r
692 table.setHTML(i, 6, " ");
\r
693 table.setHTML(i, 7, " ");
\r
696 if (folderFileCount == 0) {
\r
697 showingStats = "no files";
\r
698 prevButton.setVisible(false);
\r
699 nextButton.setVisible(false);
\r
700 } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
\r
701 if (folderFileCount == 1)
\r
702 showingStats = "1 file";
\r
704 showingStats = folderFileCount + " files";
\r
705 showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
\r
706 prevButton.setVisible(false);
\r
707 nextButton.setVisible(false);
\r
709 showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
\r
710 prevButton.setVisible(startIndex != 0);
\r
711 nextButton.setVisible(startIndex + GSS.VISIBLE_FILE_COUNT < count);
\r
713 updateCurrentlyShowingStats();
\r
718 * Return the proper icon based on the MIME type of the file.
\r
723 private AbstractImagePrototype getFileIcon(FileResource file) {
\r
724 String mimetype = file.getContentType();
\r
725 boolean shared=false;
\r
726 Folders folders = GSS.get().getFolders();
\r
727 if(folders.getCurrent() != null && folders.isOthersSharedItem(folders.getCurrent())){
\r
728 DnDTreeItem otherUser = (DnDTreeItem) folders.getUserOfSharedItem(folders.getCurrent());
\r
729 if(otherUser==null)
\r
732 String uname = otherUser.getOtherUserResource().getUsername();
\r
734 uname = ((DnDTreeItem)folders.getSharesItem()).getOthersResource().getUsernameOfUri(otherUser.getOtherUserResource().getUri());
\r
736 shared = file.isShared();
\r
740 shared = file.isShared();
\r
741 if (mimetype == null)
\r
742 return shared ? AbstractImagePrototype.create(images.documentShared()) : AbstractImagePrototype.create(images.document());
\r
743 mimetype = mimetype.toLowerCase();
\r
744 if (mimetype.startsWith("application/pdf"))
\r
745 return shared ? AbstractImagePrototype.create(images.pdfShared()) : AbstractImagePrototype.create(images.pdf());
\r
746 else if (mimetype.endsWith("excel"))
\r
747 return shared ? AbstractImagePrototype.create(images.spreadsheetShared()) : AbstractImagePrototype.create(images.spreadsheet());
\r
748 else if (mimetype.endsWith("msword"))
\r
749 return shared ? AbstractImagePrototype.create(images.wordprocessorShared()) : AbstractImagePrototype.create(images.wordprocessor());
\r
750 else if (mimetype.endsWith("powerpoint"))
\r
751 return shared ? AbstractImagePrototype.create(images.presentationShared()) : AbstractImagePrototype.create(images.presentation());
\r
752 else if (mimetype.startsWith("application/zip") ||
\r
753 mimetype.startsWith("application/gzip") ||
\r
754 mimetype.startsWith("application/x-gzip") ||
\r
755 mimetype.startsWith("application/x-tar") ||
\r
756 mimetype.startsWith("application/x-gtar"))
\r
757 return shared ? AbstractImagePrototype.create(images.zipShared()) : AbstractImagePrototype.create(images.zip());
\r
758 else if (mimetype.startsWith("text/html"))
\r
759 return shared ? AbstractImagePrototype.create(images.htmlShared()) : AbstractImagePrototype.create(images.html());
\r
760 else if (mimetype.startsWith("text/plain"))
\r
761 return shared ? AbstractImagePrototype.create(images.txtShared()) : AbstractImagePrototype.create(images.txt());
\r
762 else if (mimetype.startsWith("image/"))
\r
763 return shared ? AbstractImagePrototype.create(images.imageShared()) : AbstractImagePrototype.create(images.image());
\r
764 else if (mimetype.startsWith("video/"))
\r
765 return shared ? AbstractImagePrototype.create(images.videoShared()) : AbstractImagePrototype.create(images.video());
\r
766 else if (mimetype.startsWith("audio/"))
\r
767 return shared ? AbstractImagePrototype.create(images.audioShared()) : AbstractImagePrototype.create(images.audio());
\r
768 return shared ? AbstractImagePrototype.create(images.documentShared()) : AbstractImagePrototype.create(images.document());
\r
772 * Update status panel with currently showing file stats.
\r
774 public void updateCurrentlyShowingStats() {
\r
775 GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
\r
779 * Adjust the height of the table by adding and removing rows as necessary.
\r
781 * @param newHeight the new height to reach
\r
783 void resizeTableHeight(final int newHeight) {
\r
784 GWT.log("Panel: " + newHeight + ", parent: " + table.getParent().getOffsetHeight(), null);
\r
785 // Fill the rest with empty slots.
\r
786 if (newHeight > table.getOffsetHeight())
\r
787 while (newHeight > table.getOffsetHeight()) {
\r
788 table.resizeRows(table.getRowCount() + 1);
\r
789 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);
\r
792 while (newHeight < table.getOffsetHeight()) {
\r
793 table.resizeRows(table.getRowCount() - 1);
\r
794 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);
\r
798 public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection) {
\r
799 updateFileCache(updateSelectedFolder, clearSelection, null);
\r
802 public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection, final String newFilename) {
\r
803 if (!updateSelectedFolder && !GSS.get().getFolders().getTrashItem().equals(GSS.get().getFolders().getCurrent()))
\r
804 updateFileCache(clearSelection);
\r
805 else if (GSS.get().getFolders().getCurrent() != null) {
\r
806 final DnDTreeItem folderItem = (DnDTreeItem) GSS.get().getFolders().getCurrent();
\r
807 if( folderItem.getFolderResource()!= null){
\r
808 if(GSS.get().getFolders().isFileItem(folderItem) || GSS.get().getFolders().isMySharedItem(folderItem) || GSS.get().getFolders().isOthersSharedItem(folderItem) ){
\r
810 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, folderItem.getFolderResource().getUri(),folderItem.getFolderResource()) {
\r
813 public void onComplete() {
\r
814 folderItem.setUserObject(getResult());
\r
815 if(GSS.get().getFolders().isFileItem(folderItem)){
\r
816 String[] filePaths = new String[folderItem.getFolderResource().getFilePaths().size()];
\r
818 for(String fpath : folderItem.getFolderResource().getFilePaths()){
\r
819 filePaths[c] = fpath + "?" + Math.random();
\r
822 MultipleHeadCommand<FileResource> getFiles = new MultipleHeadCommand<FileResource>(FileResource.class, filePaths, folderItem.getFolderResource().getFileCache()){
\r
825 public void onComplete(){
\r
826 List<FileResource> result = getResult();
\r
827 //remove random from path
\r
828 for(FileResource r : result){
\r
829 String p = r.getUri();
\r
830 int indexOfQuestionMark = p.lastIndexOf('?');
\r
831 if(indexOfQuestionMark>0)
\r
832 r.setUri(p.substring(0, indexOfQuestionMark));
\r
833 GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
\r
835 folderItem.getFolderResource().setFiles(result);
\r
836 folderItem.getFolderResource().setFilesExpanded(true);
\r
837 updateFileCache(clearSelection, newFilename);
\r
841 public void onError(String p, Throwable throwable) {
\r
842 if(throwable instanceof RestException)
\r
843 GSS.get().displayError("Unable to retrieve file details:"+((RestException)throwable).getHttpStatusText());
\r
847 public void onError(Throwable t) {
\r
849 GSS.get().displayError("Unable to fetch files for folder " + folderItem.getFolderResource().getName());
\r
853 DeferredCommand.addCommand(getFiles);
\r
856 updateFileCache(clearSelection, newFilename);
\r
860 public void onError(Throwable t) {
\r
862 GSS.get().displayError("Unable to fetch folder " + folderItem.getFolderResource().getName());
\r
865 DeferredCommand.addCommand(gf);
\r
868 else if (folderItem.getTrashResource() != null) {
\r
869 GetCommand<TrashResource> gt = new GetCommand<TrashResource>(TrashResource.class, folderItem.getTrashResource().getUri(), null) {
\r
872 public void onComplete() {
\r
873 folderItem.setUserObject(getResult());
\r
874 updateFileCache(clearSelection);
\r
878 public void onError(Throwable t) {
\r
879 if (t instanceof RestException && (((RestException) t).getHttpStatusCode() == 204 || ((RestException) t).getHttpStatusCode() == 1223)) {
\r
880 folderItem.setUserObject(new TrashResource(folderItem.getTrashResource().getUri()));
\r
881 updateFileCache(clearSelection);
\r
884 GSS.get().displayError("Unable to fetch trash resource");
\r
888 DeferredCommand.addCommand(gt);
\r
889 } else if (folderItem.getSharedResource() != null) {
\r
890 GetCommand<SharedResource> gt = new GetCommand<SharedResource>(SharedResource.class, folderItem.getSharedResource().getUri(), null) {
\r
893 public void onComplete() {
\r
894 folderItem.setUserObject(getResult());
\r
895 updateFileCache(clearSelection, newFilename);
\r
896 String[] filePaths = new String[folderItem.getSharedResource().getFilePaths().size()];
\r
898 for(String fpath : folderItem.getSharedResource().getFilePaths()){
\r
899 filePaths[c] = fpath + "?" + Math.random();
\r
902 MultipleHeadCommand<FileResource> getFiles = new MultipleHeadCommand<FileResource>(FileResource.class, filePaths, folderItem.getSharedResource().getFileCache()){
\r
905 public void onComplete(){
\r
906 List<FileResource> result = getResult();
\r
907 //remove random from path
\r
908 for(FileResource r : result){
\r
909 String p = r.getUri();
\r
910 int indexOfQuestionMark = p.lastIndexOf('?');
\r
911 if(indexOfQuestionMark>0)
\r
912 r.setUri(p.substring(0, indexOfQuestionMark));
\r
913 GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
\r
915 folderItem.getSharedResource().setFiles(result);
\r
916 folderItem.getSharedResource().setFilesExpanded(true);
\r
917 updateFileCache(clearSelection, newFilename);
\r
921 public void onError(String p, Throwable throwable) {
\r
922 if(throwable instanceof RestException)
\r
923 GSS.get().displayError("Unable to retrieve file details:"+((RestException)throwable).getHttpStatusText());
\r
927 public void onError(Throwable t) {
\r
929 GSS.get().displayError("Unable to fetch files for folder " + folderItem.getFolderResource().getName());
\r
933 DeferredCommand.addCommand(getFiles);
\r
937 public void onError(Throwable t) {
\r
939 GSS.get().displayError("Unable to fetch My Shares resource");
\r
942 DeferredCommand.addCommand(gt);
\r
943 } else if (folderItem.getOtherUserResource() != null) {
\r
944 GetCommand<OtherUserResource> gt = new GetCommand<OtherUserResource>(OtherUserResource.class, folderItem.getOtherUserResource().getUri(), null) {
\r
947 public void onComplete() {
\r
948 folderItem.setUserObject(getResult());
\r
949 updateFileCache(clearSelection, newFilename);
\r
950 String[] filePaths = new String[folderItem.getOtherUserResource().getFilePaths().size()];
\r
952 for(String fpath : folderItem.getOtherUserResource().getFilePaths()){
\r
953 filePaths[c] = fpath + "?" + Math.random();
\r
956 MultipleHeadCommand<FileResource> getFiles = new MultipleHeadCommand<FileResource>(FileResource.class, filePaths, folderItem.getOtherUserResource().getFileCache()){
\r
959 public void onComplete(){
\r
960 List<FileResource> result = getResult();
\r
961 //remove random from path
\r
962 for(FileResource r : result){
\r
963 String p = r.getUri();
\r
964 int indexOfQuestionMark = p.lastIndexOf('?');
\r
965 if(indexOfQuestionMark>0)
\r
966 r.setUri(p.substring(0, indexOfQuestionMark));
\r
967 GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
\r
969 folderItem.getOtherUserResource().setFiles(result);
\r
970 folderItem.getOtherUserResource().setFilesExpanded(true);
\r
971 updateFileCache(clearSelection, newFilename);
\r
975 public void onError(String p, Throwable throwable) {
\r
976 if(throwable instanceof RestException)
\r
977 GSS.get().displayError("Unable to retrieve file details:"+((RestException)throwable).getHttpStatusText());
\r
981 public void onError(Throwable t) {
\r
983 GSS.get().displayError("Unable to fetch files for folder " + folderItem.getFolderResource().getName());
\r
987 DeferredCommand.addCommand(getFiles);
\r
991 public void onError(Throwable t) {
\r
993 GSS.get().displayError("Unable to fetch My Shares resource");
\r
996 DeferredCommand.addCommand(gt);
\r
999 updateFileCache(clearSelection);
\r
1002 private void updateFileCache(boolean clearSelection) {
\r
1003 updateFileCache(clearSelection, null);
\r
1007 * Update the file cache with data from the server.
\r
1009 * @param userId the ID of the current user
\r
1010 * @param newFilename the new name of the previously selected file,
\r
1011 * if a rename operation has taken place
\r
1013 private void updateFileCache(boolean clearSelection, String newFilename) {
\r
1014 if (clearSelection)
\r
1015 clearSelectedRows();
\r
1018 final TreeItem folderItem = GSS.get().getFolders().getCurrent();
\r
1020 if (folderItem == null || GSS.get().getFolders().isOthersShared(folderItem)) {
\r
1021 setFiles(new ArrayList<FileResource>());
\r
1025 if (folderItem instanceof DnDTreeItem) {
\r
1026 DnDTreeItem dnd = (DnDTreeItem) folderItem;
\r
1027 if (dnd.getFolderResource() != null) {
\r
1028 if (GSS.get().getFolders().isTrashItem(dnd))
\r
1029 setFiles(new ArrayList<FileResource>());
\r
1031 setFiles(dnd.getFolderResource().getFiles());
\r
1033 } else if (dnd.getTrashResource() != null)
\r
1034 setFiles(dnd.getTrashResource().getFiles());
\r
1035 else if (dnd.getSharedResource() != null)
\r
1036 setFiles(dnd.getSharedResource().getFiles());
\r
1037 else if (dnd.getOtherUserResource() != null)
\r
1038 setFiles(dnd.getOtherUserResource().getFiles());
\r
1040 setFiles(dnd.getFolderResource().getFiles());
\r
1043 if (!clearSelection && selectedRows.size()==1 && newFilename!=null) {
\r
1045 for (int i=1; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
\r
1046 if (startIndex + i > folderFileCount)
\r
1048 FileResource file = files.get(startIndex + i - 1);
\r
1049 if (newFilename.equals(file.getName())) {
\r
1054 clearSelectedRows();
\r
1056 selectRow(row, true);
\r
1062 * Fill the file cache with data.
\r
1064 public void setFiles(final List<FileResource> _files) {
\r
1065 if (_files.size() > 0 && !GSS.get().getFolders().isTrash(GSS.get().getFolders().getCurrent())) {
\r
1066 files = new ArrayList<FileResource>();
\r
1067 for (FileResource fres : _files)
\r
1068 if (!fres.isDeleted())
\r
1072 Collections.sort(files, new Comparator<FileResource>() {
\r
1074 public int compare(FileResource arg0, FileResource arg1) {
\r
1075 return arg0.getName().compareTo(arg1.getName());
\r
1079 folderFileCount = files.size();
\r
1082 private void sortFiles(final String sortProperty) {
\r
1083 if (sortProperty.equals(sortingProperty))
\r
1084 sortingType = !sortingType;
\r
1086 sortingProperty = sortProperty;
\r
1087 sortingType = true;
\r
1092 private void clearLabels() {
\r
1093 nameLabel.setText("Name");
\r
1094 versionLabel.setText("Version");
\r
1095 sizeLabel.setText("Size");
\r
1096 dateLabel.setText("Last modified");
\r
1097 ownerLabel.setText("Owner");
\r
1098 pathLabel.setText("Path");
\r
1102 * Retrieve the table.
\r
1104 * @return the table
\r
1111 * Does the list contains the requested filename
\r
1114 * @return true/false
\r
1116 public boolean contains(String fileName) {
\r
1117 for (int i = 0; i < files.size(); i++)
\r
1118 if (files.get(i).getName().equals(fileName))
\r
1123 public void clearSelectedRows() {
\r
1124 for (int r : selectedRows) {
\r
1125 int row = r - startIndex;
\r
1126 styleRow(row, false);
\r
1128 selectedRows.clear();
\r
1129 Object sel = GSS.get().getCurrentSelection();
\r
1130 if (sel instanceof FileResource || sel instanceof List)
\r
1131 GSS.get().setCurrentSelection(null);
\r
1137 public void selectAllRows() {
\r
1138 clearSelectedRows();
\r
1139 int count = folderFileCount;
\r
1142 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
\r
1146 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
\r
1147 // Don't read past the end.
\r
1148 // if (i > folderFileCount)
\r
1150 if (startIndex + i > folderFileCount)
\r
1152 selectedRows.add(startIndex + i - 1);
\r
1153 styleRow(i - 1, true);
\r
1155 GSS.get().setCurrentSelection(getSelectedFiles());
\r
1156 contextMenu.setFiles(getSelectedFiles());
\r
1157 makeRowDraggable(i-1);
\r
1161 private void makeRowDraggable(int row){
\r
1162 int contextRow = getWidgetRow(contextMenu, table);
\r
1163 if (contextRow != -1)
\r
1164 table.setWidget(contextRow, 0, getFileIcon(files.get(contextRow - 1)).createImage());
\r
1165 contextMenu.setWidget(new HTML(getFileIcon(files.get(row - 1)).getHTML()));
\r
1166 table.setWidget(row, 0, contextMenu);
\r
1169 private int getWidgetRow(Widget widget, Grid grid) {
\r
1170 for (int row = 0; row < grid.getRowCount(); row++)
\r
1171 for (int col = 0; col < grid.getCellCount(row); col++) {
\r
1172 Widget w = table.getWidget(row, col);
\r