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