Automated merge with https://gss.googlecode.com/hg/
[pithos] / src / gr / ebs / gss / client / FileList.java
1 /*
2  * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
3  *
4  * This file is part of GSS.
5  *
6  * GSS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 package gr.ebs.gss.client;
20
21 import static com.google.gwt.query.client.GQuery.$;
22 import gr.ebs.gss.client.rest.GetCommand;
23 import gr.ebs.gss.client.rest.RestCommand;
24 import gr.ebs.gss.client.rest.resource.FileResource;
25 import gr.ebs.gss.client.rest.resource.RestResource;
26 import gr.ebs.gss.client.rest.resource.RestResourceWrapper;
27 import gr.ebs.gss.client.rest.resource.SharedResource;
28 import gr.ebs.gss.client.rest.resource.TrashResource;
29 import gr.ebs.gss.client.rest.resource.UserResource;
30 import gr.ebs.gss.client.rest.resource.UserSearchResource;
31 import gwtquery.plugins.draggable.client.DraggableOptions;
32 import gwtquery.plugins.draggable.client.StopDragException;
33 import gwtquery.plugins.draggable.client.DraggableOptions.DragFunction;
34 import gwtquery.plugins.draggable.client.DraggableOptions.RevertOption;
35 import gwtquery.plugins.draggable.client.events.DragContext;
36 import gwtquery.plugins.draggable.client.events.DragStartEvent;
37 import gwtquery.plugins.draggable.client.events.DragStopEvent;
38 import gwtquery.plugins.draggable.client.events.DragStartEvent.DragStartEventHandler;
39 import gwtquery.plugins.draggable.client.events.DragStopEvent.DragStopEventHandler;
40 import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTable;
41 import gwtquery.plugins.droppable.client.gwt.DragAndDropColumn;
42
43 import java.util.ArrayList;
44 import java.util.Collections;
45 import java.util.Comparator;
46 import java.util.Iterator;
47 import java.util.List;
48
49 import com.google.gwt.cell.client.AbstractCell;
50 import com.google.gwt.cell.client.ImageResourceCell;
51 import com.google.gwt.cell.client.SafeHtmlCell;
52 import com.google.gwt.cell.client.TextCell;
53 import com.google.gwt.cell.client.ValueUpdater;
54 import com.google.gwt.core.client.GWT;
55 import com.google.gwt.core.client.Scheduler;
56 import com.google.gwt.core.client.Scheduler.RepeatingCommand;
57 import com.google.gwt.dom.client.Style.Cursor;
58 import com.google.gwt.http.client.URL;
59 import com.google.gwt.i18n.client.DateTimeFormat;
60 import com.google.gwt.resources.client.ClientBundle;
61 import com.google.gwt.resources.client.ImageResource;
62 import com.google.gwt.safehtml.client.SafeHtmlTemplates;
63 import com.google.gwt.safehtml.shared.SafeHtml;
64 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
65 import com.google.gwt.safehtml.shared.SafeHtmlUtils;
66 import com.google.gwt.user.cellview.client.CellTable;
67 import com.google.gwt.user.cellview.client.Column;
68 import com.google.gwt.user.cellview.client.TextColumn;
69 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
70 import com.google.gwt.user.client.DOM;
71 import com.google.gwt.user.client.DeferredCommand;
72 import com.google.gwt.user.client.Event;
73 import com.google.gwt.user.client.Window;
74 import com.google.gwt.user.client.ui.AbstractImagePrototype;
75 import com.google.gwt.user.client.ui.Composite;
76 import com.google.gwt.user.client.ui.HTML;
77 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
78 import com.google.gwt.user.client.ui.HorizontalPanel;
79 import com.google.gwt.user.client.ui.VerticalPanel;
80 import com.google.gwt.view.client.MultiSelectionModel;
81 import com.google.gwt.view.client.ProvidesKey;
82 import com.google.gwt.view.client.SelectionChangeEvent;
83 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
84
85 /**
86  * A composite that displays the list of files in a particular folder.
87  */
88 public class FileList extends Composite {
89
90         interface TableResources extends DragAndDropCellTable.Resources {
91             @Source({CellTable.Style.DEFAULT_CSS, "GssCellTable.css"})
92             TableStyle cellTableStyle();
93           }
94         
95         static interface Templates extends SafeHtmlTemplates {
96             Templates INSTANCE = GWT.create(Templates.class);
97
98             @Template("<div id='dragHelper' style='border:1px solid black; background-color:#ffffff; color:black; width:150px;z-index:100'></div>")
99             SafeHtml outerHelper();
100           }
101         
102         
103         /**
104            * The styles applied to the table.
105            */
106           interface TableStyle extends CellTable.Style {
107           }
108
109         private String showingStats = "";
110
111         private int startIndex = 0;
112
113         /**
114          * A constant that denotes the completion of an IncrementalCommand.
115          */
116         public static final boolean DONE = false;
117
118         
119         
120         private final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
121
122         /**
123          * Specifies that the images available for this composite will be the ones
124          * available in FileContextMenu.
125          */
126         public interface Images extends ClientBundle,FileContextMenu.Images, CellTreeView.Images {
127
128                 @Source("gr/ebs/gss/resources/blank.gif")
129                 ImageResource blank();
130
131                 @Source("gr/ebs/gss/resources/asc.png")
132                 ImageResource asc();
133
134                 @Source("gr/ebs/gss/resources/desc.png")
135                 ImageResource desc();
136
137                 @Source("gr/ebs/gss/resources/mimetypes/document_shared.png")
138                 ImageResource documentShared();
139
140                 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst.png")
141                 ImageResource wordprocessor();
142
143                 @Source("gr/ebs/gss/resources/mimetypes/log.png")
144                 ImageResource spreadsheet();
145
146                 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr.png")
147                 ImageResource presentation();
148
149                 @Source("gr/ebs/gss/resources/mimetypes/acroread.png")
150                 ImageResource pdf();
151
152                 @Source("gr/ebs/gss/resources/mimetypes/image.png")
153                 ImageResource image();
154
155                 @Source("gr/ebs/gss/resources/mimetypes/video2.png")
156                 ImageResource video();
157
158                 @Source("gr/ebs/gss/resources/mimetypes/knotify.png")
159                 ImageResource audio();
160
161                 @Source("gr/ebs/gss/resources/mimetypes/html.png")
162                 ImageResource html();
163
164                 @Source("gr/ebs/gss/resources/mimetypes/txt.png")
165                 ImageResource txt();
166
167                 @Source("gr/ebs/gss/resources/mimetypes/ark2.png")
168                 ImageResource zip();
169
170                 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst_shared.png")
171                 ImageResource wordprocessorShared();
172
173                 @Source("gr/ebs/gss/resources/mimetypes/log_shared.png")
174                 ImageResource spreadsheetShared();
175
176                 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr_shared.png")
177                 ImageResource presentationShared();
178
179                 @Source("gr/ebs/gss/resources/mimetypes/acroread_shared.png")
180                 ImageResource pdfShared();
181
182                 @Source("gr/ebs/gss/resources/mimetypes/image_shared.png")
183                 ImageResource imageShared();
184
185                 @Source("gr/ebs/gss/resources/mimetypes/video2_shared.png")
186                 ImageResource videoShared();
187
188                 @Source("gr/ebs/gss/resources/mimetypes/knotify_shared.png")
189                 ImageResource audioShared();
190
191                 @Source("gr/ebs/gss/resources/mimetypes/html_shared.png")
192                 ImageResource htmlShared();
193
194                 @Source("gr/ebs/gss/resources/mimetypes/txt_shared.png")
195                 ImageResource txtShared();
196
197                 @Source("gr/ebs/gss/resources/mimetypes/ark2_shared.png")
198                 ImageResource zipShared();
199
200         }
201         
202         DragStopEventHandler dragStop = new DragStopEventHandler() {
203                 
204                 @Override
205                 public void onDragStop(DragStopEvent event) {
206                         GWT.log("DRAG STOPPED");
207                         
208                 }
209         };
210         
211         private static class ContactCell extends AbstractCell<gr.ebs.gss.client.rest.resource.FileResource> {
212
213             /**
214              * The html of the image used for contacts.
215              * 
216              */
217             private final String imageHtml;
218
219             public ContactCell(ImageResource image) {
220               this.imageHtml = AbstractImagePrototype.create(image).getHTML();
221             }
222
223             
224
225                 
226
227             @Override
228             public void render(Context context, FileResource value, SafeHtmlBuilder sb) {
229               // Value can be null, so do a null check..
230               if (value == null) {
231                 return;
232               }
233
234               sb.appendHtmlConstant("<table>");
235
236               // Add the contact image.
237               sb.appendHtmlConstant("<tr><td rowspan='3'>");
238               sb.appendHtmlConstant(imageHtml);
239               sb.appendHtmlConstant("</td>");
240
241               // Add the name and address.
242               DisplayHelper.log("value.getName()");
243               sb.appendHtmlConstant("<td style='font-size:95%;' id='"+value.getName()+"'>");
244               sb.appendEscaped(value.getName());
245               sb.appendHtmlConstant("</td></tr><tr><td>");
246               sb.appendEscaped(value.getFileSizeAsString());
247               sb.appendHtmlConstant("</td></tr></table>");
248             }
249
250
251           }
252         /**
253          * Retrieve the celltable.
254          *
255          * @return the celltable
256          */
257         public DragAndDropCellTable<FileResource> getCelltable() {
258                 return celltable;
259         }
260         /**
261          * A label with the number of files in this folder.
262          */
263         private HTML countLabel = new HTML();
264
265         /**
266          * The table widget with the file list.
267          */
268         //private FileTable table = new FileTable(GSS.VISIBLE_FILE_COUNT + 1, 8);
269
270         /**
271          * The navigation bar for paginating the results.
272          */
273         private HorizontalPanel navBar = new HorizontalPanel();
274
275         /**
276          * The number of files in this folder.
277          */
278         int folderFileCount;
279
280         /**
281          * Total folder size
282          */
283         long folderTotalSize;
284
285         /**
286          * A cache of the files in the list.
287          */
288         private List<FileResource> files;
289
290         /**
291          * The widget's image bundle.
292          */
293         private final Images images;
294         VerticalPanel panel;
295         
296         private FileContextMenu menuShowing;
297         private DragAndDropCellTable<FileResource> celltable;
298         private final MultiSelectionModel<FileResource> selectionModel;
299         private final List<SortableHeader> allHeaders = new ArrayList<SortableHeader>();
300         SortableHeader nameHeader;
301         /**
302          * Construct the file list widget. This entails setting up the widget
303          * layout, fetching the number of files in the current folder from the
304          * server and filling the local file cache of displayed files with data from
305          * the server, as well.
306          *
307          * @param _images
308          */
309         public FileList(Images _images) {
310                 images = _images;
311                 DragAndDropCellTable.Resources resources = GWT.create(TableResources.class);
312                 
313                 
314                 // Create the 'navigation' bar at the upper-right.
315                 HorizontalPanel innerNavBar = new HorizontalPanel();
316                 innerNavBar.setStyleName("gss-ListNavBar");
317                 innerNavBar.setSpacing(8);
318                 innerNavBar.add(countLabel);
319                 navBar.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
320                 navBar.add(innerNavBar);
321                 navBar.setWidth("100%");
322                 ProvidesKey<FileResource> keyProvider = new ProvidesKey<FileResource>(){
323
324                         @Override
325                         public Object getKey(FileResource item) {
326                                 return item.getUri();
327                         }
328                         
329                 };
330                 final DragAndDropColumn<FileResource,SafeHtml> nameColumn = new DragAndDropColumn<FileResource,SafeHtml>(new SafeHtmlCell()) {
331
332
333                         @Override
334                         public SafeHtml getValue(FileResource object) {
335                                 SafeHtmlBuilder sb = new SafeHtmlBuilder();
336                                 if (object.getContentType().endsWith("png") || object.getContentType().endsWith("gif") || object.getContentType().endsWith("jpeg") ){                                   
337                                         sb.appendHtmlConstant("<span id='fileList."+ object.getName() +"'>");
338                                         sb.appendEscaped(object.getName());
339                                         sb.appendHtmlConstant("</span>");
340                                         sb.appendHtmlConstant(" <a href='" +
341                                 GSS.get().getTopPanel().getFileMenu().getDownloadURL(object) +
342                                 "' title='" + object.getOwner() + " : " + object.getPath() + object.getName() +
343                                 "' rel='lytebox[mnf]' " +
344                                 "onclick='myLytebox.start(this, false, false); return false;'>" +
345                                 "(view)" + "</a>");
346                                         
347                                         
348                                 }
349                                 else{                                   
350                                         sb.appendHtmlConstant("<span id='fileList."+ object.getName() +"'>");
351                                         sb.appendEscaped(object.getName());
352                                         sb.appendHtmlConstant("</span>");
353                                 }
354                                 return sb.toSafeHtml();
355                         }
356                         
357                         
358                 };
359                 initDragOperation(nameColumn);
360                 celltable = new DragAndDropCellTable<FileResource>(100,resources,keyProvider){
361                         @Override
362                         protected void onBrowserEvent2(Event event) {
363                                 /*if (DOM.eventGetType((Event) event) == Event.ONMOUSEDOWN && DOM.eventGetButton((Event) event) == NativeEvent.BUTTON_RIGHT){
364                                         fireClickEvent((Element) event.getEventTarget().cast());                                        
365                                 }*/
366                                 super.onBrowserEvent2(event);
367                         }
368                 };
369                 
370                 celltable.addDragStopHandler(dragStop);
371                 celltable.addDragStartHandler(new DragStartEventHandler() {
372
373                       public void onDragStart(DragStartEvent event) {
374                         FileResource value = event.getDraggableData();
375                         com.google.gwt.dom.client.Element helper = event.getHelper();
376                         SafeHtmlBuilder sb = new SafeHtmlBuilder();
377                         sb.appendHtmlConstant("<b>");
378                         DisplayHelper.log(value.getName());
379                         sb.appendEscaped(value.getName());
380                         sb.appendHtmlConstant("</b>");
381                         helper.setInnerHTML(sb.toSafeHtml().asString());
382
383                       }
384                     });
385                 Column<FileResource, ImageResource> status = new Column<FileResource, ImageResource>(new ImageResourceCell()) {
386                   @Override
387                   public ImageResource getValue(FileResource entity) {
388                     return getFileIcon(entity);
389                   }
390                };
391                celltable.addColumn(status,"");
392                 
393                 
394                 celltable.addColumn(nameColumn,nameHeader = new SortableHeader("Name"));
395                 allHeaders.add(nameHeader);
396                 nameHeader.setSorted(true);
397                 nameHeader.toggleReverseSort();
398                 nameHeader.setUpdater(new FileValueUpdater(nameHeader, "name"));
399                 celltable.redrawHeaders();
400                 SortableHeader aheader;
401                 celltable.addColumn(new TextColumn<FileResource>() {
402                         @Override
403                         public String getValue(FileResource object) {
404                                 return GSS.get().findUserFullName(object.getOwner());
405                         }                       
406                 },aheader = new SortableHeader("Owner"));
407                 allHeaders.add(aheader);
408                 aheader.setUpdater(new FileValueUpdater(aheader, "owner"));
409                 celltable.addColumn(new TextColumn<FileResource>() {
410                         @Override
411                         public String getValue(FileResource object) {
412                                 // TODO Auto-generated method stub
413                                 return object.getPath();
414                         }                       
415                 },aheader = new SortableHeader("Path"));
416                 allHeaders.add(aheader);
417                 aheader.setUpdater(new FileValueUpdater(aheader, "path"));      
418                 celltable.addColumn(new TextColumn<FileResource>() {
419                         @Override
420                         public String getValue(FileResource object) {
421                                 // TODO Auto-generated method stub
422                                 return object.getVersion().toString();
423                         }                       
424                 },aheader = new SortableHeader("Version"));
425                 allHeaders.add(aheader);
426                 aheader.setUpdater(new FileValueUpdater(aheader, "version"));
427                 celltable.addColumn(new TextColumn<FileResource>() {
428                         @Override
429                         public String getValue(FileResource object) {
430                                 // TODO Auto-generated method stub
431                                 return object.getFileSizeAsString();
432                         }                       
433                 },aheader = new SortableHeader("Size"));
434                 allHeaders.add(aheader);
435                 aheader.setUpdater(new FileValueUpdater(aheader, "size"));      
436                 celltable.addColumn(new TextColumn<FileResource>() {
437                         @Override
438                         public String getValue(FileResource object) {
439                                 return formatter.format(object.getModificationDate());
440                         }                       
441                 },aheader = new SortableHeader("Last Modified"));
442                 allHeaders.add(aheader);
443                 aheader.setUpdater(new FileValueUpdater(aheader, "date"));
444                 
445                 initWidget(celltable);
446                 setStyleName("gss-List");
447                 selectionModel = new MultiSelectionModel<FileResource>();
448                 
449
450                  Handler selectionHandler = new SelectionChangeEvent.Handler() { 
451              @Override 
452              public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
453                  if(getSelectedFiles().size()==1)
454                          GSS.get().setCurrentSelection(getSelectedFiles().get(0));
455                  else
456                          GSS.get().setCurrentSelection(getSelectedFiles());
457                                 //contextMenu.setFiles(getSelectedFiles());
458              }
459          };
460          selectionModel.addSelectionChangeHandler(selectionHandler);
461          
462                 celltable.setSelectionModel(selectionModel,GSSSelectionEventManager.<FileResource>createDefaultManager());
463                 celltable.setPageSize(GSS.VISIBLE_FILE_COUNT);
464                 celltable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
465                 Scheduler.get().scheduleIncremental(new RepeatingCommand() {
466
467                         @Override
468                         public boolean execute() {
469                                 return fetchRootFolder();
470                         }
471                 });
472                 sinkEvents(Event.ONCONTEXTMENU);
473                 sinkEvents(Event.ONMOUSEUP);
474                 sinkEvents(Event.ONMOUSEDOWN);
475                 sinkEvents(Event.ONCLICK);
476                 sinkEvents(Event.ONKEYDOWN);
477                 sinkEvents(Event.ONDBLCLICK);
478                 GSS.preventIESelection();
479         }
480         
481         //public native void fireClickEvent(Element element) /*-{
482           //  var evObj = $doc.createEvent('MouseEvents');
483             //evObj.initEvent('click', true, true);
484             //element.dispatchEvent(evObj);
485         //}-*/;
486
487          public List<FileResource> getSelectedFiles() {
488          return new ArrayList<FileResource>(selectionModel.getSelectedSet());
489          }
490         
491          private void initDragOperation(DragAndDropColumn<?, ?> column) {
492
493                     // retrieve draggableOptions on the column
494                     DraggableOptions draggableOptions = column.getDraggableOptions();
495                     // use template to construct the helper. The content of the div will be set
496                     // after
497                     draggableOptions.setHelper($(Templates.INSTANCE.outerHelper().asString()));
498                     //draggableOptions.setZIndex(100);
499                     // opacity of the helper
500                     draggableOptions.setAppendTo("body"); 
501                     //draggableOptions.setOpacity((float) 0.8);
502                     draggableOptions.setContainment("document");
503                     // cursor to use during the drag operation
504                     draggableOptions.setCursor(Cursor.MOVE);
505                     // set the revert option
506                     draggableOptions.setRevert(RevertOption.ON_INVALID_DROP);
507                     // prevents dragging when user click on the category drop-down list
508                     draggableOptions.setCancel("select");
509                     
510                     draggableOptions.setOnBeforeDragStart(new DragFunction() {
511                                 
512                                 @Override
513                                 public void f(DragContext context) {
514                                          FileResource value = context.getDraggableData();
515                                      if(!selectionModel.isSelected(value)){
516                                         throw new StopDragException();
517                                       }
518                                         
519                                 }
520                         });
521                   }
522         
523          public void showContextMenu(Event event){
524                  menuShowing = new FileContextMenu(images, false, true);
525                         menuShowing=menuShowing.onEmptyEvent(event);
526          }
527         @Override
528         public void onBrowserEvent(Event event) {
529                 
530                 if (files == null || files.size() == 0) {
531                         if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
532                                 menuShowing = new FileContextMenu(images, false, true);
533                                 menuShowing=menuShowing.onEmptyEvent(event);
534                                 event.preventDefault();
535                                 event.cancelBubble(true);
536                         }
537                         return;
538                 }
539                 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() != 0) {
540                         GWT.log("*****GOING TO SHOW CONTEXT MENU ****", null);
541                         menuShowing =  new FileContextMenu(images, false, false);
542                         menuShowing=menuShowing.onEvent(event);
543                         event.cancelBubble(true);
544                         event.preventDefault();
545                 } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
546                         menuShowing = new FileContextMenu(images, false, true);
547                         menuShowing=menuShowing.onEmptyEvent(event);
548                         event.cancelBubble(true);
549                         event.preventDefault();
550                 } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
551                         if (getSelectedFiles().size() == 1) {
552                                 GSS app = GSS.get();
553                                 FileResource file = getSelectedFiles().get(0);
554                                 String dateString = RestCommand.getDate();
555                                 String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());
556                                 String sig = app.getCurrentUserResource().getUsername() + " " +
557                                                 RestCommand.calculateSig("GET", dateString, resource,
558                                                 RestCommand.base64decode(app.getToken()));
559                                 Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");
560                                 event.preventDefault();
561                                 return;
562                         }
563                 super.onBrowserEvent(event);
564         }
565
566         /**
567          * Retrieve the root folder for the current user.
568          *
569          * @return true if the retrieval was successful
570          */
571         protected boolean fetchRootFolder() {
572                 UserResource user = GSS.get().getCurrentUserResource();
573                 if (user == null)
574                         return !DONE;
575                 // Update cache and clear selection.
576                 updateFileCache(true);
577                 return DONE;
578         }
579
580
581         /**
582          * Update the display of the file list.
583          */
584         void update(boolean sort) {
585                 int count = folderFileCount;
586                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
587                 if (max > count)
588                         max = count;
589                 folderTotalSize = 0;
590                 
591                 copyListAndContinue(files);
592                 for(FileResource f : files){
593                         folderTotalSize += f.getContentLength();
594                 }
595                 if (folderFileCount == 0) {
596                         showingStats = "no files";
597                 } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
598                         if (folderFileCount == 1)
599                                 showingStats = "1 file";
600                         else
601                                 showingStats = folderFileCount + " files";
602                         showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
603                 } else {
604                         showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
605                 }
606                 updateCurrentlyShowingStats();
607
608         }
609
610         /**
611          * Return the proper icon based on the MIME type of the file.
612          *
613          * @param file
614          * @return the icon
615          */
616         private ImageResource getFileIcon(FileResource file) {
617                 String mimetype = file.getContentType();
618                 boolean shared = false;
619                 //TODO: FETCH USER OF OTHER FOLDER ITEM
620                 //if(GSS.get().getTreeView().getSelection()!=null && (GSS.get().getTreeView().getSelection() instanceof OtherUserResource || GSS.get().getTreeView().getSelection() instanceof OthersFolderResource))
621                 /*Folders folders = GSS.get().getFolders();
622                 if(folders.getCurrent() != null && folders.isOthersSharedItem(folders.getCurrent())){
623                         DnDTreeItem otherUser = (DnDTreeItem) folders.getUserOfSharedItem(folders.getCurrent());
624                         if(otherUser==null)
625                                 shared = false;
626                         else{
627                                 String uname = otherUser.getOtherUserResource().getUsername();
628                                 if(uname==null)
629                                         uname = ((DnDTreeItem)folders.getSharesItem()).getOthersResource().getUsernameOfUri(otherUser.getOtherUserResource().getUri());
630                                 if(uname != null)
631                                         shared = file.isShared();
632                         }
633                 }
634                 else*/
635                         shared = file.isShared();
636                 if (mimetype == null)
637                         return shared ? images.documentShared() : images.document();
638                 mimetype = mimetype.toLowerCase();
639                 if (mimetype.startsWith("application/pdf"))
640                         return shared ? images.pdfShared() : images.pdf();
641                 else if (mimetype.endsWith("excel"))
642                         return shared ? images.spreadsheetShared() : images.spreadsheet();
643                 else if (mimetype.endsWith("msword"))
644                         return shared ? images.wordprocessorShared() : images.wordprocessor();
645                 else if (mimetype.endsWith("powerpoint"))
646                         return shared ? images.presentationShared() : images.presentation();
647                 else if (mimetype.startsWith("application/zip") ||
648                                         mimetype.startsWith("application/gzip") ||
649                                         mimetype.startsWith("application/x-gzip") ||
650                                         mimetype.startsWith("application/x-tar") ||
651                                         mimetype.startsWith("application/x-gtar"))
652                         return shared ? images.zipShared() : images.zip();
653                 else if (mimetype.startsWith("text/html"))
654                         return shared ? images.htmlShared() : images.html();
655                 else if (mimetype.startsWith("text/plain"))
656                         return shared ? images.txtShared() : images.txt();
657                 else if (mimetype.startsWith("image/"))
658                         return shared ? images.imageShared() : images.image();
659                 else if (mimetype.startsWith("video/"))
660                         return shared ? images.videoShared() : images.video();
661                 else if (mimetype.startsWith("audio/"))
662                         return shared ? images.audioShared() : images.audio();
663                 return shared ? images.documentShared() : images.document();
664         }
665
666         /**
667          * Update status panel with currently showing file stats.
668          */
669         public void updateCurrentlyShowingStats() {
670                 GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
671         }
672
673         public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection) {
674                 updateFileCache(updateSelectedFolder, clearSelection, null);
675         }
676
677         public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection, final String newFilename) {
678                 if (!updateSelectedFolder && !GSS.get().getTreeView().getSelection().equals(GSS.get().getTreeView().getTrash()))
679                         updateFileCache(clearSelection);
680                 else if (GSS.get().getTreeView().getSelection() != null) {
681                         update(true);
682                 }
683                 updateFileCache(clearSelection);
684         }
685
686
687         private void updateFileCache(boolean clearSelection) {
688                 updateFileCache(clearSelection, null);
689         }
690
691         /**
692          * Update the file cache with data from the server.
693          *
694          * @param newFilename the new name of the previously selected file,
695          *                      if a rename operation has taken place
696          */
697         private void updateFileCache(boolean clearSelection, String newFilename) {
698                 if (clearSelection)
699                         clearSelectedRows();
700                 startIndex = 0;
701                 final RestResource folderItem = GSS.get().getTreeView().getSelection();
702                 // Validation.
703                 if (folderItem == null || folderItem.equals(GSS.get().getTreeView().getOthers())) {
704                         setFiles(new ArrayList<FileResource>());
705                         update(true);
706                         return;
707                 }
708                 if (folderItem instanceof RestResourceWrapper) {
709                         setFiles(((RestResourceWrapper) folderItem).getResource().getFiles());
710                         update(true);
711                 }
712                 if (folderItem instanceof SharedResource) {
713                         setFiles(((SharedResource) folderItem).getFiles());
714                         update(true);
715                 }
716                 if (folderItem instanceof TrashResource) {
717                         setFiles(((TrashResource) folderItem).getFiles());
718                         update(true);
719                 }
720         }
721
722         /**
723          * Fill the file cache with data.
724          */
725         public void setFiles(final List<FileResource> _files) {
726                 if (_files.size() > 0 && ! (GSS.get().getTreeView().getSelection() instanceof TrashResource)) {
727                         files = new ArrayList<FileResource>();
728                         for (FileResource fres : _files)
729                                 if (!fres.isDeleted())
730                                         files.add(fres);
731                 }
732                 else
733                         files = _files;
734                 Collections.sort(files, new Comparator<FileResource>() {
735
736                         @Override
737                         public int compare(FileResource arg0, FileResource arg1) {
738                                 return arg0.getName().compareTo(arg1.getName());
739                         }
740
741                 });
742                 folderFileCount = files.size();
743         }
744
745         
746
747         
748         /**
749          * Does the list contains the requested filename
750          *
751          * @param fileName
752          * @return true/false
753          */
754         public boolean contains(String fileName) {
755                 for (int i = 0; i < files.size(); i++)
756                         if (files.get(i).getName().equals(fileName))
757                                 return true;
758                 return false;
759         }
760
761         public void clearSelectedRows() {
762                 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
763                 while(it.hasNext()){
764                         selectionModel.setSelected(it.next(),false);
765                 }
766         }
767
768         /**
769          *
770          */
771         public void selectAllRows() {
772                 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
773                 while(it.hasNext()){
774                         selectionModel.setSelected(it.next(),true);
775                 }
776
777
778         }
779
780         
781         private void sortFiles(final String sortingProperty, final boolean sortingType){
782                 Collections.sort(files, new Comparator<FileResource>() {
783
784             @Override
785             public int compare(FileResource arg0, FileResource arg1) {
786                     AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
787                     AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
788                     if (sortingType){
789                             if (sortingProperty.equals("version")) {
790                                     return arg0.getVersion().compareTo(arg1.getVersion());
791                             } else if (sortingProperty.equals("owner")) {
792                                     return arg0.getOwner().compareTo(arg1.getOwner());
793                             } else if (sortingProperty.equals("date")) {
794                                     return arg0.getModificationDate().compareTo(arg1.getModificationDate());
795                             } else if (sortingProperty.equals("size")) {
796                                     return arg0.getContentLength().compareTo(arg1.getContentLength());
797                             } else if (sortingProperty.equals("name")) {
798                                     return arg0.getName().compareTo(arg1.getName());
799                             } else if (sortingProperty.equals("path")) {
800                                     return arg0.getUri().compareTo(arg1.getUri());
801                             } else {
802                                     return arg0.getName().compareTo(arg1.getName());
803                             }
804                     }
805                     else if (sortingProperty.equals("version")) {
806                             
807                             return arg1.getVersion().compareTo(arg0.getVersion());
808                     } else if (sortingProperty.equals("owner")) {
809                             
810                             return arg1.getOwner().compareTo(arg0.getOwner());
811                     } else if (sortingProperty.equals("date")) {
812                             
813                             return arg1.getModificationDate().compareTo(arg0.getModificationDate());
814                     } else if (sortingProperty.equals("size")) {
815                             
816                             return arg1.getContentLength().compareTo(arg0.getContentLength());
817                     } else if (sortingProperty.equals("name")) {
818                             
819                             return arg1.getName().compareTo(arg0.getName());
820                     } else if (sortingProperty.equals("path")) {
821                             
822                             return arg1.getUri().compareTo(arg0.getUri());
823                     } else {
824                             
825                             return arg1.getName().compareTo(arg0.getName());
826                     }
827             }
828
829                 });
830         }
831         
832         final class FileValueUpdater implements ValueUpdater<String>{
833                 private String property;
834                 private SortableHeader header;
835                 /**
836                  * 
837                  */
838                 public FileValueUpdater(SortableHeader header,String property) {
839                         this.property=property;
840                         this.header=header;
841                 }
842                 @Override
843                 public void update(String value) {
844                         header.setSorted(true);
845                         header.toggleReverseSort();
846
847                 for (SortableHeader otherHeader : allHeaders) {
848                   if (otherHeader != header) {
849                     otherHeader.setSorted(false);
850                     otherHeader.setReverseSort(true);
851                   }
852                 }
853                 celltable.redrawHeaders();
854                 sortFiles(property, header.getReverseSort());
855                 FileList.this.update(true);                     
856                 }
857                 
858         }
859         /**
860          * Creates a new ArrayList<FileResources> from the given files ArrayList 
861          * in order that the input files remain untouched 
862          * and continues to find user's full names of each FileResource element
863          * in the new ArrayList
864          *    
865          * @param filesInput
866          */
867         private void copyListAndContinue(List<FileResource> filesInput){
868                 List<FileResource> copiedFiles = new ArrayList<FileResource>();         
869                 for(FileResource file : filesInput) {
870                         copiedFiles.add(file);
871                 }
872                 handleFullNames(copiedFiles);
873         }
874         
875         /**
876          * Examines whether or not the user's full name exists in the 
877          * userFullNameMap in the GSS.java for every element of the input list.
878          * If the user's full name does not exist in the map then a command is being made.  
879          * 
880          * @param filesInput
881          */
882         private void handleFullNames(List<FileResource> filesInput){            
883                 if(filesInput.size() == 0){
884                         showCellTable();
885                         return;
886                 }               
887
888                 if(GSS.get().findUserFullName(filesInput.get(0).getOwner()) == null){
889                         findFullNameAndUpdate(filesInput);              
890                         return;
891                 }
892                                 
893                 if(filesInput.size() >= 1){
894                         filesInput.remove(filesInput.get(0));
895                         if(filesInput.isEmpty()){
896                                 showCellTable();                                
897                         }else{
898                                 handleFullNames(filesInput);
899                         }
900                 }               
901         }
902         
903         /**
904          * Makes a command to search for full name from a given username. 
905          * Only after the completion of the command the celltable is shown
906          * or the search for the next full name continues.
907          *  
908          * @param filesInput
909          */
910         private void findFullNameAndUpdate(final List<FileResource> filesInput){                
911                 String aUserName = filesInput.get(0).getOwner();
912                 String path = GSS.get().getApiPath() + "users/" + aUserName; 
913
914                 GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class, path, false,null) {
915                         @Override
916                         public void onComplete() {
917                                 final UserSearchResource result = getResult();
918                                 for (UserResource user : result.getUsers()){
919                                         String username = user.getUsername();
920                                         String userFullName = user.getName();
921                                         GSS.get().putUserToMap(username, userFullName);
922                                         if(filesInput.size() >= 1){
923                                                 filesInput.remove(filesInput.get(0));
924                                                 if(filesInput.isEmpty()){
925                                                         showCellTable();
926                                                 }else{
927                                                         handleFullNames(filesInput);
928                                                 }                                                                                               
929                                         }                                                                       
930                                 }
931                         }
932                         @Override
933                         public void onError(Throwable t) {
934                                 GWT.log("", t);
935                                 GSS.get().displayError("Unable to fetch user's full name from the given username " + filesInput.get(0).getOwner());
936                                 if(filesInput.size() >= 1){
937                                         filesInput.remove(filesInput.get(0));
938                                         handleFullNames(filesInput);                                    
939                                 }
940                         }
941                 };
942                 DeferredCommand.addCommand(gg);
943         
944         }
945         /**
946          * Shows the files in the cellTable 
947          */
948
949         private void showCellTable(){
950                 celltable.setRowCount(files.size());
951                 celltable.setRowData(0,files);
952                 celltable.redrawHeaders();              
953         }
954
955         
956 }