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