Formating commit. Comments fixed after code review. 1. Added a 2010 entry in copyrigh...
[pithos] / src / gr / ebs / gss / client / SearchResults.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.DnDSimpleFocusPanel;\r
22 import gr.ebs.gss.client.rest.GetCommand;\r
23 import gr.ebs.gss.client.rest.RestCommand;\r
24 import gr.ebs.gss.client.rest.RestException;\r
25 import gr.ebs.gss.client.rest.resource.FileResource;\r
26 import gr.ebs.gss.client.rest.resource.SearchResource;\r
27 import gr.ebs.gss.client.rest.resource.UserResource;\r
28 \r
29 import java.util.ArrayList;\r
30 import java.util.Collections;\r
31 import java.util.Comparator;\r
32 import java.util.List;\r
33 \r
34 import com.google.gwt.core.client.GWT;\r
35 import com.google.gwt.dom.client.NativeEvent;\r
36 import com.google.gwt.event.dom.client.ClickEvent;\r
37 import com.google.gwt.event.dom.client.ClickHandler;\r
38 import com.google.gwt.http.client.URL;\r
39 import com.google.gwt.i18n.client.DateTimeFormat;\r
40 import com.google.gwt.resources.client.ClientBundle;\r
41 import com.google.gwt.resources.client.ImageResource;\r
42 import com.google.gwt.user.client.DOM;\r
43 import com.google.gwt.user.client.DeferredCommand;\r
44 import com.google.gwt.user.client.Event;\r
45 import com.google.gwt.user.client.IncrementalCommand;\r
46 import com.google.gwt.user.client.Window;\r
47 import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
48 import com.google.gwt.user.client.ui.Composite;\r
49 import com.google.gwt.user.client.ui.Grid;\r
50 import com.google.gwt.user.client.ui.HTML;\r
51 import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
52 import com.google.gwt.user.client.ui.HorizontalPanel;\r
53 import com.google.gwt.user.client.ui.VerticalPanel;\r
54 import com.google.gwt.user.client.ui.HTMLTable.Cell;\r
55 \r
56 /**\r
57  * A composite that displays a list of search results for a particular query on\r
58  * files.\r
59  */\r
60 public class SearchResults extends Composite implements  ClickHandler {\r
61 \r
62         private HTML prevButton = new HTML("<a href='javascript:;'>&lt; Previous</a>", true);\r
63 \r
64         private HTML nextButton = new HTML("<a href='javascript:;'>Next &gt;</a>", true);\r
65 \r
66         private String showingStats = "";\r
67 \r
68         private int startIndex = 0;\r
69 \r
70         /**\r
71          * A constant that denotes the completion of an IncrementalCommand.\r
72          */\r
73         public static final boolean DONE = false;\r
74 \r
75         private boolean clickControl = false;\r
76 \r
77         private boolean clickShift = false;\r
78 \r
79         private int firstShift = -1;\r
80 \r
81         private ArrayList<Integer> selectedRows = new ArrayList<Integer>();\r
82 \r
83         /**\r
84          * The context menu for the selected file.\r
85          */\r
86         final DnDSimpleFocusPanel contextMenu;\r
87 \r
88         /**\r
89          * Specifies that the images available for this composite will be the ones\r
90          * available in FileContextMenu.\r
91          */\r
92         public interface Images extends ClientBundle,FileContextMenu.Images, Folders.Images {\r
93 \r
94                 @Source("gr/ebs/gss/resources/blank.gif")\r
95                 ImageResource blank();\r
96 \r
97                 @Source("gr/ebs/gss/resources/asc.png")\r
98                 ImageResource asc();\r
99 \r
100                 @Source("gr/ebs/gss/resources/desc.png")\r
101                 ImageResource desc();\r
102         }\r
103 \r
104         /**\r
105          * A label with the number of files in this folder.\r
106          */\r
107         private HTML countLabel = new HTML();\r
108 \r
109         /**\r
110          * The table widget with the file list.\r
111          */\r
112         private FileTable table;\r
113 \r
114         /**\r
115          * The navigation bar for paginating the results.\r
116          */\r
117         private HorizontalPanel navBar = new HorizontalPanel();\r
118 \r
119         /**\r
120          * The number of files in the search results\r
121          */\r
122         private int folderFileCount;\r
123 \r
124         /**\r
125          * Total search results size\r
126          */\r
127         private long folderTotalSize;\r
128 \r
129         /**\r
130          * A cache of the files in the list.\r
131          */\r
132         private List<FileResource> files;\r
133 \r
134         /**\r
135          * The widget's image bundle.\r
136          */\r
137         private final Images images;\r
138 \r
139         private String sortingProperty = "name";\r
140 \r
141         private boolean sortingType = true;\r
142 \r
143         private HTML nameLabel;\r
144 \r
145         private HTML versionLabel;\r
146 \r
147         private HTML sizeLabel;\r
148 \r
149         private HTML dateLabel;\r
150 \r
151         private HTML ownerLabel;\r
152 \r
153         private HTML pathLabel;\r
154 \r
155         private HTML searchResults = new HTML("Results for search:");\r
156 \r
157         /**\r
158          * Construct the file list widget. This entails setting up the widget\r
159          * layout, fetching the number of files in the current folder from the\r
160          * server and filling the local file cache of displayed files with data from\r
161          * the server, as well.\r
162          *\r
163          * @param _images\r
164          */\r
165         public SearchResults(final Images _images) {\r
166                 images = _images;\r
167                 final GSS app = GSS.get();\r
168                 table = new FileTable(GSS.VISIBLE_FILE_COUNT + 1, 8) {\r
169 \r
170                         @Override\r
171                         public void onBrowserEvent(Event event) {\r
172                                 if (DOM.eventGetType(event) == Event.ONMOUSEDOWN && DOM.eventGetButton(event) == NativeEvent.BUTTON_RIGHT){\r
173                                         if (DOM.eventGetCtrlKey(event))\r
174                                                 clickControl = true;\r
175                                         else\r
176                                                 clickControl = false;\r
177                                         if (DOM.eventGetShiftKey(event)) {\r
178                                                 clickShift = true;\r
179                                                 if (selectedRows.size() == 1)\r
180                                                         firstShift = selectedRows.get(0) - startIndex;\r
181                                                 //event.preventDefault();\r
182                                         } else {\r
183                                                 clickShift = false;\r
184                                                 firstShift = -1;\r
185                                                 //event.preventDefault();\r
186                                         }\r
187                                         int ri = table.getRowForEvent2(event);\r
188                                         if(ri != -1)\r
189                                                 if(!selectedRows.contains(ri-1))\r
190                                                         onRowClicked(ri, false);\r
191                                 }\r
192 \r
193                                 if (files == null || files.size() == 0) {\r
194                                         if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() == 0) {\r
195                                                 FileContextMenu fm = new FileContextMenu(images, false, true);\r
196                                                 fm.onEmptyEvent(event);\r
197                                         }\r
198                                         return;\r
199                                 }\r
200                                 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() != 0) {\r
201                                         FileContextMenu fm = new FileContextMenu(images, false, false);\r
202                                         fm.onEvent(event);\r
203                                 } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() == 0) {\r
204                                         FileContextMenu fm = new FileContextMenu(images, false, true);\r
205                                         fm.onEmptyEvent(event);\r
206                                 } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)\r
207                                         if (getSelectedFiles().size() == 1) {\r
208                                                 GSS app = GSS.get();\r
209                                                 FileResource file = getSelectedFiles().get(0);\r
210                                                 String dateString = RestCommand.getDate();\r
211                                                 String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());\r
212                                                 String sig = app.getCurrentUserResource().getUsername() + " " +\r
213                                                                 RestCommand.calculateSig("GET", dateString, resource,\r
214                                                                 RestCommand.base64decode(app.getToken()));\r
215                                                 Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");\r
216                                                 event.preventDefault();\r
217                                                 return;\r
218                                         }\r
219                                 if (DOM.eventGetType(event) == Event.ONCLICK) {\r
220                                         if (DOM.eventGetCtrlKey(event))\r
221                                                 clickControl = true;\r
222                                         else\r
223                                                 clickControl = false;\r
224                                         if (DOM.eventGetShiftKey(event)) {\r
225                                                 clickShift = true;\r
226                                                 if (selectedRows.size() == 1)\r
227                                                         firstShift = selectedRows.get(0) - startIndex;\r
228                                                 //event.preventDefault();\r
229                                         } else {\r
230                                                 clickShift = false;\r
231                                                 firstShift = -1;\r
232                                                 //event.preventDefault();\r
233                                         }\r
234                                 }\r
235                                 super.onBrowserEvent(event);\r
236                         }\r
237                 };\r
238                 prevButton.addClickHandler(this);\r
239                 nextButton.addClickHandler(this);\r
240 \r
241                 contextMenu = new DnDSimpleFocusPanel(new HTML(AbstractImagePrototype.create(images.fileContextMenu()).getHTML()));\r
242                 contextMenu.addClickHandler(new FileContextMenu(images, false, false));\r
243                 app.getDragController().makeDraggable(contextMenu);\r
244 \r
245                 // Setup the table.\r
246                 table.setCellSpacing(0);\r
247                 table.setCellPadding(2);\r
248                 table.setWidth("100%");\r
249 \r
250                 // Hook up events.\r
251                 table.addClickHandler(new ClickHandler() {\r
252 \r
253                         @Override\r
254                         public void onClick(ClickEvent event) {\r
255                                 Cell cell = table.getCellForEvent(event);\r
256                                 onRowClicked(cell.getRowIndex(),true);\r
257                         }\r
258                 });\r
259 \r
260                 // Create the 'navigation' bar at the upper-right.\r
261                 HorizontalPanel innerNavBar = new HorizontalPanel();\r
262                 innerNavBar.setStyleName("gss-ListNavBar");\r
263                 innerNavBar.setSpacing(8);\r
264                 innerNavBar.add(prevButton);\r
265                 innerNavBar.add(countLabel);\r
266                 innerNavBar.add(nextButton);\r
267                 navBar.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);\r
268                 navBar.add(innerNavBar);\r
269                 navBar.setWidth("100%");\r
270                 VerticalPanel vp = new VerticalPanel();\r
271                 vp.add(searchResults);\r
272                 searchResults.addStyleName("gss-searchLabel");\r
273                 vp.add(table);\r
274                 initWidget(vp);\r
275                 table.setStyleName("gss-List");\r
276                 initTable();\r
277                 DeferredCommand.addCommand(new IncrementalCommand() {\r
278 \r
279                         public boolean execute() {\r
280                                 return fetchRootFolder();\r
281                         }\r
282                 });\r
283                 table.sinkEvents(Event.ONCONTEXTMENU);\r
284                 table.sinkEvents(Event.ONMOUSEUP);\r
285                 table.sinkEvents(Event.ONMOUSEDOWN);\r
286                 table.sinkEvents(Event.ONCLICK);\r
287                 table.sinkEvents(Event.ONKEYDOWN);\r
288                 table.sinkEvents(Event.ONDBLCLICK);\r
289                 preventIESelection();\r
290         }\r
291 \r
292         public void onClick(ClickEvent event) {\r
293                 if (event.getSource() == nextButton) {\r
294                         // Move forward a page.\r
295                         clearSelectedRows();\r
296                         startIndex += GSS.VISIBLE_FILE_COUNT;\r
297                         if (startIndex >= folderFileCount)\r
298                                 startIndex -= GSS.VISIBLE_FILE_COUNT;\r
299                         else\r
300                                 update(false);\r
301                 } else if (event.getSource() == prevButton) {\r
302                         clearSelectedRows();\r
303                         // Move back a page.\r
304                         startIndex -= GSS.VISIBLE_FILE_COUNT;\r
305                         if (startIndex < 0)\r
306                                 startIndex = 0;\r
307                         else\r
308                                 update(false);\r
309                 }\r
310         }\r
311 \r
312         /**\r
313          * Retrieve the root folder for the current user.\r
314          *\r
315          * @return true if the retrieval was successful\r
316          */\r
317         protected boolean fetchRootFolder() {\r
318                 UserResource user = GSS.get().getCurrentUserResource();\r
319                 if (user == null)\r
320                         return !DONE;\r
321                 updateFileCache("");\r
322                 return DONE;\r
323         }\r
324 \r
325         public void onRowClicked(int row, boolean toggleSelection) {\r
326                 // Select the row that was clicked (-1 to account for header row).\r
327                 if (row > folderFileCount)\r
328                         return;\r
329                 if (clickShift) {\r
330                         GWT.log("ROW is:" + row + " fs:" + firstShift, null);\r
331                         if (firstShift == -1)\r
332                                 firstShift = row;\r
333                         else if (row > firstShift) {\r
334                                 clearSelectedRows();\r
335                                 for (int i = firstShift; i < row; i++) {\r
336                                         selectedRows.add(startIndex + i);\r
337                                         styleRow(i, true);\r
338                                 }\r
339                                 GSS.get().setCurrentSelection(getSelectedFiles());\r
340                                 //contextMenu.setFiles(getSelectedFiles());\r
341                                 table.setWidget(row, 0, contextMenu);\r
342                         } else if (row != -1 && row == firstShift) {\r
343                                 selectedRows.add(row);\r
344                                 selectedRows.add(row - 1);\r
345                                 styleRow(row, true);\r
346                                 styleRow(row - 1, true);\r
347                         } else if (row < firstShift) {\r
348                                 GWT.log("ROW is:" + row + " fs:" + firstShift, null);\r
349                                 clearSelectedRows();\r
350 \r
351                                 for (int i = firstShift; i >= row - 1; i--) {\r
352                                         selectedRows.add(startIndex + i);\r
353                                         styleRow(i, true);\r
354                                 }\r
355                                 GSS.get().setCurrentSelection(getSelectedFiles());\r
356                                 table.setWidget(row, 0, contextMenu);\r
357                                 //contextMenu.setFiles(getSelectedFiles());\r
358                         }\r
359 \r
360                 } else if (row > 0)\r
361                         selectRow(row - 1, toggleSelection);\r
362 \r
363         }\r
364 \r
365         /**\r
366          * Initializes the table so that it contains enough rows for a full page of\r
367          * files.\r
368          */\r
369         private void initTable() {\r
370 \r
371                 nameLabel = new HTML("Name");\r
372                 nameLabel.addClickHandler(new ClickHandler() {\r
373                         @Override\r
374                         public void onClick(ClickEvent event) {\r
375                                 sortFiles("name");\r
376                         }\r
377 \r
378                 });\r
379                 versionLabel = new HTML("Version");\r
380                 versionLabel.addClickHandler(new ClickHandler() {\r
381                         @Override\r
382                         public void onClick(ClickEvent event) {\r
383                                 sortFiles("version");\r
384                         }\r
385 \r
386                 });\r
387                 sizeLabel = new HTML("Size");\r
388                 sizeLabel.addClickHandler(new ClickHandler() {\r
389                         @Override\r
390                         public void onClick(ClickEvent event) {\r
391                                 sortFiles("size");\r
392                         }\r
393 \r
394                 });\r
395                 dateLabel = new HTML("Last modified");\r
396                 dateLabel.addClickHandler(new ClickHandler() {\r
397                         @Override\r
398                         public void onClick(ClickEvent event) {\r
399                                 sortFiles("date");\r
400                         }\r
401 \r
402                 });\r
403                 ownerLabel = new HTML("Owner");\r
404                 ownerLabel.addClickHandler(new ClickHandler() {\r
405                         @Override\r
406                         public void onClick(ClickEvent event) {\r
407                                 sortFiles("owner");\r
408                         }\r
409 \r
410                 });\r
411 \r
412                 pathLabel = new HTML("Path");\r
413                 pathLabel.addClickHandler(new ClickHandler() {\r
414                         @Override\r
415                         public void onClick(ClickEvent event) {\r
416                                 sortFiles("path");\r
417                         }\r
418 \r
419                 });\r
420                 // Create the header row.\r
421                 table.setText(0, 0, "");\r
422                 // table.setText(0, 1, "Name");\r
423                 table.setWidget(0, 1, nameLabel);\r
424                 table.setWidget(0, 2, ownerLabel);\r
425                 // table.setText(0, 3, "Version");\r
426                 table.setWidget(0, 3, pathLabel);\r
427                 table.setWidget(0, 4, versionLabel);\r
428                 // table.setText(0, 4, "Size");\r
429                 table.setWidget(0, 5, sizeLabel);\r
430                 // table.setText(0, 5, "Last modified");\r
431                 table.setWidget(0, 6, dateLabel);\r
432                 table.setWidget(0, 7, navBar);\r
433                 table.getRowFormatter().setStyleName(0, "gss-ListHeader");\r
434 \r
435                 // Initialize the rest of the rows.\r
436                 for (int i = 1; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {\r
437                         table.setText(i, 0, "");\r
438                         table.setText(i, 1, "");\r
439                         table.setText(i, 2, "");\r
440                         table.setText(i, 3, "");\r
441                         table.setText(i, 4, "");\r
442                         table.setText(i, 5, "");\r
443                         table.setText(i, 6, "");\r
444                         table.getCellFormatter().setWordWrap(i, 0, false);\r
445                         table.getCellFormatter().setWordWrap(i, 1, false);\r
446                         table.getCellFormatter().setWordWrap(i, 2, false);\r
447                         table.getCellFormatter().setWordWrap(i, 3, false);\r
448                         table.getCellFormatter().setWordWrap(i, 4, false);\r
449                         table.getCellFormatter().setWordWrap(i, 5, false);\r
450                         table.getCellFormatter().setWordWrap(i, 6, false);\r
451                         table.getCellFormatter().setHorizontalAlignment(i, 4, HasHorizontalAlignment.ALIGN_CENTER);\r
452                 }\r
453                 prevButton.setVisible(false);\r
454                 nextButton.setVisible(false);\r
455         }\r
456 \r
457         /**\r
458          * Selects the given row (relative to the current page).\r
459          *\r
460          * @param row the row to be selected\r
461          */\r
462         private void selectRow(final int row, boolean toggleSelection) {\r
463                 if (row < folderFileCount) {\r
464                         if (clickControl)\r
465                                 if (selectedRows.contains(row) && toggleSelection) {\r
466                                         int i = selectedRows.indexOf(startIndex + row);\r
467                                         selectedRows.remove(i);\r
468                                         styleRow(row, false);\r
469                                 } else {\r
470                                         for (int r : selectedRows) {\r
471                                                 int prow = r - startIndex;\r
472                                                 table.setWidget(prow + 1, 0, AbstractImagePrototype.create(images.document()).createImage());\r
473                                         }\r
474                                         selectedRows.add(startIndex + row);\r
475                                         styleRow(row, true);\r
476                                 }\r
477                         else {\r
478                                 clearSelectedRows();\r
479                                 selectedRows.add(startIndex + row);\r
480                                 styleRow(row, true);\r
481                         }\r
482                         if (selectedRows.size() == 1)\r
483                                 GSS.get().setCurrentSelection(files.get(selectedRows.get(0)));\r
484                         else\r
485                                 GSS.get().setCurrentSelection(getSelectedFiles());\r
486                         //contextMenu.setFiles(getSelectedFiles());\r
487                         table.setWidget(row + 1, 0, contextMenu);\r
488                 }\r
489         }\r
490 \r
491         public List<FileResource> getSelectedFiles() {\r
492                 List<FileResource> result = new ArrayList();\r
493                 for (int i : selectedRows)\r
494                         result.add(files.get(i));\r
495                 return result;\r
496         }\r
497 \r
498         /**\r
499          * Make the specified row look like selected or not, according to the\r
500          * <code>selected</code> flag.\r
501          *\r
502          * @param row\r
503          * @param selected\r
504          */\r
505         void styleRow(final int row, final boolean selected) {\r
506                 if (row != -1 && row >= 0)\r
507                         if (selected)\r
508                                 table.getRowFormatter().addStyleName(row + 1, "gss-SelectedRow");\r
509                         else\r
510                                 table.getRowFormatter().removeStyleName(row + 1, "gss-SelectedRow");\r
511         }\r
512 \r
513         /**\r
514          * Update the display of the file list.\r
515          */\r
516         void update(boolean sort) {\r
517                 int count = folderFileCount;\r
518                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;\r
519                 if (max > count)\r
520                         max = count;\r
521                 folderTotalSize = 0;\r
522 \r
523                 if (sort && files != null && files.size() != 0) {\r
524                         clearLabels();\r
525                         clearSelectedRows();\r
526 \r
527                         Collections.sort(files, new Comparator<FileResource>() {\r
528 \r
529                                 public int compare(FileResource arg0, FileResource arg1) {\r
530                                         AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());\r
531                                         AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());\r
532                                         if (sortingType)\r
533                                                 if (sortingProperty.equals("version")) {\r
534                                                         versionLabel.setHTML("Version&nbsp;" + descPrototype.getHTML());\r
535                                                         return arg0.getVersion().compareTo(arg1.getVersion());\r
536                                                 } else if (sortingProperty.equals("owner")) {\r
537                                                         ownerLabel.setHTML("Owner&nbsp;" + descPrototype.getHTML());\r
538                                                         return arg0.getOwner().compareTo(arg1.getOwner());\r
539                                                 } else if (sortingProperty.equals("date")) {\r
540                                                         dateLabel.setHTML("Last modified&nbsp;" + descPrototype.getHTML());\r
541                                                         return arg0.getModificationDate().compareTo(arg1.getModificationDate());\r
542                                                 } else if (sortingProperty.equals("size")) {\r
543                                                         sizeLabel.setHTML("Size&nbsp;" + descPrototype.getHTML());\r
544                                                         return arg0.getContentLength().compareTo(arg1.getContentLength());\r
545                                                 } else if (sortingProperty.equals("name")) {\r
546                                                         nameLabel.setHTML("Name&nbsp;" + descPrototype.getHTML());\r
547                                                         return arg0.getName().compareTo(arg1.getName());\r
548                                                 } else if (sortingProperty.equals("path")) {\r
549                                                         pathLabel.setHTML("Path&nbsp;" + descPrototype.getHTML());\r
550                                                         return arg0.getUri().compareTo(arg1.getUri());\r
551                                                 } else {\r
552                                                         nameLabel.setHTML("Name&nbsp;" + descPrototype.getHTML());\r
553                                                         return arg0.getName().compareTo(arg1.getName());\r
554                                                 }\r
555                                         else if (sortingProperty.equals("version")) {\r
556                                                 versionLabel.setHTML("Version&nbsp;" + ascPrototype.getHTML());\r
557                                                 return arg1.getVersion().compareTo(arg0.getVersion());\r
558                                         } else if (sortingProperty.equals("owner")) {\r
559                                                 ownerLabel.setHTML("Owner&nbsp;" + ascPrototype.getHTML());\r
560                                                 return arg1.getOwner().compareTo(arg0.getOwner());\r
561                                         } else if (sortingProperty.equals("date")) {\r
562                                                 dateLabel.setHTML("Last modified&nbsp;" + ascPrototype.getHTML());\r
563                                                 return arg1.getModificationDate().compareTo(arg0.getModificationDate());\r
564                                         } else if (sortingProperty.equals("size")) {\r
565                                                 sizeLabel.setHTML("Size&nbsp;" + ascPrototype.getHTML());\r
566                                                 return arg1.getContentLength().compareTo(arg0.getContentLength());\r
567                                         } else if (sortingProperty.equals("name")) {\r
568                                                 nameLabel.setHTML("Name&nbsp;" + ascPrototype.getHTML());\r
569                                                 return arg1.getName().compareTo(arg0.getName());\r
570                                         } else if (sortingProperty.equals("path")) {\r
571                                                 pathLabel.setHTML("Path&nbsp;" + ascPrototype.getHTML());\r
572                                                 return arg1.getUri().compareTo(arg0.getUri());\r
573                                         } else {\r
574                                                 nameLabel.setHTML("Name&nbsp;" + ascPrototype.getHTML());\r
575                                                 return arg1.getName().compareTo(arg0.getName());\r
576                                         }\r
577                                 }\r
578 \r
579                         });\r
580 \r
581                 }\r
582                 // Show the selected files.\r
583                 int i = 1;\r
584                 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {\r
585                         // Don't read past the end.\r
586                         // if (i > folderFileCount)\r
587                         // break;\r
588                         if (startIndex + i > folderFileCount)\r
589                                 break;\r
590                         // Add a new row to the table, then set each of its columns to the\r
591                         // proper values.\r
592                         table.setWidget(i, 0, AbstractImagePrototype.create(images.document()).createImage());\r
593                         FileResource fileHeader = files.get(startIndex + i - 1);\r
594                         table.getRowFormatter().addStyleName(i, "gss-fileRow");\r
595                         table.setHTML(i, 1, fileHeader.getName());\r
596                         table.setText(i, 2, fileHeader.getOwner());\r
597                         table.setText(i, 3, fileHeader.getPath());\r
598                         table.setText(i, 4, String.valueOf(fileHeader.getVersion()));\r
599                         table.setText(i, 5, String.valueOf(fileHeader.getFileSizeAsString()));\r
600                         final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");\r
601                         table.setText(i, 6, formatter.format(fileHeader.getModificationDate()));\r
602                         folderTotalSize += fileHeader.getContentLength();\r
603                 }\r
604 \r
605                 // Clear any remaining slots.\r
606                 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {\r
607                         table.setHTML(i, 0, "&nbsp;");\r
608                         table.setHTML(i, 1, "&nbsp;");\r
609                         table.setHTML(i, 2, "&nbsp;");\r
610                         table.setHTML(i, 3, "&nbsp;");\r
611                         table.setHTML(i, 4, "&nbsp;");\r
612                         table.setHTML(i, 5, "&nbsp;");\r
613                         table.setHTML(i, 6, "&nbsp;");\r
614                         table.setHTML(i, 7, "&nbsp;");\r
615                 }\r
616 \r
617                 if (folderFileCount == 0) {\r
618                         showingStats = "no files";\r
619                         prevButton.setVisible(false);\r
620                         nextButton.setVisible(false);\r
621                 } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {\r
622                         if (folderFileCount == 1)\r
623                                 showingStats = "1 file";\r
624                         else\r
625                                 showingStats = folderFileCount + " files";\r
626                         showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";\r
627                         prevButton.setVisible(false);\r
628                         nextButton.setVisible(false);\r
629                 } else {\r
630                         showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";\r
631                         prevButton.setVisible(startIndex != 0);\r
632                         nextButton.setVisible(startIndex + GSS.VISIBLE_FILE_COUNT < count);\r
633                 }\r
634                 updateCurrentlyShowingStats();\r
635         }\r
636 \r
637         /**\r
638          *  update status panel with currently showing file stats\r
639          */\r
640         public void updateCurrentlyShowingStats() {\r
641                 GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);\r
642         }\r
643 \r
644         /**\r
645          * Adjust the height of the table by adding and removing rows as necessary.\r
646          *\r
647          * @param newHeight the new height to reach\r
648          */\r
649         void resizeTableHeight(final int newHeight) {\r
650                 GWT.log("Panel: " + newHeight + ", parent: " + table.getParent().getOffsetHeight(), null);\r
651                 // Fill the rest with empty slots.\r
652                 if (newHeight > table.getOffsetHeight())\r
653                         while (newHeight > table.getOffsetHeight()) {\r
654                                 // table.setHTML(table.getRowCount(), 5, "&nbsp;");\r
655                                 table.resizeRows(table.getRowCount() + 1);\r
656                                 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);\r
657                         }\r
658                 else\r
659                         while (newHeight < table.getOffsetHeight()) {\r
660                                 // table.setHTML(table.getRowCount(), 5, "&nbsp;");\r
661                                 table.resizeRows(table.getRowCount() - 1);\r
662                                 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);\r
663                         }\r
664         }\r
665 \r
666         /**\r
667          * Update the file cache with data from the server.\r
668          */\r
669         public void updateFileCache(String query) {\r
670                 final GSS app = GSS.get();\r
671                 clearSelectedRows();\r
672                 clearLabels();\r
673                 startIndex = 0;\r
674                 app.showLoadingIndicator();\r
675                 if (query == null || query.trim().equals("")) {\r
676                         searchResults.setHTML("You must specify a query");\r
677                         setFiles(new ArrayList());\r
678                         update(true);\r
679                         app.hideLoadingIndicator();\r
680                 } else{\r
681                         searchResults.setHTML("Search results for " + query);\r
682 \r
683                         GetCommand<SearchResource> eg = new GetCommand<SearchResource>(SearchResource.class,\r
684                                                 app.getApiPath() + "search/" + URL.encodeComponent(query), null) {\r
685 \r
686                                 @Override\r
687                                 public void onComplete() {\r
688                                         SearchResource s = getResult();\r
689                                         setFiles(s.getFiles());\r
690                                         update(true);\r
691                                 }\r
692 \r
693                                 @Override\r
694                                 public void onError(Throwable t) {\r
695                                         if(t instanceof RestException)\r
696                                                 app.displayError("Unable to perform search:"+((RestException)t).getHttpStatusText());\r
697                                         else\r
698                                                 app.displayError("System error performing search:"+t.getMessage());\r
699                                         updateFileCache("");\r
700                                 }\r
701 \r
702                         };\r
703                         DeferredCommand.addCommand(eg);\r
704                 }\r
705         }\r
706 \r
707         /**\r
708          * Fill the file cache with data.\r
709          *\r
710          * @param _files\r
711          * @param filePaths the files to set\r
712          */\r
713         private void setFiles(List<FileResource> _files) {\r
714                 files = _files;\r
715                 Collections.sort(files, new Comparator<FileResource>() {\r
716 \r
717                         public int compare(FileResource arg0, FileResource arg1) {\r
718                                 return arg0.getName().compareTo(arg1.getName());\r
719                         }\r
720 \r
721                 });\r
722                 folderFileCount = files.size();\r
723                 GWT.log("File count:" + folderFileCount, null);\r
724         }\r
725 \r
726         private void sortFiles(final String sortProperty) {\r
727                 if (sortProperty.equals(sortingProperty))\r
728                         sortingType = !sortingType;\r
729                 else {\r
730                         sortingProperty = sortProperty;\r
731                         sortingType = true;\r
732                 }\r
733                 update(true);\r
734         }\r
735 \r
736         private void clearLabels() {\r
737                 nameLabel.setText("Name");\r
738                 versionLabel.setText("Version");\r
739                 sizeLabel.setText("Size");\r
740                 dateLabel.setText("Last modified");\r
741                 ownerLabel.setText("Owner");\r
742                 pathLabel.setText("Path");\r
743         }\r
744 \r
745         /**\r
746          * Retrieve the table.\r
747          *\r
748          * @return the table\r
749          */\r
750         Grid getTable() {\r
751                 return table;\r
752         }\r
753 \r
754         /**\r
755          * Does the list contains the requested filename\r
756          *\r
757          * @param fileName\r
758          * @return true/false\r
759          */\r
760         public boolean contains(String fileName) {\r
761                 for (int i = 0; i < files.size(); i++)\r
762                         if (files.get(i).getName().equals(fileName))\r
763                                 return true;\r
764                 return false;\r
765         }\r
766 \r
767         public void clearSelectedRows() {\r
768                 for (int r : selectedRows) {\r
769                         int row = r - startIndex;\r
770                         styleRow(row, false);\r
771                         table.setWidget(row + 1, 0, AbstractImagePrototype.create(images.document()).createImage());\r
772                 }\r
773                 selectedRows.clear();\r
774                 Object sel = GSS.get().getCurrentSelection();\r
775                 if (sel instanceof FileResource || sel instanceof List)\r
776                         GSS.get().setCurrentSelection(null);\r
777         }\r
778 \r
779         public static native void preventIESelection() /*-{\r
780              $doc.body.onselectstart = function () { return false; };\r
781          }-*/;\r
782 \r
783         public static native void enableIESelection() /*-{\r
784          if ($doc.body.onselectstart != null)\r
785              $doc.body.onselectstart = null;\r
786          }-*/;\r
787 \r
788         public void selectAllRows() {\r
789                 clearSelectedRows();\r
790                 int count = folderFileCount;\r
791                 if (count == 0)\r
792                         return;\r
793                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;\r
794                 if (max > count)\r
795                         max = count;\r
796                 int i = 1;\r
797                 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {\r
798                         // Don't read past the end.\r
799                         // if (i > folderFileCount)\r
800                         // break;\r
801                         if (startIndex + i > folderFileCount)\r
802                                 break;\r
803                         selectedRows.add(startIndex + i - 1);\r
804                         styleRow(i - 1, true);\r
805                 }\r
806                 GSS.get().setCurrentSelection(getSelectedFiles());\r
807                 //contextMenu.setFiles(getSelectedFiles());\r
808                 table.setWidget(i - 1, 0, contextMenu);\r
809         }\r
810 \r
811 }\r