2 * Copyright (c) 2011 Greek Research and Technology Network
4 package gr.grnet.pithos.web.client;
7 import static com.google.gwt.query.client.GQuery.$;
9 import gr.grnet.pithos.web.client.rest.GetCommand;
10 import gr.grnet.pithos.web.client.rest.RestCommand;
11 import gr.grnet.pithos.web.client.rest.RestException;
12 import gr.grnet.pithos.web.client.rest.resource.FileResource;
13 import gr.grnet.pithos.web.client.rest.resource.SearchResource;
14 import gr.grnet.pithos.web.client.rest.resource.TrashResource;
15 import gr.grnet.pithos.web.client.rest.resource.UserResource;
16 import gr.grnet.pithos.web.client.rest.resource.UserSearchResource;
17 import gwtquery.plugins.draggable.client.DraggableOptions;
18 import gwtquery.plugins.draggable.client.StopDragException;
19 import gwtquery.plugins.draggable.client.DraggableOptions.DragFunction;
20 import gwtquery.plugins.draggable.client.DraggableOptions.RevertOption;
21 import gwtquery.plugins.draggable.client.events.DragContext;
22 import gwtquery.plugins.draggable.client.events.DragStartEvent;
23 import gwtquery.plugins.draggable.client.events.DragStopEvent;
24 import gwtquery.plugins.draggable.client.events.DragStartEvent.DragStartEventHandler;
25 import gwtquery.plugins.draggable.client.events.DragStopEvent.DragStopEventHandler;
26 import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTable;
27 import gwtquery.plugins.droppable.client.gwt.DragAndDropColumn;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.Comparator;
32 import java.util.Iterator;
33 import java.util.List;
35 import com.google.gwt.cell.client.AbstractCell;
36 import com.google.gwt.cell.client.ImageResourceCell;
37 import com.google.gwt.cell.client.SafeHtmlCell;
38 import com.google.gwt.cell.client.TextCell;
39 import com.google.gwt.core.client.GWT;
40 import com.google.gwt.core.client.Scheduler;
41 import com.google.gwt.core.client.Scheduler.RepeatingCommand;
42 import com.google.gwt.dom.client.Style.Cursor;
43 import com.google.gwt.http.client.URL;
44 import com.google.gwt.i18n.client.DateTimeFormat;
45 import com.google.gwt.resources.client.ClientBundle;
46 import com.google.gwt.resources.client.ImageResource;
47 import com.google.gwt.safehtml.shared.SafeHtml;
48 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
49 import com.google.gwt.user.cellview.client.CellTable;
50 import com.google.gwt.user.cellview.client.GssSimplePager;
51 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
52 import com.google.gwt.user.client.DOM;
53 import com.google.gwt.user.client.DeferredCommand;
54 import com.google.gwt.user.client.Event;
55 import com.google.gwt.user.client.Window;
56 import com.google.gwt.user.client.ui.AbstractImagePrototype;
57 import com.google.gwt.user.client.ui.Composite;
58 import com.google.gwt.user.client.ui.HTML;
59 import com.google.gwt.user.client.ui.VerticalPanel;
60 import com.google.gwt.view.client.AsyncDataProvider;
61 import com.google.gwt.view.client.HasData;
62 import com.google.gwt.view.client.MultiSelectionModel;
63 import com.google.gwt.view.client.ProvidesKey;
64 import com.google.gwt.view.client.SelectionChangeEvent;
65 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
68 * A composite that displays a list of search results for a particular query on
71 public class SearchResults extends Composite{
72 private HTML searchResults = new HTML("Results for search:");
73 private String lastQuery;
74 SearchDataProvider provider = new SearchDataProvider();
76 * Specifies that the images available for this composite will be the ones
77 * available in FileContextMenu.
79 public interface Images extends ClientBundle,FileContextMenu.Images, CellTreeView.Images, FileList.Images {
81 @Source("gr/grnet/pithos/resources/blank.gif")
82 ImageResource blank();
84 @Source("gr/grnet/pithos/resources/asc.png")
87 @Source("gr/grnet/pithos/resources/desc.png")
92 interface TableResources extends DragAndDropCellTable.Resources {
93 @Source({CellTable.Style.DEFAULT_CSS, "GssCellTable.css"})
94 TableStyle cellTableStyle();
98 * The styles applied to the table.
100 interface TableStyle extends CellTable.Style {
103 private String showingStats = "";
105 private int startIndex = 0;
108 * A constant that denotes the completion of an IncrementalCommand.
110 public static final boolean DONE = false;
114 private final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
118 DragStopEventHandler dragStop = new DragStopEventHandler() {
121 public void onDragStop(DragStopEvent event) {
122 GWT.log("DRAG STOPPED");
127 private static class ContactCell extends AbstractCell<gr.grnet.pithos.web.client.rest.resource.FileResource> {
130 * The html of the image used for contacts.
133 private final String imageHtml;
135 public ContactCell(ImageResource image) {
136 this.imageHtml = AbstractImagePrototype.create(image).getHTML();
144 public void render(Context context, FileResource value, SafeHtmlBuilder sb) {
145 // Value can be null, so do a null check..
150 sb.append(FileList.Templates.INSTANCE.rendelContactCell(imageHtml, value.getName(), value.getFileSizeAsString()));
156 * Retrieve the celltable.
158 * @return the celltable
160 public DragAndDropCellTable<FileResource> getCelltable() {
167 * The number of files in this folder.
174 long folderTotalSize;
177 * A cache of the files in the list.
179 private List<FileResource> files;
182 * The widget's image bundle.
184 private final Images images;
186 private FileContextMenu menuShowing;
187 private DragAndDropCellTable<FileResource> celltable;
188 private final MultiSelectionModel<FileResource> selectionModel;
190 GssSimplePager pager;
191 GssSimplePager pagerTop;
193 * Construct the file list widget. This entails setting up the widget
194 * layout, fetching the number of files in the current folder from the
195 * server and filling the local file cache of displayed files with data from
196 * the server, as well.
200 public SearchResults(Images _images) {
202 DragAndDropCellTable.Resources resources = GWT.create(TableResources.class);
203 ProvidesKey<FileResource> keyProvider = new ProvidesKey<FileResource>(){
206 public Object getKey(FileResource item) {
207 return item.getUri();
212 celltable = new DragAndDropCellTable<FileResource>(GSS.VISIBLE_FILE_COUNT,resources,keyProvider){
214 protected void onBrowserEvent2(Event event) {
215 /*if (DOM.eventGetType((Event) event) == Event.ONMOUSEDOWN && DOM.eventGetButton((Event) event) == NativeEvent.BUTTON_RIGHT){
216 fireClickEvent((Element) event.getEventTarget().cast());
218 super.onBrowserEvent2(event);
221 provider.addDataDisplay(celltable);
222 celltable.addDragStopHandler(dragStop);
223 celltable.addDragStartHandler(new DragStartEventHandler() {
225 public void onDragStart(DragStartEvent event) {
226 FileResource value = event.getDraggableData();
228 com.google.gwt.dom.client.Element helper = event.getHelper();
229 SafeHtmlBuilder sb = new SafeHtmlBuilder();
230 sb.appendHtmlConstant("<b>");
231 DisplayHelper.log(value.getName());
232 if(getSelectedFiles().size()==1)
233 sb.appendEscaped(value.getName());
235 sb.appendEscaped(getSelectedFiles().size()+" files");
236 sb.appendHtmlConstant("</b>");
237 helper.setInnerHTML(sb.toSafeHtml().asString());
241 DragAndDropColumn<FileResource, ImageResource> status = new DragAndDropColumn<FileResource, ImageResource>(new ImageResourceCell(){
243 public boolean handlesSelection() {
248 public ImageResource getValue(FileResource entity) {
249 return getFileIcon(entity);
253 celltable.addColumn(status,"");
255 initDragOperation(status);
256 final DragAndDropColumn<FileResource,SafeHtml> nameColumn = new DragAndDropColumn<FileResource,SafeHtml>(new SafeHtmlCell()) {
260 public SafeHtml getValue(FileResource object) {
261 SafeHtmlBuilder sb = new SafeHtmlBuilder();
262 sb.append(FileList.Templates.INSTANCE.filenameSpan(object.getName()));
263 if (object.getContentType().endsWith("png") || object.getContentType().endsWith("gif") || object.getContentType().endsWith("jpeg") ){
264 sb.appendHtmlConstant(" ").append(FileList.Templates.INSTANCE.viewLink(GSS.get().getTopPanel().getFileMenu().getDownloadURL(object), object.getOwner() + " : " + object.getPath() + object.getName()));
267 return sb.toSafeHtml();
271 initDragOperation(nameColumn);
272 celltable.addColumn(nameColumn,"Name");
274 DragAndDropColumn<FileResource,String> aColumn;
275 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
277 public String getValue(FileResource object) {
278 return GSS.get().findUserFullName(object.getOwner());
281 initDragOperation(aColumn);
283 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
285 public String getValue(FileResource object) {
286 if(object.isDeleted())
287 return object.getPath()+" (In Trash)";
288 return object.getPath();
291 initDragOperation(aColumn);
295 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
297 public String getValue(FileResource object) {
298 return object.getVersion().toString();
301 initDragOperation(aColumn);
304 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
306 public String getValue(FileResource object) {
307 // TODO Auto-generated method stub
308 return object.getFileSizeAsString();
311 initDragOperation(aColumn);
313 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
315 public String getValue(FileResource object) {
316 return formatter.format(object.getModificationDate());
323 VerticalPanel vp = new VerticalPanel();
325 celltable.setWidth("100%");
326 vp.add(searchResults);
327 searchResults.addStyleName("pithos-searchLabel");
328 pagerTop = new GssSimplePager(GssSimplePager.TextLocation.CENTER);
329 pagerTop.setDisplay(celltable);
332 pager = new GssSimplePager(GssSimplePager.TextLocation.CENTER);
333 pager.setDisplay(celltable);
334 //celltable.setPageSize(2);
337 vp.setCellWidth(celltable, "100%");
341 //initWidget(celltable);
342 celltable.setStyleName("pithos-List");
343 selectionModel = new MultiSelectionModel<FileResource>();
346 Handler selectionHandler = new SelectionChangeEvent.Handler() {
348 public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
349 if(getSelectedFiles().size()==1)
350 GSS.get().setCurrentSelection(getSelectedFiles().get(0));
352 GSS.get().setCurrentSelection(getSelectedFiles());
353 //contextMenu.setFiles(getSelectedFiles());
356 selectionModel.addSelectionChangeHandler(selectionHandler);
358 celltable.setSelectionModel(selectionModel,GSSSelectionEventManager.<FileResource>createDefaultManager());
359 celltable.setPageSize(GSS.VISIBLE_FILE_COUNT);
360 celltable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
361 Scheduler.get().scheduleIncremental(new RepeatingCommand() {
364 public boolean execute() {
365 return fetchRootFolder();
368 sinkEvents(Event.ONCONTEXTMENU);
369 sinkEvents(Event.ONMOUSEUP);
370 sinkEvents(Event.ONMOUSEDOWN);
371 sinkEvents(Event.ONCLICK);
372 sinkEvents(Event.ONKEYDOWN);
373 sinkEvents(Event.ONDBLCLICK);
374 GSS.preventIESelection();
377 //public native void fireClickEvent(Element element) /*-{
378 // var evObj = $doc.createEvent('MouseEvents');
379 //evObj.initEvent('click', true, true);
380 //element.dispatchEvent(evObj);
383 public List<FileResource> getSelectedFiles() {
384 return new ArrayList<FileResource>(selectionModel.getSelectedSet());
387 private void initDragOperation(DragAndDropColumn<?, ?> column) {
389 // retrieve draggableOptions on the column
390 DraggableOptions draggableOptions = column.getDraggableOptions();
391 // use template to construct the helper. The content of the div will be set
393 draggableOptions.setHelper($(FileList.Templates.INSTANCE.outerHelper().asString()));
394 //draggableOptions.setZIndex(100);
395 // opacity of the helper
396 draggableOptions.setAppendTo("body");
397 //draggableOptions.setOpacity((float) 0.8);
398 draggableOptions.setContainment("document");
399 // cursor to use during the drag operation
400 draggableOptions.setCursor(Cursor.MOVE);
401 // set the revert option
402 draggableOptions.setRevert(RevertOption.ON_INVALID_DROP);
403 // prevents dragging when user click on the category drop-down list
404 draggableOptions.setCancel("select");
406 draggableOptions.setOnBeforeDragStart(new DragFunction() {
409 public void f(DragContext context) {
410 FileResource value = context.getDraggableData();
411 if(!selectionModel.isSelected(value)){
412 throw new StopDragException();
419 public void showContextMenu(Event event){
420 menuShowing = new FileContextMenu(images, false, true);
421 menuShowing=menuShowing.onEmptyEvent(event);
424 public void onBrowserEvent(Event event) {
426 if (files == null || files.size() == 0) {
427 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
428 menuShowing = new FileContextMenu(images, false, true);
429 menuShowing=menuShowing.onEmptyEvent(event);
430 event.preventDefault();
431 event.cancelBubble(true);
435 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() != 0) {
436 GWT.log("*****GOING TO SHOW CONTEXT MENU ****", null);
437 menuShowing = new FileContextMenu(images, false, false);
438 menuShowing=menuShowing.onEvent(event);
439 event.cancelBubble(true);
440 event.preventDefault();
441 } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
442 menuShowing = new FileContextMenu(images, false, true);
443 menuShowing=menuShowing.onEmptyEvent(event);
444 event.cancelBubble(true);
445 event.preventDefault();
446 } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
447 if (getSelectedFiles().size() == 1) {
449 FileResource file = getSelectedFiles().get(0);
450 String dateString = RestCommand.getDate();
451 String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());
452 String sig = app.getCurrentUserResource().getUsername() + " " +
453 RestCommand.calculateSig("GET", dateString, resource,
454 RestCommand.base64decode(app.getToken()));
455 if(!file.isDeleted()){
456 Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");
458 event.preventDefault();
461 super.onBrowserEvent(event);
465 * Retrieve the root folder for the current user.
467 * @return true if the retrieval was successful
469 protected boolean fetchRootFolder() {
470 UserResource user = GSS.get().getCurrentUserResource();
473 // Update cache and clear selection.
474 updateFileCache(null);
480 * Update the display of the file list.
482 void update(boolean sort) {
483 int count = folderFileCount;
484 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
489 copyListAndContinue(files);
490 for(FileResource f : files){
491 folderTotalSize += f.getContentLength();
493 if (folderFileCount == 0) {
494 showingStats = "no files";
495 } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
496 if (folderFileCount == 1)
497 showingStats = "1 file";
499 showingStats = folderFileCount + " files";
500 showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
502 showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
504 updateCurrentlyShowingStats();
509 * Return the proper icon based on the MIME type of the file.
514 private ImageResource getFileIcon(FileResource file) {
515 String mimetype = file.getContentType();
516 boolean shared = file.isShared();
517 if (mimetype == null)
518 return shared ? images.documentShared() : images.document();
519 mimetype = mimetype.toLowerCase();
520 if (mimetype.startsWith("application/pdf"))
521 return shared ? images.pdfShared() : images.pdf();
522 else if (mimetype.endsWith("excel"))
523 return shared ? images.spreadsheetShared() : images.spreadsheet();
524 else if (mimetype.endsWith("msword"))
525 return shared ? images.wordprocessorShared() : images.wordprocessor();
526 else if (mimetype.endsWith("powerpoint"))
527 return shared ? images.presentationShared() : images.presentation();
528 else if (mimetype.startsWith("application/zip") ||
529 mimetype.startsWith("application/gzip") ||
530 mimetype.startsWith("application/x-gzip") ||
531 mimetype.startsWith("application/x-tar") ||
532 mimetype.startsWith("application/x-gtar"))
533 return shared ? images.zipShared() : images.zip();
534 else if (mimetype.startsWith("text/html"))
535 return shared ? images.htmlShared() : images.html();
536 else if (mimetype.startsWith("text/plain"))
537 return shared ? images.txtShared() : images.txt();
538 else if (mimetype.startsWith("image/"))
539 return shared ? images.imageShared() : images.image();
540 else if (mimetype.startsWith("video/"))
541 return shared ? images.videoShared() : images.video();
542 else if (mimetype.startsWith("audio/"))
543 return shared ? images.audioShared() : images.audio();
544 return shared ? images.documentShared() : images.document();
548 * Update status panel with currently showing file stats.
550 public void updateCurrentlyShowingStats() {
551 GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
554 public void updateFileCache(String query) {
555 final GSS app = GSS.get();
560 app.showLoadingIndicator("Getting Search Results",null);
561 if (query == null || query.trim().equals("")) {
562 searchResults.setHTML("You must specify a query.");
563 setFiles(new ArrayList());
565 app.hideLoadingIndicator();
566 } else if (!GSS.isValidResourceName(query)) {
567 searchResults.setHTML("The query was invalid. Try to use words that appear in the file's name, contents or tags.");
568 setFiles(new ArrayList());
570 app.hideLoadingIndicator();
572 searchResults.setHTML("Search results for " + query);
579 * Fill the file cache with data.
581 public void setFiles(final List<FileResource> _files) {
582 if (_files.size() > 0 && ! (GSS.get().getTreeView().getSelection() instanceof TrashResource)) {
583 files = new ArrayList<FileResource>();
584 for (FileResource fres : _files)
589 Collections.sort(files, new Comparator<FileResource>() {
592 public int compare(FileResource arg0, FileResource arg1) {
593 return arg0.getName().compareTo(arg1.getName());
597 folderFileCount = files.size();
604 * Does the list contains the requested filename
609 public boolean contains(String fileName) {
610 for (int i = 0; i < files.size(); i++)
611 if (files.get(i).getName().equals(fileName))
616 public void clearSelectedRows() {
617 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
619 selectionModel.setSelected(it.next(),false);
626 public void selectAllRows() {
627 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
629 selectionModel.setSelected(it.next(),true);
636 private void sortFiles(final String sortingProperty, final boolean sortingType){
637 Collections.sort(files, new Comparator<FileResource>() {
640 public int compare(FileResource arg0, FileResource arg1) {
641 AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
642 AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
644 if (sortingProperty.equals("version")) {
645 return arg0.getVersion().compareTo(arg1.getVersion());
646 } else if (sortingProperty.equals("owner")) {
647 return arg0.getOwner().compareTo(arg1.getOwner());
648 } else if (sortingProperty.equals("date")) {
649 return arg0.getModificationDate().compareTo(arg1.getModificationDate());
650 } else if (sortingProperty.equals("size")) {
651 return arg0.getContentLength().compareTo(arg1.getContentLength());
652 } else if (sortingProperty.equals("name")) {
653 return arg0.getName().compareTo(arg1.getName());
654 } else if (sortingProperty.equals("path")) {
655 return arg0.getUri().compareTo(arg1.getUri());
657 return arg0.getName().compareTo(arg1.getName());
660 else if (sortingProperty.equals("version")) {
662 return arg1.getVersion().compareTo(arg0.getVersion());
663 } else if (sortingProperty.equals("owner")) {
665 return arg1.getOwner().compareTo(arg0.getOwner());
666 } else if (sortingProperty.equals("date")) {
668 return arg1.getModificationDate().compareTo(arg0.getModificationDate());
669 } else if (sortingProperty.equals("size")) {
671 return arg1.getContentLength().compareTo(arg0.getContentLength());
672 } else if (sortingProperty.equals("name")) {
674 return arg1.getName().compareTo(arg0.getName());
675 } else if (sortingProperty.equals("path")) {
677 return arg1.getUri().compareTo(arg0.getUri());
680 return arg1.getName().compareTo(arg0.getName());
689 * Creates a new ArrayList<FileResources> from the given files ArrayList
690 * in order that the input files remain untouched
691 * and continues to find user's full names of each FileResource element
692 * in the new ArrayList
696 private void copyListAndContinue(List<FileResource> filesInput){
697 List<FileResource> copiedFiles = new ArrayList<FileResource>();
698 for(FileResource file : filesInput) {
699 copiedFiles.add(file);
701 handleFullNames(copiedFiles);
705 * Examines whether or not the user's full name exists in the
706 * userFullNameMap in the GSS.java for every element of the input list.
707 * If the user's full name does not exist in the map then a command is being made.
711 private void handleFullNames(List<FileResource> filesInput){
712 if(filesInput.size() == 0){
713 showCellTable(false);
717 if(GSS.get().findUserFullName(filesInput.get(0).getOwner()) == null){
718 findFullNameAndUpdate(filesInput);
722 if(filesInput.size() >= 1){
723 filesInput.remove(filesInput.get(0));
724 if(filesInput.isEmpty()){
725 showCellTable(false);
727 handleFullNames(filesInput);
733 * Makes a command to search for full name from a given username.
734 * Only after the completion of the command the celltable is shown
735 * or the search for the next full name continues.
739 private void findFullNameAndUpdate(final List<FileResource> filesInput){
740 String aUserName = filesInput.get(0).getOwner();
741 String path = GSS.get().getApiPath() + "users/" + aUserName;
743 GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class, path, false,null) {
745 public void onComplete() {
746 final UserSearchResource result = getResult();
747 for (UserResource user : result.getUsers()){
748 String username = user.getUsername();
749 String userFullName = user.getName();
750 GSS.get().putUserToMap(username, userFullName);
751 if(filesInput.size() >= 1){
752 filesInput.remove(filesInput.get(0));
753 if(filesInput.isEmpty()){
754 showCellTable(false);
756 handleFullNames(filesInput);
762 public void onError(Throwable t) {
764 GSS.get().displayError("Unable to fetch user's full name from the given username " + filesInput.get(0).getOwner());
765 if(filesInput.size() >= 1){
766 filesInput.remove(filesInput.get(0));
767 handleFullNames(filesInput);
771 DeferredCommand.addCommand(gg);
775 * Shows the files in the cellTable
778 private void showCellTable(boolean update){
779 if(celltable.getRowCount()>GSS.VISIBLE_FILE_COUNT){
780 pager.setVisible(true);
781 pagerTop.setVisible(true);
784 pager.setVisible(false);
785 pagerTop.setVisible(false);
788 provider.onRangeChanged(celltable);
789 celltable.redrawHeaders();
794 * Retrieve the lastQuery.
796 * @return the lastQuery
798 public String getLastQuery() {
804 * Modify the lastQuery.
806 * @param lastQuery the lastQuery to set
808 public void setLastQuery(String lastQuery) {
809 this.lastQuery = lastQuery;
812 class SearchDataProvider extends AsyncDataProvider<FileResource>{
815 protected void onRangeChanged(final HasData<FileResource> display) {
816 final int start = display.getVisibleRange().getStart();
817 final GSS app = GSS.get();
818 if(getLastQuery()==null||getLastQuery().equals("")){
819 display.setRowCount(0,true);
823 GetCommand<SearchResource> eg = new GetCommand<SearchResource>(SearchResource.class,
824 app.getApiPath() + "search/" +URL.encodeComponent(getLastQuery())+"?start="+start, null) {
827 public void onComplete() {
828 SearchResource s = getResult();
829 display.setRowCount(s.getSize(),true);
830 display.setRowData(start, s.getFiles());
831 setFiles(s.getFiles());
837 public void onError(Throwable t) {
838 if(t instanceof RestException)
839 app.displayError("Unable to perform search:"+((RestException)t).getHttpStatusText());
841 app.displayError("System error performing search:"+t.getMessage());
847 DeferredCommand.addCommand(eg);