right click selection done right
[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 gr.ebs.gss.client.dnd.DnDSimpleFocusPanel;
22 import gr.ebs.gss.client.dnd.DnDTreeItem;
23 import gr.ebs.gss.client.rest.GetCommand;
24 import gr.ebs.gss.client.rest.MultipleHeadCommand;
25 import gr.ebs.gss.client.rest.RestCommand;
26 import gr.ebs.gss.client.rest.RestException;
27 import gr.ebs.gss.client.rest.resource.FileResource;
28 import gr.ebs.gss.client.rest.resource.FolderResource;
29 import gr.ebs.gss.client.rest.resource.OtherUserResource;
30 import gr.ebs.gss.client.rest.resource.SharedResource;
31 import gr.ebs.gss.client.rest.resource.TrashResource;
32 import gr.ebs.gss.client.rest.resource.UserResource;
33
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.Iterator;
38 import java.util.List;
39
40 import com.google.gwt.cell.client.ImageResourceCell;
41 import com.google.gwt.cell.client.ValueUpdater;
42 import com.google.gwt.core.client.GWT;
43 import com.google.gwt.core.client.Scheduler;
44 import com.google.gwt.core.client.Scheduler.RepeatingCommand;
45 import com.google.gwt.dom.client.Element;
46 import com.google.gwt.dom.client.NativeEvent;
47 import com.google.gwt.http.client.URL;
48 import com.google.gwt.i18n.client.DateTimeFormat;
49 import com.google.gwt.resources.client.ClientBundle;
50 import com.google.gwt.resources.client.ImageResource;
51 import com.google.gwt.user.cellview.client.CellTable;
52 import com.google.gwt.user.cellview.client.Column;
53 import com.google.gwt.user.cellview.client.TextColumn;
54 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
55 import com.google.gwt.user.client.DOM;
56 import com.google.gwt.user.client.DeferredCommand;
57 import com.google.gwt.user.client.Event;
58 import com.google.gwt.user.client.Window;
59 import com.google.gwt.user.client.ui.AbstractImagePrototype;
60 import com.google.gwt.user.client.ui.Composite;
61 import com.google.gwt.user.client.ui.Grid;
62 import com.google.gwt.user.client.ui.HTML;
63 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
64 import com.google.gwt.user.client.ui.HorizontalPanel;
65 import com.google.gwt.user.client.ui.TreeItem;
66 import com.google.gwt.user.client.ui.Widget;
67 import com.google.gwt.view.client.DefaultSelectionEventManager;
68 import com.google.gwt.view.client.MultiSelectionModel;
69 import com.google.gwt.view.client.ProvidesKey;
70 import com.google.gwt.view.client.SelectionChangeEvent;
71 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
72
73 /**
74  * A composite that displays the list of files in a particular folder.
75  */
76 public class FileList extends Composite {
77
78         interface TableResources extends CellTable.Resources {
79             @Source({CellTable.Style.DEFAULT_CSS, "GssCellTable.css"})
80             TableStyle cellTableStyle();
81           }
82         
83         /**
84            * The styles applied to the table.
85            */
86           interface TableStyle extends CellTable.Style {
87           }
88
89         private String showingStats = "";
90
91         private int startIndex = 0;
92
93         /**
94          * A constant that denotes the completion of an IncrementalCommand.
95          */
96         public static final boolean DONE = false;
97
98         /**
99          * The context menu for the selected file.
100          */
101         final DnDSimpleFocusPanel contextMenu;
102         
103         private final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
104
105         /**
106          * Specifies that the images available for this composite will be the ones
107          * available in FileContextMenu.
108          */
109         public interface Images extends ClientBundle,FileContextMenu.Images, Folders.Images {
110
111                 @Source("gr/ebs/gss/resources/blank.gif")
112                 ImageResource blank();
113
114                 @Source("gr/ebs/gss/resources/asc.png")
115                 ImageResource asc();
116
117                 @Source("gr/ebs/gss/resources/desc.png")
118                 ImageResource desc();
119
120                 @Source("gr/ebs/gss/resources/mimetypes/document_shared.png")
121                 ImageResource documentShared();
122
123                 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst.png")
124                 ImageResource wordprocessor();
125
126                 @Source("gr/ebs/gss/resources/mimetypes/log.png")
127                 ImageResource spreadsheet();
128
129                 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr.png")
130                 ImageResource presentation();
131
132                 @Source("gr/ebs/gss/resources/mimetypes/acroread.png")
133                 ImageResource pdf();
134
135                 @Source("gr/ebs/gss/resources/mimetypes/image.png")
136                 ImageResource image();
137
138                 @Source("gr/ebs/gss/resources/mimetypes/video2.png")
139                 ImageResource video();
140
141                 @Source("gr/ebs/gss/resources/mimetypes/knotify.png")
142                 ImageResource audio();
143
144                 @Source("gr/ebs/gss/resources/mimetypes/html.png")
145                 ImageResource html();
146
147                 @Source("gr/ebs/gss/resources/mimetypes/txt.png")
148                 ImageResource txt();
149
150                 @Source("gr/ebs/gss/resources/mimetypes/ark2.png")
151                 ImageResource zip();
152
153                 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst_shared.png")
154                 ImageResource wordprocessorShared();
155
156                 @Source("gr/ebs/gss/resources/mimetypes/log_shared.png")
157                 ImageResource spreadsheetShared();
158
159                 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr_shared.png")
160                 ImageResource presentationShared();
161
162                 @Source("gr/ebs/gss/resources/mimetypes/acroread_shared.png")
163                 ImageResource pdfShared();
164
165                 @Source("gr/ebs/gss/resources/mimetypes/image_shared.png")
166                 ImageResource imageShared();
167
168                 @Source("gr/ebs/gss/resources/mimetypes/video2_shared.png")
169                 ImageResource videoShared();
170
171                 @Source("gr/ebs/gss/resources/mimetypes/knotify_shared.png")
172                 ImageResource audioShared();
173
174                 @Source("gr/ebs/gss/resources/mimetypes/html_shared.png")
175                 ImageResource htmlShared();
176
177                 @Source("gr/ebs/gss/resources/mimetypes/txt_shared.png")
178                 ImageResource txtShared();
179
180                 @Source("gr/ebs/gss/resources/mimetypes/ark2_shared.png")
181                 ImageResource zipShared();
182
183         }
184
185         /**
186          * A label with the number of files in this folder.
187          */
188         private HTML countLabel = new HTML();
189
190         /**
191          * The table widget with the file list.
192          */
193         //private FileTable table = new FileTable(GSS.VISIBLE_FILE_COUNT + 1, 8);
194
195         /**
196          * The navigation bar for paginating the results.
197          */
198         private HorizontalPanel navBar = new HorizontalPanel();
199
200         /**
201          * The number of files in this folder.
202          */
203         int folderFileCount;
204
205         /**
206          * Total folder size
207          */
208         long folderTotalSize;
209
210         /**
211          * A cache of the files in the list.
212          */
213         private List<FileResource> files;
214
215         /**
216          * The widget's image bundle.
217          */
218         private final Images images;
219
220         
221         private FileContextMenu menuShowing;
222         private CellTable<FileResource> celltable;
223         private final MultiSelectionModel<FileResource> selectionModel;
224         private final List<SortableHeader> allHeaders = new ArrayList<SortableHeader>();
225         SortableHeader nameHeader;
226         /**
227          * Construct the file list widget. This entails setting up the widget
228          * layout, fetching the number of files in the current folder from the
229          * server and filling the local file cache of displayed files with data from
230          * the server, as well.
231          *
232          * @param _images
233          */
234         public FileList(Images _images) {
235                 images = _images;
236                 CellTable.Resources resources = GWT.create(TableResources.class);
237                 
238                 contextMenu = new DnDSimpleFocusPanel(new HTML(AbstractImagePrototype.create(images.fileContextMenu()).getHTML()));
239                 GSS.get().getDragController().makeDraggable(contextMenu);
240
241                 // Setup the table.
242                 
243
244                 // Create the 'navigation' bar at the upper-right.
245                 HorizontalPanel innerNavBar = new HorizontalPanel();
246                 innerNavBar.setStyleName("gss-ListNavBar");
247                 innerNavBar.setSpacing(8);
248                 innerNavBar.add(countLabel);
249                 navBar.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
250                 navBar.add(innerNavBar);
251                 navBar.setWidth("100%");
252                 ProvidesKey<FileResource> keyProvider = new ProvidesKey<FileResource>(){
253
254                         @Override
255                         public Object getKey(FileResource item) {
256                                 return item.getUri();
257                         }
258                         
259                 };
260                 final TextColumn<FileResource> nameColumn = new TextColumn<FileResource>() {
261
262                         @Override
263                         public String getValue(FileResource object) {
264                                 // TODO Auto-generated method stub
265                                 return object.getName();
266                         }
267                         
268                         
269                 };
270                 celltable = new CellTable<FileResource>(100,resources,keyProvider){
271                         @Override
272                         protected void onBrowserEvent2(Event event) {
273                                 /*if (DOM.eventGetType((Event) event) == Event.ONMOUSEDOWN && DOM.eventGetButton((Event) event) == NativeEvent.BUTTON_RIGHT){
274                                         fireClickEvent((Element) event.getEventTarget().cast());                                        
275                                 }*/
276                                 super.onBrowserEvent2(event);
277                         }
278                 };
279                 
280                 
281                 Column<FileResource, ImageResource> status = new Column<FileResource, ImageResource>(new ImageResourceCell()) {
282                   @Override
283                   public ImageResource getValue(FileResource entity) {
284                     return getFileIcon(entity);
285                   }
286                };
287                celltable.addColumn(status,"");
288                 
289                 
290                 celltable.addColumn(nameColumn,nameHeader = new SortableHeader("Name"));
291                 allHeaders.add(nameHeader);
292                 nameHeader.setSorted(true);
293                 nameHeader.toggleReverseSort();
294                 nameHeader.setUpdater(new FileValueUpdater(nameHeader, "name"));
295                 celltable.redrawHeaders();
296                 SortableHeader aheader;
297                 celltable.addColumn(new TextColumn<FileResource>() {
298                         @Override
299                         public String getValue(FileResource object) {
300                                 // TODO Auto-generated method stub
301                                 return object.getOwner();
302                         }                       
303                 },aheader = new SortableHeader("Owner"));
304                 allHeaders.add(aheader);
305                 aheader.setUpdater(new FileValueUpdater(aheader, "owner"));
306                 celltable.addColumn(new TextColumn<FileResource>() {
307                         @Override
308                         public String getValue(FileResource object) {
309                                 // TODO Auto-generated method stub
310                                 return object.getPath();
311                         }                       
312                 },aheader = new SortableHeader("Path"));
313                 allHeaders.add(aheader);
314                 aheader.setUpdater(new FileValueUpdater(aheader, "path"));      
315                 celltable.addColumn(new TextColumn<FileResource>() {
316                         @Override
317                         public String getValue(FileResource object) {
318                                 // TODO Auto-generated method stub
319                                 return object.getVersion().toString();
320                         }                       
321                 },aheader = new SortableHeader("Version"));
322                 allHeaders.add(aheader);
323                 aheader.setUpdater(new FileValueUpdater(aheader, "version"));
324                 celltable.addColumn(new TextColumn<FileResource>() {
325                         @Override
326                         public String getValue(FileResource object) {
327                                 // TODO Auto-generated method stub
328                                 return object.getFileSizeAsString();
329                         }                       
330                 },aheader = new SortableHeader("Size"));
331                 allHeaders.add(aheader);
332                 aheader.setUpdater(new FileValueUpdater(aheader, "size"));      
333                 celltable.addColumn(new TextColumn<FileResource>() {
334                         @Override
335                         public String getValue(FileResource object) {
336                                 return formatter.format(object.getModificationDate());
337                         }                       
338                 },aheader = new SortableHeader("Last Modified"));
339                 allHeaders.add(aheader);
340                 aheader.setUpdater(new FileValueUpdater(aheader, "date"));
341                 initWidget(celltable);
342                 setStyleName("gss-List");
343                 selectionModel = new MultiSelectionModel<FileResource>();
344                 
345
346                  Handler selectionHandler = new SelectionChangeEvent.Handler() { 
347              @Override 
348              public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
349                  if(getSelectedFiles().size()==1)
350                          GSS.get().setCurrentSelection(getSelectedFiles().get(0));
351                  else
352                          GSS.get().setCurrentSelection(getSelectedFiles());
353                                 contextMenu.setFiles(getSelectedFiles());
354              }
355          };
356          selectionModel.addSelectionChangeHandler(selectionHandler);
357          
358                 celltable.setSelectionModel(selectionModel,GSSSelectionEventManager.<FileResource>createDefaultManager());
359                 celltable.setPageSize(GSS.VISIBLE_FILE_COUNT);
360                 celltable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
361                 Scheduler.get().scheduleIncremental(new RepeatingCommand() {
362
363                         @Override
364                         public boolean execute() {
365                                 return fetchRootFolder();
366                         }
367                 });
368                 sinkEvents(Event.ONCONTEXTMENU);
369                 sinkEvents(Event.ONMOUSEUP);
370                 sinkEvents(Event.ONMOUSEDOWN);
371                 sinkEvents(Event.ONCLICK);
372                 sinkEvents(Event.ONKEYDOWN);
373                 sinkEvents(Event.ONDBLCLICK);
374                 GSS.preventIESelection();
375         }
376         
377         //public native void fireClickEvent(Element element) /*-{
378           //  var evObj = $doc.createEvent('MouseEvents');
379             //evObj.initEvent('click', true, true);
380             //element.dispatchEvent(evObj);
381         //}-*/;
382
383          public List<FileResource> getSelectedFiles() {
384          return new ArrayList<FileResource>(selectionModel.getSelectedSet());
385          }
386         
387         
388
389         @Override
390         public void onBrowserEvent(Event event) {
391                 
392                 if (files == null || files.size() == 0) {
393                         if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
394                                 menuShowing = new FileContextMenu(images, false, true);
395                                 menuShowing=menuShowing.onEmptyEvent(event);
396                         }
397                         return;
398                 }
399                 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() != 0) {
400                         GWT.log("*****GOING TO SHOW CONTEXT MENU ****", null);
401                         menuShowing =  new FileContextMenu(images, false, false);
402                         menuShowing=menuShowing.onEvent(event);
403                 } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
404                         menuShowing = new FileContextMenu(images, false, true);
405                         menuShowing=menuShowing.onEmptyEvent(event);
406                 } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
407                         if (getSelectedFiles().size() == 1) {
408                                 GSS app = GSS.get();
409                                 FileResource file = getSelectedFiles().get(0);
410                                 String dateString = RestCommand.getDate();
411                                 String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());
412                                 String sig = app.getCurrentUserResource().getUsername() + " " +
413                                                 RestCommand.calculateSig("GET", dateString, resource,
414                                                 RestCommand.base64decode(app.getToken()));
415                                 Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");
416                                 event.preventDefault();
417                                 return;
418                         }
419                 super.onBrowserEvent(event);
420         }
421
422         /**
423          * Retrieve the root folder for the current user.
424          *
425          * @return true if the retrieval was successful
426          */
427         protected boolean fetchRootFolder() {
428                 UserResource user = GSS.get().getCurrentUserResource();
429                 if (user == null)
430                         return !DONE;
431                 // Update cache and clear selection.
432                 updateFileCache(true);
433                 return DONE;
434         }
435
436         
437
438         
439         /**
440          * Make the specified row look like selected or not, according to the
441          * <code>selected</code> flag.
442          *
443          * @param row
444          * @param selected
445          */
446         void styleRow(final int row, final boolean selected) {
447                 
448         }
449
450         /**
451          * Update the display of the file list.
452          */
453         void update(boolean sort) {
454                 int count = folderFileCount;
455                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
456                 if (max > count)
457                         max = count;
458                 folderTotalSize = 0;
459                 
460                 celltable.setRowCount(files.size());
461                 celltable.setRowData(0,files);
462                 celltable.redrawHeaders();
463                 if (folderFileCount == 0) {
464                         showingStats = "no files";
465                 } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
466                         if (folderFileCount == 1)
467                                 showingStats = "1 file";
468                         else
469                                 showingStats = folderFileCount + " files";
470                         showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
471                 } else {
472                         showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
473                 }
474                 updateCurrentlyShowingStats();
475
476         }
477
478         /**
479          * Return the proper icon based on the MIME type of the file.
480          *
481          * @param file
482          * @return the icon
483          */
484         private ImageResource getFileIcon(FileResource file) {
485                 String mimetype = file.getContentType();
486                 boolean shared = false;
487                 Folders folders = GSS.get().getFolders();
488                 if(folders.getCurrent() != null && folders.isOthersSharedItem(folders.getCurrent())){
489                         DnDTreeItem otherUser = (DnDTreeItem) folders.getUserOfSharedItem(folders.getCurrent());
490                         if(otherUser==null)
491                                 shared = false;
492                         else{
493                                 String uname = otherUser.getOtherUserResource().getUsername();
494                                 if(uname==null)
495                                         uname = ((DnDTreeItem)folders.getSharesItem()).getOthersResource().getUsernameOfUri(otherUser.getOtherUserResource().getUri());
496                                 if(uname != null)
497                                         shared = file.isShared();
498                         }
499                 }
500                 else
501                         shared = file.isShared();
502                 if (mimetype == null)
503                         return shared ? images.documentShared() : images.document();
504                 mimetype = mimetype.toLowerCase();
505                 if (mimetype.startsWith("application/pdf"))
506                         return shared ? images.pdfShared() : images.pdf();
507                 else if (mimetype.endsWith("excel"))
508                         return shared ? images.spreadsheetShared() : images.spreadsheet();
509                 else if (mimetype.endsWith("msword"))
510                         return shared ? images.wordprocessorShared() : images.wordprocessor();
511                 else if (mimetype.endsWith("powerpoint"))
512                         return shared ? images.presentationShared() : images.presentation();
513                 else if (mimetype.startsWith("application/zip") ||
514                                         mimetype.startsWith("application/gzip") ||
515                                         mimetype.startsWith("application/x-gzip") ||
516                                         mimetype.startsWith("application/x-tar") ||
517                                         mimetype.startsWith("application/x-gtar"))
518                         return shared ? images.zipShared() : images.zip();
519                 else if (mimetype.startsWith("text/html"))
520                         return shared ? images.htmlShared() : images.html();
521                 else if (mimetype.startsWith("text/plain"))
522                         return shared ? images.txtShared() : images.txt();
523                 else if (mimetype.startsWith("image/"))
524                         return shared ? images.imageShared() : images.image();
525                 else if (mimetype.startsWith("video/"))
526                         return shared ? images.videoShared() : images.video();
527                 else if (mimetype.startsWith("audio/"))
528                         return shared ? images.audioShared() : images.audio();
529                 return shared ? images.documentShared() : images.document();
530         }
531
532         /**
533          * Update status panel with currently showing file stats.
534          */
535         public void updateCurrentlyShowingStats() {
536                 GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
537         }
538
539         /**
540          * Adjust the height of the table by adding and removing rows as necessary.
541          *
542          * @param newHeight the new height to reach
543          */
544         //void resizeTableHeight(final int newHeight) {
545                 /*GWT.log("Panel: " + newHeight + ", parent: " + table.getParent().getOffsetHeight(), null);
546                 // Fill the rest with empty slots.
547                 if (newHeight > table.getOffsetHeight())
548                         while (newHeight > table.getOffsetHeight()) {
549                                 table.resizeRows(table.getRowCount() + 1);
550                                 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);
551                         }
552                 else
553                         while (newHeight < table.getOffsetHeight()) {
554                                 table.resizeRows(table.getRowCount() - 1);
555                                 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);
556                         }*/
557         //}
558
559         public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection) {
560                 updateFileCache(updateSelectedFolder, clearSelection, null);
561         }
562
563         public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection, final String newFilename) {
564                 if (!updateSelectedFolder && !GSS.get().getFolders().getCurrent().equals(GSS.get().getFolders().getTrashItem()))
565                         updateFileCache(clearSelection);
566                 else if (GSS.get().getFolders().getCurrent() != null) {
567                         final DnDTreeItem folderItem = (DnDTreeItem) GSS.get().getFolders().getCurrent();
568                         if (folderItem.getFolderResource() != null) {
569                                 if(GSS.get().getFolders().isFileItem(folderItem) || GSS.get().getFolders().isMySharedItem(folderItem)  || GSS.get().getFolders().isOthersSharedItem(folderItem) ){
570                                 update(true);
571                                 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, folderItem.getFolderResource().getUri(),folderItem.getFolderResource()) {
572
573                                         @Override
574                                         public void onComplete() {
575                                                 folderItem.setUserObject(getResult());
576                                                                 if(GSS.get().getFolders().isFileItem(folderItem)){
577                                                         String[] filePaths = new String[folderItem.getFolderResource().getFilePaths().size()];
578                                                         int c=0;
579                                                         for(String fpath : folderItem.getFolderResource().getFilePaths()){
580                                                                 filePaths[c] = fpath + "?" + Math.random();
581                                                                 c++;
582                                                         }
583                                                         MultipleHeadCommand<FileResource> getFiles = new MultipleHeadCommand<FileResource>(FileResource.class, filePaths, folderItem.getFolderResource().getFileCache()){
584
585                                                                 @Override
586                                                                 public void onComplete(){
587                                                                         List<FileResource> result = getResult();
588                                                                         //remove random from path
589                                                                         for(FileResource r : result){
590                                                                                 String p = r.getUri();
591                                                                                 int indexOfQuestionMark = p.lastIndexOf('?');
592                                                                                 if(indexOfQuestionMark>0)
593                                                                                         r.setUri(p.substring(0, indexOfQuestionMark));
594                                                                                 GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
595                                                                         }
596                                                                         folderItem.getFolderResource().setFiles(result);
597                                                                         folderItem.getFolderResource().setFilesExpanded(true);
598                                                                         updateFileCache(clearSelection, newFilename);
599                                                                 }
600
601                                                                 @Override
602                                                                 public void onError(String p, Throwable throwable) {
603                                                                         if(throwable instanceof RestException)
604                                                                                 GSS.get().displayError("Unable to retrieve file details:"+((RestException)throwable).getHttpStatusText());
605                                                                 }
606
607                                                                 @Override
608                                                                 public void onError(Throwable t) {
609                                                                         GWT.log("", t);
610                                                                         GSS.get().displayError("Unable to fetch files for folder " + folderItem.getFolderResource().getName());
611                                                                 }
612
613                                                         };
614                                                         DeferredCommand.addCommand(getFiles);
615                                                 }
616                                                 else
617                                                         updateFileCache(clearSelection, newFilename);
618                                         }
619
620                                         @Override
621                                         public void onError(Throwable t) {
622                                                 GWT.log("", t);
623                                                 GSS.get().displayError("Unable to fetch folder " + folderItem.getFolderResource().getName());
624                                         }
625                                 };
626                                 DeferredCommand.addCommand(gf);
627                                 }
628                         }
629                         else if (folderItem.getTrashResource() != null) {
630                                 GetCommand<TrashResource> gt = new GetCommand<TrashResource>(TrashResource.class, folderItem.getTrashResource().getUri(), null) {
631
632                                         @Override
633                                         public void onComplete() {
634                                                 folderItem.setUserObject(getResult());
635                                                 updateFileCache(clearSelection);
636                                         }
637
638                                         @Override
639                                         public void onError(Throwable t) {
640                                                 if (t instanceof RestException && (((RestException) t).getHttpStatusCode() == 204 || ((RestException) t).getHttpStatusCode() == 1223)) {
641                                                         folderItem.setUserObject(new TrashResource(folderItem.getTrashResource().getUri()));
642                                                         updateFileCache(clearSelection);
643                                                 } else {
644                                                         GWT.log("", t);
645                                                         GSS.get().displayError("Unable to fetch trash resource");
646                                                 }
647                                         }
648                                 };
649                                 DeferredCommand.addCommand(gt);
650                         } else if (folderItem.getSharedResource() != null) {
651                                 GetCommand<SharedResource> gt = new GetCommand<SharedResource>(SharedResource.class, folderItem.getSharedResource().getUri(), null) {
652
653                                         @Override
654                                         public void onComplete() {
655                                                 folderItem.setUserObject(getResult());
656                                                 for(FileResource r : folderItem.getSharedResource().getFiles()){
657                                                                         String p = r.getUri();
658                                                                         int indexOfQuestionMark = p.lastIndexOf('?');
659                                                                         if(indexOfQuestionMark>0)
660                                                                                 r.setUri(p.substring(0, indexOfQuestionMark));
661                                                                         GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
662                                                                 }
663                                                                 folderItem.getSharedResource().setFilesExpanded(true);
664                                                                 updateFileCache(clearSelection, newFilename);
665                                                 
666                                         }
667
668                                         @Override
669                                         public void onError(Throwable t) {
670                                                 GWT.log("", t);
671                                                 GSS.get().displayError("Unable to fetch My Shares resource");
672                                         }
673                                 };
674                                 DeferredCommand.addCommand(gt);
675                         } else if (folderItem.getOtherUserResource() != null) {
676                                 GetCommand<OtherUserResource> gt = new GetCommand<OtherUserResource>(OtherUserResource.class, folderItem.getOtherUserResource().getUri(), null) {
677
678                                         @Override
679                                         public void onComplete() {
680                                                 folderItem.setUserObject(getResult());
681                                                 //updateFileCache(clearSelection, newFilename);
682                                                 for(FileResource r : folderItem.getOtherUserResource().getFiles()){
683                                                                         String p = r.getUri();
684                                                                         int indexOfQuestionMark = p.lastIndexOf('?');
685                                                                         if(indexOfQuestionMark>0)
686                                                                                 r.setUri(p.substring(0, indexOfQuestionMark));
687                                                                         GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
688                                                                 }
689                                                                 folderItem.getOtherUserResource().setFilesExpanded(true);
690                                                                 updateFileCache(clearSelection, newFilename);
691                                                 
692                                         }
693
694                                         @Override
695                                         public void onError(Throwable t) {
696                                                 GWT.log("", t);
697                                                 GSS.get().displayError("Unable to fetch My Shares resource");
698                                         }
699                                 };
700                                 DeferredCommand.addCommand(gt);
701                         }
702                 } else
703                         updateFileCache(clearSelection);
704         }
705
706
707         private void updateFileCache(boolean clearSelection) {
708                 updateFileCache(clearSelection, null);
709         }
710
711         /**
712          * Update the file cache with data from the server.
713          *
714          * @param newFilename the new name of the previously selected file,
715          *                      if a rename operation has taken place
716          */
717         private void updateFileCache(boolean clearSelection, String newFilename) {
718                 if (clearSelection)
719                         clearSelectedRows();
720                 startIndex = 0;
721                 final TreeItem folderItem = GSS.get().getFolders().getCurrent();
722                 // Validation.
723                 if (folderItem == null || GSS.get().getFolders().isOthersShared(folderItem)) {
724                         setFiles(new ArrayList<FileResource>());
725                         update(true);
726                         return;
727                 }
728                 if (folderItem instanceof DnDTreeItem) {
729                         DnDTreeItem dnd = (DnDTreeItem) folderItem;
730                         if (dnd.getFolderResource() != null) {
731                                 if (GSS.get().getFolders().isTrashItem(dnd))
732                                         setFiles(new ArrayList<FileResource>());
733                                 else
734                                         setFiles(dnd.getFolderResource().getFiles());
735
736                         } else if (dnd.getTrashResource() != null)
737                                 setFiles(dnd.getTrashResource().getFiles());
738                         else if (dnd.getSharedResource() != null)
739                                 setFiles(dnd.getSharedResource().getFiles());
740                         else if (dnd.getOtherUserResource() != null)
741                                 setFiles(dnd.getOtherUserResource().getFiles());
742                         else
743                                 setFiles(dnd.getFolderResource().getFiles());
744                         update(true);
745
746                 }
747         }
748
749         /**
750          * Fill the file cache with data.
751          */
752         public void setFiles(final List<FileResource> _files) {
753                 if (_files.size() > 0 && !GSS.get().getFolders().isTrash(GSS.get().getFolders().getCurrent())) {
754                         files = new ArrayList<FileResource>();
755                         for (FileResource fres : _files)
756                                 if (!fres.isDeleted())
757                                         files.add(fres);
758                 } else
759                         files = _files;
760                 Collections.sort(files, new Comparator<FileResource>() {
761
762                         @Override
763                         public int compare(FileResource arg0, FileResource arg1) {
764                                 return arg0.getName().compareTo(arg1.getName());
765                         }
766
767                 });
768                 folderFileCount = files.size();
769         }
770
771         
772
773         
774         /**
775          * Does the list contains the requested filename
776          *
777          * @param fileName
778          * @return true/false
779          */
780         public boolean contains(String fileName) {
781                 for (int i = 0; i < files.size(); i++)
782                         if (files.get(i).getName().equals(fileName))
783                                 return true;
784                 return false;
785         }
786
787         public void clearSelectedRows() {
788                 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
789                 while(it.hasNext()){
790                         selectionModel.setSelected(it.next(),false);
791                 }
792                 
793                 /*for (int r : selectedRows) {
794                         int row = r - startIndex;
795                         styleRow(row, false);
796                         makeRowNotDraggable(row+1);
797                 }
798                 selectedRows.clear();
799                 Object sel = GSS.get().getCurrentSelection();
800                 if (sel instanceof FileResource || sel instanceof List)
801                         GSS.get().setCurrentSelection(null);
802                 if(menuShowing != null && menuShowing.isShowing()){
803                         menuShowing.hide();
804                         menuShowing=null;
805                 }*/
806         }
807
808         /**
809          *
810          */
811         public void selectAllRows() {
812                 /*clearSelectedRows();
813                 int count = folderFileCount;
814                 if (count == 0)
815                         return;
816                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
817                 if (max > count)
818                         max = count;
819                 int i = 1;
820                 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
821                         // Don't read past the end.
822                         // if (i > folderFileCount)
823                         // break;
824                         if (startIndex + i > folderFileCount)
825                                 break;
826                         selectedRows.add(startIndex + i - 1);
827                         styleRow(i - 1, true);
828                         makeRowDraggable(i);
829                 }
830                 GSS.get().setCurrentSelection(getSelectedFiles());
831                 contextMenu.setFiles(getSelectedFiles());*/
832
833
834         }
835
836         private void makeRowDraggable(int row){
837         /*      int contextRow = getWidgetRow(contextMenu, table);
838                 if (contextRow != -1)
839                         table.setWidget(contextRow, 0, getFileIcon(files.get(contextRow - 1)).createImage());
840                 contextMenu.setWidget(new HTML(getFileIcon(files.get(row - 1)).getHTML()));
841                 table.setWidget(row, 0, contextMenu);
842                 //for(int i=1;i<table.getCellCount(row);i++)
843                         //GSS.get().getDragController().makeDraggable(table.getWidget(row, i));
844                 table.setWidget(row, 1, new DnDSimpleFocusPanel(table.getWidget(row, 1)));
845                 ((DnDSimpleFocusPanel)table.getWidget(row, 1)).setFiles(getSelectedFiles());
846                 GSS.get().getDragController().makeDraggable(table.getWidget(row, 1));*/
847         }
848         private void makeRowNotDraggable(int row){
849                 /*if(table.getWidget(row, 1) instanceof DnDSimpleFocusPanel){
850                         ((DnDSimpleFocusPanel)table.getWidget(row, 1)).setFiles(null);
851                         GSS.get().getDragController().makeNotDraggable(table.getWidget(row, 1));
852                         table.setWidget(row, 1, new DnDSimpleFocusPanel(((DnDSimpleFocusPanel)table.getWidget(row, 1)).getWidget()));
853
854                 }
855                 */
856         }
857
858         private int getWidgetRow(Widget widget, Grid grid) {
859                 /*for (int row = 0; row < grid.getRowCount(); row++)
860                         for (int col = 0; col < grid.getCellCount(row); col++) {
861                                 Widget w = table.getWidget(row, col);
862                                 if (w == widget)
863                                         return row;
864                         }*/
865                 return -1;
866         }
867         
868         
869         private void sortFiles(final String sortingProperty, final boolean sortingType){
870                 Collections.sort(files, new Comparator<FileResource>() {
871
872             @Override
873             public int compare(FileResource arg0, FileResource arg1) {
874                     AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
875                     AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
876                     if (sortingType){
877                             if (sortingProperty.equals("version")) {
878                                     return arg0.getVersion().compareTo(arg1.getVersion());
879                             } else if (sortingProperty.equals("owner")) {
880                                     return arg0.getOwner().compareTo(arg1.getOwner());
881                             } else if (sortingProperty.equals("date")) {
882                                     return arg0.getModificationDate().compareTo(arg1.getModificationDate());
883                             } else if (sortingProperty.equals("size")) {
884                                     return arg0.getContentLength().compareTo(arg1.getContentLength());
885                             } else if (sortingProperty.equals("name")) {
886                                     return arg0.getName().compareTo(arg1.getName());
887                             } else if (sortingProperty.equals("path")) {
888                                     return arg0.getUri().compareTo(arg1.getUri());
889                             } else {
890                                     return arg0.getName().compareTo(arg1.getName());
891                             }
892                     }
893                     else if (sortingProperty.equals("version")) {
894                             
895                             return arg1.getVersion().compareTo(arg0.getVersion());
896                     } else if (sortingProperty.equals("owner")) {
897                             
898                             return arg1.getOwner().compareTo(arg0.getOwner());
899                     } else if (sortingProperty.equals("date")) {
900                             
901                             return arg1.getModificationDate().compareTo(arg0.getModificationDate());
902                     } else if (sortingProperty.equals("size")) {
903                             
904                             return arg1.getContentLength().compareTo(arg0.getContentLength());
905                     } else if (sortingProperty.equals("name")) {
906                             
907                             return arg1.getName().compareTo(arg0.getName());
908                     } else if (sortingProperty.equals("path")) {
909                             
910                             return arg1.getUri().compareTo(arg0.getUri());
911                     } else {
912                             
913                             return arg1.getName().compareTo(arg0.getName());
914                     }
915             }
916
917                 });
918         }
919         
920         final class FileValueUpdater implements ValueUpdater<String>{
921                 private String property;
922                 private SortableHeader header;
923                 /**
924                  * 
925                  */
926                 public FileValueUpdater(SortableHeader header,String property) {
927                         this.property=property;
928                         this.header=header;
929                 }
930                 @Override
931                 public void update(String value) {
932                         header.setSorted(true);
933                         header.toggleReverseSort();
934
935                 for (SortableHeader otherHeader : allHeaders) {
936                   if (otherHeader != header) {
937                     otherHeader.setSorted(false);
938                     otherHeader.setReverseSort(true);
939                   }
940                 }
941                 celltable.redrawHeaders();
942                 sortFiles(property, header.getReverseSort());
943                 FileList.this.update(true);                     
944                 }
945                 
946         }
947 }