Remove unused code, fix a few warnings and restore some inadvertent changes. Also...
[pithos] / src / gr / ebs / gss / client / FileList.java
1 /*\r
2  * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
3  *\r
4  * This file is part of GSS.\r
5  *\r
6  * GSS is free software: you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation, either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * GSS is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.\r
18  */\r
19 package gr.ebs.gss.client;\r
20 \r
21 import gr.ebs.gss.client.dnd.DnDFocusPanel;\r
22 import gr.ebs.gss.client.dnd.DnDTreeItem;\r
23 import gr.ebs.gss.client.rest.GetCommand;\r
24 import gr.ebs.gss.client.rest.MultipleHeadCommand;\r
25 import gr.ebs.gss.client.rest.RestCommand;\r
26 import gr.ebs.gss.client.rest.RestException;\r
27 import gr.ebs.gss.client.rest.resource.FileResource;\r
28 import gr.ebs.gss.client.rest.resource.FolderResource;\r
29 import gr.ebs.gss.client.rest.resource.OtherUserResource;\r
30 import gr.ebs.gss.client.rest.resource.SharedResource;\r
31 import gr.ebs.gss.client.rest.resource.TrashResource;\r
32 import gr.ebs.gss.client.rest.resource.UserResource;\r
33 \r
34 import java.util.ArrayList;\r
35 import java.util.Collections;\r
36 import java.util.Comparator;\r
37 import java.util.List;\r
38 \r
39 import com.google.gwt.core.client.GWT;\r
40 import com.google.gwt.event.dom.client.ClickEvent;\r
41 import com.google.gwt.event.dom.client.ClickHandler;\r
42 import com.google.gwt.http.client.URL;\r
43 import com.google.gwt.i18n.client.DateTimeFormat;\r
44 import com.google.gwt.resources.client.ClientBundle;\r
45 import com.google.gwt.resources.client.ImageResource;\r
46 import com.google.gwt.user.client.DOM;\r
47 import com.google.gwt.user.client.DeferredCommand;\r
48 import com.google.gwt.user.client.Event;\r
49 import com.google.gwt.user.client.IncrementalCommand;\r
50 import com.google.gwt.user.client.Window;\r
51 import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
52 import com.google.gwt.user.client.ui.Composite;\r
53 import com.google.gwt.user.client.ui.Grid;\r
54 import com.google.gwt.user.client.ui.HTML;\r
55 import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
56 import com.google.gwt.user.client.ui.HorizontalPanel;\r
57 import com.google.gwt.user.client.ui.TreeItem;\r
58 import com.google.gwt.user.client.ui.Widget;\r
59 import com.google.gwt.user.client.ui.HTMLTable.Cell;\r
60 \r
61 /**\r
62  * A composite that displays the list of files in a particular folder.\r
63  */\r
64 public class FileList extends Composite implements ClickHandler {\r
65 \r
66         private HTML prevButton = new HTML("<a href='javascript:;'>&lt; Previous</a>", true);\r
67 \r
68         private HTML nextButton = new HTML("<a href='javascript:;'>Next &gt;</a>", true);\r
69 \r
70         private String showingStats = "";\r
71 \r
72         private int startIndex = 0;\r
73 \r
74         /**\r
75          * A constant that denotes the completion of an IncrementalCommand.\r
76          */\r
77         public static final boolean DONE = false;\r
78 \r
79         private boolean clickControl = false;\r
80 \r
81         private boolean clickShift = false;\r
82 \r
83         private int firstShift = -1;\r
84 \r
85         private ArrayList<Integer> selectedRows = new ArrayList<Integer>();\r
86 \r
87         /**\r
88          * The context menu for the selected file.\r
89          */\r
90         final DnDFocusPanel contextMenu;\r
91 \r
92         /**\r
93          * Specifies that the images available for this composite will be the ones\r
94          * available in FileContextMenu.\r
95          */\r
96         public interface Images extends ClientBundle,FileContextMenu.Images, Folders.Images {\r
97 \r
98                 @Source("gr/ebs/gss/resources/blank.gif")\r
99                 ImageResource blank();\r
100 \r
101                 @Source("gr/ebs/gss/resources/asc.png")\r
102                 ImageResource asc();\r
103 \r
104                 @Source("gr/ebs/gss/resources/desc.png")\r
105                 ImageResource desc();\r
106 \r
107                 @Source("gr/ebs/gss/resources/mimetypes/document_shared.png")\r
108                 ImageResource documentShared();\r
109 \r
110                 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst.png")\r
111                 ImageResource wordprocessor();\r
112 \r
113                 @Source("gr/ebs/gss/resources/mimetypes/log.png")\r
114                 ImageResource spreadsheet();\r
115 \r
116                 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr.png")\r
117                 ImageResource presentation();\r
118 \r
119                 @Source("gr/ebs/gss/resources/mimetypes/acroread.png")\r
120                 ImageResource pdf();\r
121 \r
122                 @Source("gr/ebs/gss/resources/mimetypes/image.png")\r
123                 ImageResource image();\r
124 \r
125                 @Source("gr/ebs/gss/resources/mimetypes/video2.png")\r
126                 ImageResource video();\r
127 \r
128                 @Source("gr/ebs/gss/resources/mimetypes/knotify.png")\r
129                 ImageResource audio();\r
130 \r
131                 @Source("gr/ebs/gss/resources/mimetypes/html.png")\r
132                 ImageResource html();\r
133 \r
134                 @Source("gr/ebs/gss/resources/mimetypes/txt.png")\r
135                 ImageResource txt();\r
136 \r
137                 @Source("gr/ebs/gss/resources/mimetypes/ark2.png")\r
138                 ImageResource zip();\r
139 \r
140                 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst_shared.png")\r
141                 ImageResource wordprocessorShared();\r
142 \r
143                 @Source("gr/ebs/gss/resources/mimetypes/log_shared.png")\r
144                 ImageResource spreadsheetShared();\r
145 \r
146                 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr_shared.png")\r
147                 ImageResource presentationShared();\r
148 \r
149                 @Source("gr/ebs/gss/resources/mimetypes/acroread_shared.png")\r
150                 ImageResource pdfShared();\r
151 \r
152                 @Source("gr/ebs/gss/resources/mimetypes/image_shared.png")\r
153                 ImageResource imageShared();\r
154 \r
155                 @Source("gr/ebs/gss/resources/mimetypes/video2_shared.png")\r
156                 ImageResource videoShared();\r
157 \r
158                 @Source("gr/ebs/gss/resources/mimetypes/knotify_shared.png")\r
159                 ImageResource audioShared();\r
160 \r
161                 @Source("gr/ebs/gss/resources/mimetypes/html_shared.png")\r
162                 ImageResource htmlShared();\r
163 \r
164                 @Source("gr/ebs/gss/resources/mimetypes/txt_shared.png")\r
165                 ImageResource txtShared();\r
166 \r
167                 @Source("gr/ebs/gss/resources/mimetypes/ark2_shared.png")\r
168                 ImageResource zipShared();\r
169 \r
170         }\r
171 \r
172         /**\r
173          * A label with the number of files in this folder.\r
174          */\r
175         private HTML countLabel = new HTML();\r
176 \r
177         /**\r
178          * The table widget with the file list.\r
179          */\r
180         private Grid table = new Grid(GSS.VISIBLE_FILE_COUNT + 1, 8);\r
181 \r
182         /**\r
183          * The navigation bar for paginating the results.\r
184          */\r
185         private HorizontalPanel navBar = new HorizontalPanel();\r
186 \r
187         /**\r
188          * The number of files in this folder.\r
189          */\r
190         int folderFileCount;\r
191 \r
192         /**\r
193          * Total folder size\r
194          */\r
195         long folderTotalSize;\r
196 \r
197         /**\r
198          * A cache of the files in the list.\r
199          */\r
200         private List<FileResource> files;\r
201 \r
202         /**\r
203          * The widget's image bundle.\r
204          */\r
205         private final Images images;\r
206 \r
207         private String sortingProperty = "name";\r
208 \r
209         private boolean sortingType = true;\r
210 \r
211         private HTML nameLabel;\r
212 \r
213         private HTML versionLabel;\r
214 \r
215         private HTML sizeLabel;\r
216 \r
217         private HTML dateLabel;\r
218 \r
219         private HTML ownerLabel;\r
220 \r
221         private HTML pathLabel;\r
222 \r
223         /**\r
224          * Construct the file list widget. This entails setting up the widget\r
225          * layout, fetching the number of files in the current folder from the\r
226          * server and filling the local file cache of displayed files with data from\r
227          * the server, as well.\r
228          *\r
229          * @param _images\r
230          */\r
231         public FileList(Images _images) {\r
232                 images = _images;\r
233 \r
234                 prevButton.addClickHandler(this);\r
235                 nextButton.addClickHandler(this);\r
236 \r
237                 contextMenu = new DnDFocusPanel(new HTML(AbstractImagePrototype.create(images.fileContextMenu()).getHTML()));\r
238                 contextMenu.addClickHandler(new FileContextMenu(images, false, false));\r
239                 GSS.get().getDragController().makeDraggable(contextMenu);\r
240 \r
241                 // Setup the table.\r
242                 table.setCellSpacing(0);\r
243                 table.setCellPadding(2);\r
244                 table.setWidth("100%");\r
245                 table.addClickHandler(new ClickHandler() {\r
246 \r
247                         @Override\r
248                         public void onClick(ClickEvent event) {\r
249                                 Cell cell = table.getCellForEvent(event);\r
250                                 onRowClicked(cell.getRowIndex());\r
251                         }\r
252                 });\r
253                 // Create the 'navigation' bar at the upper-right.\r
254                 HorizontalPanel innerNavBar = new HorizontalPanel();\r
255                 innerNavBar.setStyleName("gss-ListNavBar");\r
256                 innerNavBar.setSpacing(8);\r
257                 innerNavBar.add(prevButton);\r
258                 innerNavBar.add(countLabel);\r
259                 innerNavBar.add(nextButton);\r
260                 navBar.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);\r
261                 navBar.add(innerNavBar);\r
262                 navBar.setWidth("100%");\r
263 \r
264                 initWidget(table);\r
265                 setStyleName("gss-List");\r
266 \r
267                 initTable();\r
268                 DeferredCommand.addCommand(new IncrementalCommand() {\r
269 \r
270                         public boolean execute() {\r
271                                 return fetchRootFolder();\r
272                         }\r
273                 });\r
274                 sinkEvents(Event.ONCONTEXTMENU);\r
275                 sinkEvents(Event.ONMOUSEUP);\r
276                 sinkEvents(Event.ONCLICK);\r
277                 sinkEvents(Event.ONKEYDOWN);\r
278                 sinkEvents(Event.ONDBLCLICK);\r
279                 GSS.preventIESelection();\r
280         }\r
281 \r
282         @Override\r
283         public void onClick(ClickEvent event) {\r
284                  if(event.getSource() == nextButton){\r
285                         // Move forward a page.\r
286                         clearSelectedRows();\r
287                         startIndex += GSS.VISIBLE_FILE_COUNT;\r
288                         if (startIndex >= folderFileCount)\r
289                                 startIndex -= GSS.VISIBLE_FILE_COUNT;\r
290                         else\r
291                                 update(false);\r
292                 } else if (event.getSource() == prevButton) {\r
293                         clearSelectedRows();\r
294                         // Move back a page.\r
295                         startIndex -= GSS.VISIBLE_FILE_COUNT;\r
296                         if (startIndex < 0)\r
297                                 startIndex = 0;\r
298                         else\r
299                                 update(false);\r
300                 }\r
301         }\r
302 \r
303 \r
304         @Override\r
305         public void onBrowserEvent(Event event) {\r
306                 if (files == null || files.size() == 0) {\r
307                         if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() == 0) {\r
308                                 FileContextMenu fm = new FileContextMenu(images, false, true);\r
309                                 fm.onEmptyEvent(event);\r
310                         }\r
311                         return;\r
312                 }\r
313                 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() != 0) {\r
314                         FileContextMenu fm = new FileContextMenu(images, false, false);\r
315                         fm.onEvent(event);\r
316                 } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() == 0) {\r
317                         FileContextMenu fm = new FileContextMenu(images, false, true);\r
318                         fm.onEmptyEvent(event);\r
319                 } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)\r
320                         if (getSelectedFiles().size() == 1) {\r
321                                 GSS app = GSS.get();\r
322                                 FileResource file = getSelectedFiles().get(0);\r
323                                 String dateString = RestCommand.getDate();\r
324                                 String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());\r
325                                 String sig = app.getCurrentUserResource().getUsername() + " " +\r
326                                                 RestCommand.calculateSig("GET", dateString, resource,\r
327                                                 RestCommand.base64decode(app.getToken()));\r
328                                 Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");\r
329                                 event.preventDefault();\r
330                                 return;\r
331                         }\r
332                 if (DOM.eventGetType(event) == Event.ONCLICK) {\r
333                         if (DOM.eventGetCtrlKey(event))\r
334                                 clickControl = true;\r
335                         else\r
336                                 clickControl = false;\r
337                         if (DOM.eventGetShiftKey(event)) {\r
338                                 clickShift = true;\r
339                                 if (selectedRows.size() == 1)\r
340                                         firstShift = selectedRows.get(0) - startIndex;\r
341                                 event.preventDefault();\r
342                         } else {\r
343                                 clickShift = false;\r
344                                 firstShift = -1;\r
345                                 event.preventDefault();\r
346                         }\r
347                 }\r
348                 super.onBrowserEvent(event);\r
349         }\r
350 \r
351         /**\r
352          * Retrieve the root folder for the current user.\r
353          *\r
354          * @return true if the retrieval was successful\r
355          */\r
356         protected boolean fetchRootFolder() {\r
357                 UserResource user = GSS.get().getCurrentUserResource();\r
358                 if (user == null)\r
359                         return !DONE;\r
360                 // Update cache and clear selection.\r
361                 updateFileCache(true);\r
362                 return DONE;\r
363         }\r
364 \r
365         private void onRowClicked(int row) {\r
366                 // Select the row that was clicked (-1 to account for header row).\r
367                 if (row > folderFileCount)\r
368                         return;\r
369                 if (clickShift) {\r
370                         GWT.log("Row is: " + row + " fs: " + firstShift, null);\r
371                         if (firstShift == -1)\r
372                                 firstShift = row;\r
373                         else if (row > firstShift) {\r
374                                 clearSelectedRows();\r
375                                 for (int i = firstShift; i < row; i++) {\r
376                                         selectedRows.add(startIndex + i);\r
377                                         styleRow(i, true);\r
378                                 }\r
379                                 GSS.get().setCurrentSelection(getSelectedFiles());\r
380                                 contextMenu.setFiles(getSelectedFiles());\r
381                                 makeRowDraggable(row);\r
382                         } else if (row != -1 && row == firstShift) {\r
383                                 selectedRows.add(row - 1);\r
384                                 styleRow(row, true);\r
385                                 styleRow(row - 1, true);\r
386                                 GSS.get().setCurrentSelection(getSelectedFiles());\r
387                                 contextMenu.setFiles(getSelectedFiles());\r
388                                 makeRowDraggable(row);\r
389                         } else if (row < firstShift) {\r
390                                 GWT.log("Row is:" + row + " fs:" + firstShift, null);\r
391                                 clearSelectedRows();\r
392 \r
393                                 for (int i = firstShift; i >= row - 1; i--) {\r
394                                         selectedRows.add(startIndex + i);\r
395                                         styleRow(i, true);\r
396                                 }\r
397                                 GSS.get().setCurrentSelection(getSelectedFiles());\r
398                                 makeRowDraggable(row);\r
399                                 contextMenu.setFiles(getSelectedFiles());\r
400                         }\r
401                 } else if (row > 0)\r
402                         selectRow(row - 1);\r
403         }\r
404 \r
405         /**\r
406          * Initializes the table so that it contains enough rows for a full page of\r
407          * files.\r
408          */\r
409         private void initTable() {\r
410                 nameLabel = new HTML("Name");\r
411                 nameLabel.addClickHandler(new ClickHandler() {\r
412 \r
413                         @Override\r
414                         public void onClick(ClickEvent event) {\r
415                                 sortFiles("name");\r
416 \r
417                         }\r
418 \r
419                 });\r
420                 versionLabel = new HTML("Version");\r
421                 versionLabel.addClickHandler(new ClickHandler() {\r
422 \r
423                         @Override\r
424                         public void onClick(ClickEvent event) {\r
425                                 sortFiles("version");\r
426                         }\r
427 \r
428                 });\r
429                 sizeLabel = new HTML("Size");\r
430                 sizeLabel.addClickHandler(new ClickHandler() {\r
431 \r
432                         @Override\r
433                         public void onClick(ClickEvent event) {\r
434                                 sortFiles("size");\r
435                         }\r
436 \r
437                 });\r
438                 dateLabel = new HTML("Last modified");\r
439                 dateLabel.addClickHandler(new ClickHandler() {\r
440 \r
441                         @Override\r
442                         public void onClick(ClickEvent event) {\r
443                                 sortFiles("date");\r
444                         }\r
445 \r
446                 });\r
447                 ownerLabel = new HTML("Owner");\r
448                 ownerLabel.addClickHandler(new ClickHandler() {\r
449 \r
450                         @Override\r
451                         public void onClick(ClickEvent event) {\r
452                                 sortFiles("owner");\r
453                         }\r
454 \r
455                 });\r
456                 pathLabel = new HTML("Path");\r
457                 pathLabel.addClickHandler(new ClickHandler() {\r
458 \r
459                         @Override\r
460                         public void onClick(ClickEvent event) {\r
461                                 sortFiles("path");\r
462                         }\r
463 \r
464                 });\r
465                 // Create the header row.\r
466                 table.setText(0, 0, "");\r
467                 table.setWidget(0, 1, nameLabel);\r
468                 table.setWidget(0, 2, ownerLabel);\r
469                 table.setWidget(0, 3, pathLabel);\r
470                 table.setWidget(0, 4, versionLabel);\r
471                 table.setWidget(0, 5, sizeLabel);\r
472                 table.setWidget(0, 6, dateLabel);\r
473                 table.setWidget(0, 7, navBar);\r
474                 table.getRowFormatter().setStyleName(0, "gss-ListHeader");\r
475 \r
476                 // Initialize the rest of the rows.\r
477                 for (int i = 1; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {\r
478                         table.setText(i, 0, "");\r
479                         table.setText(i, 1, "");\r
480                         table.setText(i, 2, "");\r
481                         table.setText(i, 3, "");\r
482                         table.setText(i, 4, "");\r
483                         table.setText(i, 5, "");\r
484                         table.setText(i, 6, "");\r
485                         table.setText(i, 7, "");\r
486                         table.getCellFormatter().setWordWrap(i, 0, false);\r
487                         table.getCellFormatter().setWordWrap(i, 1, false);\r
488                         table.getCellFormatter().setWordWrap(i, 2, false);\r
489                         table.getCellFormatter().setWordWrap(i, 3, false);\r
490                         table.getCellFormatter().setWordWrap(i, 4, false);\r
491                         table.getCellFormatter().setWordWrap(i, 5, false);\r
492                         table.getCellFormatter().setWordWrap(i, 6, false);\r
493                         table.getCellFormatter().setWordWrap(i, 7, false);\r
494                         table.getCellFormatter().setHorizontalAlignment(i, 4, HasHorizontalAlignment.ALIGN_CENTER);\r
495                 }\r
496                 prevButton.setVisible(false);\r
497                 nextButton.setVisible(false);\r
498         }\r
499 \r
500         /**\r
501          * Selects the given row (relative to the current page).\r
502          *\r
503          * @param row the row to be selected\r
504          */\r
505         private void selectRow(final int row) {\r
506                 if (row < folderFileCount) {\r
507                         if (clickControl)\r
508                                 if (selectedRows.contains(row)) {\r
509                                         int i = selectedRows.indexOf(startIndex + row);\r
510                                         selectedRows.remove(i);\r
511                                         styleRow(row, false);\r
512                                 } else {\r
513                                         selectedRows.add(startIndex + row);\r
514                                         styleRow(row, true);\r
515                                 }\r
516                         else if (selectedRows.size() == 1 && selectedRows.contains(row)){\r
517                                 clearSelectedRows();\r
518                                 return;\r
519                         }\r
520                         else {\r
521                                 clearSelectedRows();\r
522                                 selectedRows.add(startIndex + row);\r
523                                 styleRow(row, true);\r
524                         }\r
525                         if (selectedRows.size() == 1)\r
526                                 GSS.get().setCurrentSelection(files.get(selectedRows.get(0)));\r
527                         else if(selectedRows.size() == 0)\r
528                                 GSS.get().setCurrentSelection(null);\r
529                         else\r
530                                 GSS.get().setCurrentSelection(getSelectedFiles());\r
531                         contextMenu.setFiles(getSelectedFiles());\r
532                         makeRowDraggable(row+1);\r
533                 }\r
534         }\r
535 \r
536         public List<FileResource> getSelectedFiles() {\r
537                 List<FileResource> result = new ArrayList();\r
538                 for (int i : selectedRows)\r
539                         result.add(files.get(i));\r
540                 return result;\r
541         }\r
542 \r
543         /**\r
544          * Make the specified row look like selected or not, according to the\r
545          * <code>selected</code> flag.\r
546          *\r
547          * @param row\r
548          * @param selected\r
549          */\r
550         void styleRow(final int row, final boolean selected) {\r
551                 if (row != -1 && row >= 0)\r
552                         if (selected)\r
553                                 table.getRowFormatter().addStyleName(row + 1, "gss-SelectedRow");\r
554                         else\r
555                                 table.getRowFormatter().removeStyleName(row + 1, "gss-SelectedRow");\r
556         }\r
557 \r
558         /**\r
559          * Update the display of the file list.\r
560          */\r
561         void update(boolean sort) {\r
562                 int count = folderFileCount;\r
563                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;\r
564                 if (max > count)\r
565                         max = count;\r
566                 folderTotalSize = 0;\r
567 \r
568                 if (sort && files != null && files.size() != 0) {\r
569                         clearLabels();\r
570                         clearSelectedRows();\r
571 \r
572                         Collections.sort(files, new Comparator<FileResource>() {\r
573 \r
574                                 public int compare(FileResource arg0, FileResource arg1) {\r
575                                         AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());\r
576                                         AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());\r
577                                         if (sortingType)\r
578                                                 if (sortingProperty.equals("version")) {\r
579                                                         versionLabel.setHTML("Version&nbsp;" + descPrototype.getHTML());\r
580                                                         return arg0.getVersion().compareTo(arg1.getVersion());\r
581                                                 } else if (sortingProperty.equals("owner")) {\r
582                                                         ownerLabel.setHTML("Owner&nbsp;" + descPrototype.getHTML());\r
583                                                         return arg0.getOwner().compareTo(arg1.getOwner());\r
584                                                 } else if (sortingProperty.equals("date")) {\r
585                                                         dateLabel.setHTML("Date modified&nbsp;" + descPrototype.getHTML());\r
586                                                         return arg0.getModificationDate().compareTo(arg1.getModificationDate());\r
587                                                 } else if (sortingProperty.equals("size")) {\r
588                                                         sizeLabel.setHTML("Size&nbsp;" + descPrototype.getHTML());\r
589                                                         return arg0.getContentLength().compareTo(arg1.getContentLength());\r
590                                                 } else if (sortingProperty.equals("name")) {\r
591                                                         nameLabel.setHTML("Name&nbsp;" + descPrototype.getHTML());\r
592                                                         return arg0.getName().compareTo(arg1.getName());\r
593                                                 } else if (sortingProperty.equals("path")) {\r
594                                                         pathLabel.setHTML("Path&nbsp;" + descPrototype.getHTML());\r
595                                                         return arg0.getUri().compareTo(arg1.getUri());\r
596                                                 } else {\r
597                                                         nameLabel.setHTML("Name&nbsp;" + descPrototype.getHTML());\r
598                                                         return arg0.getName().compareTo(arg1.getName());\r
599                                                 }\r
600                                         else if (sortingProperty.equals("version")) {\r
601                                                 versionLabel.setHTML("Version&nbsp;" + ascPrototype.getHTML());\r
602                                                 return arg1.getVersion().compareTo(arg0.getVersion());\r
603                                         } else if (sortingProperty.equals("owner")) {\r
604                                                 ownerLabel.setHTML("Owner&nbsp;" + ascPrototype.getHTML());\r
605                                                 return arg1.getOwner().compareTo(arg0.getOwner());\r
606                                         } else if (sortingProperty.equals("date")) {\r
607                                                 dateLabel.setHTML("Date modified&nbsp;" + ascPrototype.getHTML());\r
608                                                 return arg1.getModificationDate().compareTo(arg0.getModificationDate());\r
609                                         } else if (sortingProperty.equals("size")) {\r
610                                                 sizeLabel.setHTML("Size&nbsp;" + ascPrototype.getHTML());\r
611                                                 return arg1.getContentLength().compareTo(arg0.getContentLength());\r
612                                         } else if (sortingProperty.equals("name")) {\r
613                                                 nameLabel.setHTML("Name&nbsp;" + ascPrototype.getHTML());\r
614                                                 return arg1.getName().compareTo(arg0.getName());\r
615                                         } else if (sortingProperty.equals("path")) {\r
616                                                 pathLabel.setHTML("Path&nbsp;" + ascPrototype.getHTML());\r
617                                                 return arg1.getUri().compareTo(arg0.getUri());\r
618                                         } else {\r
619                                                 nameLabel.setHTML("Name&nbsp;" + ascPrototype.getHTML());\r
620                                                 return arg1.getName().compareTo(arg0.getName());\r
621                                         }\r
622                                 }\r
623 \r
624                         });\r
625                 }\r
626 \r
627 \r
628                 // Show the selected files.\r
629                 int i = 1;\r
630                 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {\r
631                         // Don't read past the end.\r
632                         // if (i > folderFileCount)\r
633                         // break;\r
634                         if (startIndex + i > folderFileCount)\r
635                                 break;\r
636                         // Add a new row to the table, then set each of its columns to the\r
637                         // proper values.\r
638                         FileResource file = files.get(startIndex + i - 1);\r
639                         table.setWidget(i, 0, getFileIcon(file).createImage());\r
640                         table.getRowFormatter().addStyleName(i, "gss-fileRow");\r
641 \r
642                         //add view image link for image files\r
643                         String contentType = file.getContentType();\r
644                         if (contentType.endsWith("png") || contentType.endsWith("gif") || contentType.endsWith("jpeg") )\r
645                                 table.setHTML(i, 1, file.getName() + " <a href='" +\r
646                                                 GSS.get().getTopPanel().getFileMenu().getDownloadURL(file) +\r
647                                                 "' title='" + file.getName() + "' rel='lytebox[p]' " +\r
648                                                 "onclick='myLytebox.start(this, false, false)'>" +\r
649                                                 "(view)" + "</a>");\r
650                         else\r
651                                 table.setHTML(i, 1, file.getName());\r
652                         table.setText(i, 2, file.getOwner());\r
653                         table.setText(i, 3, file.getPath());\r
654                         table.setText(i, 4, String.valueOf(file.getVersion()));\r
655                         table.setText(i, 5, String.valueOf(file.getFileSizeAsString()));\r
656                         final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");\r
657                         table.setText(i, 6, formatter.format(file.getModificationDate()));\r
658                         folderTotalSize += file.getContentLength();\r
659                 }\r
660 \r
661                 // Clear any remaining slots.\r
662                 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {\r
663                         table.setHTML(i, 0, "&nbsp;");\r
664                         table.setHTML(i, 1, "&nbsp;");\r
665                         table.setHTML(i, 2, "&nbsp;");\r
666                         table.setHTML(i, 3, "&nbsp;");\r
667                         table.setHTML(i, 4, "&nbsp;");\r
668                         table.setHTML(i, 5, "&nbsp;");\r
669                         table.setHTML(i, 6, "&nbsp;");\r
670                         table.setHTML(i, 7, "&nbsp;");\r
671                 }\r
672 \r
673                 if (folderFileCount == 0) {\r
674                         showingStats = "no files";\r
675                         prevButton.setVisible(false);\r
676                         nextButton.setVisible(false);\r
677                 } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {\r
678                         if (folderFileCount == 1)\r
679                                 showingStats = "1 file";\r
680                         else\r
681                                 showingStats = folderFileCount + " files";\r
682                         showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";\r
683                         prevButton.setVisible(false);\r
684                         nextButton.setVisible(false);\r
685                 } else {\r
686                         showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";\r
687                         prevButton.setVisible(startIndex != 0);\r
688                         nextButton.setVisible(startIndex + GSS.VISIBLE_FILE_COUNT < count);\r
689                 }\r
690                 updateCurrentlyShowingStats();\r
691 \r
692         }\r
693 \r
694         /**\r
695          * Return the proper icon based on the MIME type of the file.\r
696          *\r
697          * @param file\r
698          * @return the icon\r
699          */\r
700         private AbstractImagePrototype getFileIcon(FileResource file) {\r
701                 String mimetype = file.getContentType();\r
702                 boolean shared = file.isShared();\r
703                 if (mimetype == null)\r
704                         return shared ? AbstractImagePrototype.create(images.documentShared()) : AbstractImagePrototype.create(images.document());\r
705                 mimetype = mimetype.toLowerCase();\r
706                 if (mimetype.startsWith("application/pdf"))\r
707                         return shared ? AbstractImagePrototype.create(images.pdfShared()) : AbstractImagePrototype.create(images.pdf());\r
708                 else if (mimetype.endsWith("excel"))\r
709                         return shared ? AbstractImagePrototype.create(images.spreadsheetShared()) : AbstractImagePrototype.create(images.spreadsheet());\r
710                 else if (mimetype.endsWith("msword"))\r
711                         return shared ? AbstractImagePrototype.create(images.wordprocessorShared()) : AbstractImagePrototype.create(images.wordprocessor());\r
712                 else if (mimetype.endsWith("powerpoint"))\r
713                         return shared ? AbstractImagePrototype.create(images.presentationShared()) : AbstractImagePrototype.create(images.presentation());\r
714                 else if (mimetype.startsWith("application/zip") ||\r
715                                         mimetype.startsWith("application/gzip") ||\r
716                                         mimetype.startsWith("application/x-gzip") ||\r
717                                         mimetype.startsWith("application/x-tar") ||\r
718                                         mimetype.startsWith("application/x-gtar"))\r
719                         return shared ? AbstractImagePrototype.create(images.zipShared()) : AbstractImagePrototype.create(images.zip());\r
720                 else if (mimetype.startsWith("text/html"))\r
721                         return shared ? AbstractImagePrototype.create(images.htmlShared()) : AbstractImagePrototype.create(images.html());\r
722                 else if (mimetype.startsWith("text/plain"))\r
723                         return shared ? AbstractImagePrototype.create(images.txtShared()) : AbstractImagePrototype.create(images.txt());\r
724                 else if (mimetype.startsWith("image/"))\r
725                         return shared ? AbstractImagePrototype.create(images.imageShared()) : AbstractImagePrototype.create(images.image());\r
726                 else if (mimetype.startsWith("video/"))\r
727                         return shared ? AbstractImagePrototype.create(images.videoShared()) : AbstractImagePrototype.create(images.video());\r
728                 else if (mimetype.startsWith("audio/"))\r
729                         return shared ? AbstractImagePrototype.create(images.audioShared()) : AbstractImagePrototype.create(images.audio());\r
730                 return shared ? AbstractImagePrototype.create(images.documentShared()) : AbstractImagePrototype.create(images.document());\r
731         }\r
732 \r
733         /**\r
734          * Update status panel with currently showing file stats.\r
735          */\r
736         public void updateCurrentlyShowingStats() {\r
737                 GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);\r
738         }\r
739 \r
740         /**\r
741          * Adjust the height of the table by adding and removing rows as necessary.\r
742          *\r
743          * @param newHeight the new height to reach\r
744          */\r
745         void resizeTableHeight(final int newHeight) {\r
746                 GWT.log("Panel: " + newHeight + ", parent: " + table.getParent().getOffsetHeight(), null);\r
747                 // Fill the rest with empty slots.\r
748                 if (newHeight > table.getOffsetHeight())\r
749                         while (newHeight > table.getOffsetHeight()) {\r
750                                 table.resizeRows(table.getRowCount() + 1);\r
751                                 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);\r
752                         }\r
753                 else\r
754                         while (newHeight < table.getOffsetHeight()) {\r
755                                 table.resizeRows(table.getRowCount() - 1);\r
756                                 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);\r
757                         }\r
758         }\r
759 \r
760         public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection) {\r
761                 updateFileCache(updateSelectedFolder, clearSelection, null);\r
762         }\r
763 \r
764         public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection, final String newFilename) {\r
765                 if (!updateSelectedFolder && !GSS.get().getFolders().getTrashItem().equals(GSS.get().getFolders().getCurrent()))\r
766                         updateFileCache(clearSelection);\r
767                 else if (GSS.get().getFolders().getCurrent() != null) {\r
768                         final DnDTreeItem folderItem = (DnDTreeItem) GSS.get().getFolders().getCurrent();\r
769                         if (folderItem.getFolderResource() != null) {\r
770                                 update(true);\r
771                                 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, folderItem.getFolderResource().getUri()) {\r
772 \r
773                                                 @Override\r
774                                                 public void onComplete() {\r
775                                                         folderItem.setUserObject(getResult());\r
776                                                         if(GSS.get().getFolders().isFileItem(folderItem)){\r
777                                                                 String[] filePaths = new String[folderItem.getFolderResource().getFilePaths().size()];\r
778                                                                 int c=0;\r
779                                                                 for(String fpath : folderItem.getFolderResource().getFilePaths()){\r
780                                                                         filePaths[c] = fpath + "?" + Math.random();\r
781                                                                         c++;\r
782                                                                 }\r
783                                                                 MultipleHeadCommand<FileResource> getFiles = new MultipleHeadCommand<FileResource>(FileResource.class, filePaths){\r
784 \r
785                                                                         @Override\r
786                                                                         public void onComplete(){\r
787                                                                                 List<FileResource> result = getResult();\r
788                                                                                 //remove random from path\r
789                                                                                 for(FileResource r : result){\r
790                                                                                         String p = r.getUri();\r
791                                                                                         int indexOfQuestionMark = p.lastIndexOf('?');\r
792                                                                                         if(indexOfQuestionMark>0)\r
793                                                                                                 r.setUri(p.substring(0, indexOfQuestionMark));\r
794                                                                                 }\r
795                                                                                 folderItem.getFolderResource().setFiles(result);\r
796                                                                                 updateFileCache(clearSelection, newFilename);\r
797                                                                         }\r
798 \r
799                                                                         @Override\r
800                                                                         public void onError(String p, Throwable throwable) {\r
801                                                                                 if(throwable instanceof RestException)\r
802                                                                                         GSS.get().displayError("Unable to retrieve file details:"+((RestException)throwable).getHttpStatusText());\r
803                                                                         }\r
804 \r
805                                                                         @Override\r
806                                                                         public void onError(Throwable t) {\r
807                                                                                 GWT.log("", t);\r
808                                                                                 GSS.get().displayError("Unable to fetch files for folder " + folderItem.getFolderResource().getName());\r
809                                                                         }\r
810 \r
811                                                                 };\r
812                                                                 DeferredCommand.addCommand(getFiles);\r
813                                                         }\r
814                                                         else\r
815                                                                 updateFileCache(clearSelection, newFilename);\r
816                                                 }\r
817 \r
818                                                 @Override\r
819                                                 public void onError(Throwable t) {\r
820                                                         GWT.log("", t);\r
821                                                         GSS.get().displayError("Unable to fetch folder " + folderItem.getFolderResource().getName());\r
822                                                 }\r
823                                         };\r
824                                         DeferredCommand.addCommand(gf);\r
825                         } else if (folderItem.getTrashResource() != null) {\r
826                                 GetCommand<TrashResource> gt = new GetCommand<TrashResource>(TrashResource.class, folderItem.getTrashResource().getUri()) {\r
827 \r
828                                         @Override\r
829                                         public void onComplete() {\r
830                                                 folderItem.setUserObject(getResult());\r
831                                                 updateFileCache(clearSelection);\r
832                                         }\r
833 \r
834                                         @Override\r
835                                         public void onError(Throwable t) {\r
836                                                 if (t instanceof RestException && (((RestException) t).getHttpStatusCode() == 204 || ((RestException) t).getHttpStatusCode() == 1223)) {\r
837                                                         folderItem.setUserObject(new TrashResource(folderItem.getTrashResource().getUri()));\r
838                                                         updateFileCache(clearSelection);\r
839                                                 } else {\r
840                                                         GWT.log("", t);\r
841                                                         GSS.get().displayError("Unable to fetch trash resource");\r
842                                                 }\r
843                                         }\r
844                                 };\r
845                                 DeferredCommand.addCommand(gt);\r
846                         } else if (folderItem.getSharedResource() != null) {\r
847                                 GetCommand<SharedResource> gt = new GetCommand<SharedResource>(SharedResource.class, folderItem.getSharedResource().getUri()) {\r
848 \r
849                                         @Override\r
850                                         public void onComplete() {\r
851                                                 folderItem.setUserObject(getResult());\r
852                                                 updateFileCache(clearSelection, newFilename);\r
853                                         }\r
854 \r
855                                         @Override\r
856                                         public void onError(Throwable t) {\r
857                                                 GWT.log("", t);\r
858                                                 GSS.get().displayError("Unable to fetch My Shares resource");\r
859                                         }\r
860                                 };\r
861                                 DeferredCommand.addCommand(gt);\r
862                         } else if (folderItem.getOtherUserResource() != null) {\r
863                                 GetCommand<OtherUserResource> gt = new GetCommand<OtherUserResource>(OtherUserResource.class, folderItem.getOtherUserResource().getUri()) {\r
864 \r
865                                         @Override\r
866                                         public void onComplete() {\r
867                                                 folderItem.setUserObject(getResult());\r
868                                                 updateFileCache(clearSelection, newFilename);\r
869                                         }\r
870 \r
871                                         @Override\r
872                                         public void onError(Throwable t) {\r
873                                                 GWT.log("", t);\r
874                                                 GSS.get().displayError("Unable to fetch My Shares resource");\r
875                                         }\r
876                                 };\r
877                                 DeferredCommand.addCommand(gt);\r
878                         }\r
879                 } else\r
880                         updateFileCache(clearSelection);\r
881         }\r
882 \r
883         private void updateFileCache(boolean clearSelection) {\r
884                 updateFileCache(clearSelection, null);\r
885         }\r
886 \r
887         /**\r
888          * Update the file cache with data from the server.\r
889          *\r
890          * @param userId the ID of the current user\r
891          * @param newFilename the new name of the previously selected file,\r
892          *                      if a rename operation has taken place\r
893          */\r
894         private void updateFileCache(boolean clearSelection, String newFilename) {\r
895                 if (clearSelection)\r
896                         clearSelectedRows();\r
897                 clearLabels();\r
898                 startIndex = 0;\r
899                 final TreeItem folderItem = GSS.get().getFolders().getCurrent();\r
900                 // Validation.\r
901                 if (folderItem == null || GSS.get().getFolders().isOthersShared(folderItem)) {\r
902                         setFiles(new ArrayList<FileResource>());\r
903                         update(true);\r
904                         return;\r
905                 }\r
906                 if (folderItem instanceof DnDTreeItem) {\r
907                         DnDTreeItem dnd = (DnDTreeItem) folderItem;\r
908                         if (dnd.getFolderResource() != null) {\r
909                                 if (GSS.get().getFolders().isTrashItem(dnd))\r
910                                         setFiles(new ArrayList<FileResource>());\r
911                                 else\r
912                                         setFiles(dnd.getFolderResource().getFiles());\r
913 \r
914                         } else if (dnd.getTrashResource() != null)\r
915                                 setFiles(dnd.getTrashResource().getFiles());\r
916                         else if (dnd.getSharedResource() != null)\r
917                                 setFiles(dnd.getSharedResource().getFiles());\r
918                         else if (dnd.getOtherUserResource() != null)\r
919                                 setFiles(dnd.getOtherUserResource().getFiles());\r
920                         else\r
921                                 setFiles(dnd.getFolderResource().getFiles());\r
922                         update(true);\r
923 \r
924                         if (!clearSelection && selectedRows.size()==1 && newFilename!=null) {\r
925                                 int row = -1;\r
926                                 for (int i=1; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {\r
927                                         if (startIndex + i > folderFileCount)\r
928                                                 break;\r
929                                         FileResource file = files.get(startIndex + i - 1);\r
930                                         if (newFilename.equals(file.getName())) {\r
931                                                 row = i-1;\r
932                                                 break;\r
933                                         }\r
934                                 }\r
935                                 clearSelectedRows();\r
936                                 if (row!=-1)\r
937                                         selectRow(row);\r
938                         }\r
939                 }\r
940         }\r
941 \r
942         /**\r
943          * Fill the file cache with data.\r
944          */\r
945         public void setFiles(final List<FileResource> _files) {\r
946                 if (_files.size() > 0 && !GSS.get().getFolders().isTrash(GSS.get().getFolders().getCurrent())) {\r
947                         files = new ArrayList<FileResource>();\r
948                         for (FileResource fres : _files)\r
949                                 if (!fres.isDeleted())\r
950                                         files.add(fres);\r
951                 } else\r
952                         files = _files;\r
953                 Collections.sort(files, new Comparator<FileResource>() {\r
954 \r
955                         public int compare(FileResource arg0, FileResource arg1) {\r
956                                 return arg0.getName().compareTo(arg1.getName());\r
957                         }\r
958 \r
959                 });\r
960                 folderFileCount = files.size();\r
961         }\r
962 \r
963         private void sortFiles(final String sortProperty) {\r
964                 if (sortProperty.equals(sortingProperty))\r
965                         sortingType = !sortingType;\r
966                 else {\r
967                         sortingProperty = sortProperty;\r
968                         sortingType = true;\r
969                 }\r
970                 update(true);\r
971         }\r
972 \r
973         private void clearLabels() {\r
974                 nameLabel.setText("Name");\r
975                 versionLabel.setText("Version");\r
976                 sizeLabel.setText("Size");\r
977                 dateLabel.setText("Last modified");\r
978                 ownerLabel.setText("Owner");\r
979                 pathLabel.setText("Path");\r
980         }\r
981 \r
982         /**\r
983          * Retrieve the table.\r
984          *\r
985          * @return the table\r
986          */\r
987         Grid getTable() {\r
988                 return table;\r
989         }\r
990 \r
991         /**\r
992          * Does the list contains the requested filename\r
993          *\r
994          * @param fileName\r
995          * @return true/false\r
996          */\r
997         public boolean contains(String fileName) {\r
998                 for (int i = 0; i < files.size(); i++)\r
999                         if (files.get(i).getName().equals(fileName))\r
1000                                 return true;\r
1001                 return false;\r
1002         }\r
1003 \r
1004         public void clearSelectedRows() {\r
1005                 for (int r : selectedRows) {\r
1006                         int row = r - startIndex;\r
1007                         styleRow(row, false);\r
1008                 }\r
1009                 selectedRows.clear();\r
1010                 Object sel = GSS.get().getCurrentSelection();\r
1011                 if (sel instanceof FileResource || sel instanceof List)\r
1012                         GSS.get().setCurrentSelection(null);\r
1013         }\r
1014 \r
1015         /**\r
1016          *\r
1017          */\r
1018         public void selectAllRows() {\r
1019                 clearSelectedRows();\r
1020                 int count = folderFileCount;\r
1021                 if (count == 0)\r
1022                         return;\r
1023                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;\r
1024                 if (max > count)\r
1025                         max = count;\r
1026                 int i = 1;\r
1027                 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {\r
1028                         // Don't read past the end.\r
1029                         // if (i > folderFileCount)\r
1030                         // break;\r
1031                         if (startIndex + i > folderFileCount)\r
1032                                 break;\r
1033                         selectedRows.add(startIndex + i - 1);\r
1034                         styleRow(i - 1, true);\r
1035                 }\r
1036                 GSS.get().setCurrentSelection(getSelectedFiles());\r
1037                 contextMenu.setFiles(getSelectedFiles());\r
1038                 makeRowDraggable(i-1);\r
1039 \r
1040         }\r
1041 \r
1042         private void makeRowDraggable(int row){\r
1043                 int contextRow = getWidgetRow(contextMenu, table);\r
1044                 if (contextRow != -1)\r
1045                         table.setWidget(contextRow, 0, getFileIcon(files.get(contextRow - 1)).createImage());\r
1046                 contextMenu.setWidget(new HTML(getFileIcon(files.get(row - 1)).getHTML()));\r
1047                 table.setWidget(row, 0, contextMenu);\r
1048         }\r
1049 \r
1050         private int getWidgetRow(Widget widget, Grid grid) {\r
1051                 for (int row = 0; row < grid.getRowCount(); row++)\r
1052                         for (int col = 0; col < grid.getCellCount(row); col++) {\r
1053                                 Widget w = table.getWidget(row, col);\r
1054                                 if (w == widget)\r
1055                                         return row;\r
1056                         }\r
1057                 return -1;\r
1058         }\r
1059 \r
1060 \r
1061 \r
1062 }\r