sorting support for celltable
authorkoutsoub <devnull@localhost>
Fri, 14 Jan 2011 11:39:58 +0000 (13:39 +0200)
committerkoutsoub <devnull@localhost>
Fri, 14 Jan 2011 11:39:58 +0000 (13:39 +0200)
src/gr/ebs/gss/client/FileList.java
src/gr/ebs/gss/client/SortableHeader.java [new file with mode: 0644]
src/gr/ebs/gss/client/downArrow.png [new file with mode: 0644]
src/gr/ebs/gss/client/upArrow.png [new file with mode: 0644]

index 8c0fb79..c525b72 100644 (file)
@@ -17,6 +17,7 @@
  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
  */
 package gr.ebs.gss.client;
+
 import gr.ebs.gss.client.dnd.DnDSimpleFocusPanel;
 import gr.ebs.gss.client.dnd.DnDTreeItem;
 import gr.ebs.gss.client.rest.GetCommand;
@@ -37,14 +38,12 @@ import java.util.Iterator;
 import java.util.List;
 
 import com.google.gwt.cell.client.ImageResourceCell;
-import com.google.gwt.cell.client.Cell.Context;
+import com.google.gwt.cell.client.ValueUpdater;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.Scheduler;
 import com.google.gwt.core.client.Scheduler.RepeatingCommand;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.NativeEvent;
-import com.google.gwt.dom.client.TableCellElement;
-import com.google.gwt.dom.client.TableRowElement;
 import com.google.gwt.http.client.URL;
 import com.google.gwt.i18n.client.DateTimeFormat;
 import com.google.gwt.resources.client.ClientBundle;
@@ -212,7 +211,8 @@ public class FileList extends Composite {
        private FileContextMenu menuShowing;
        private CellTable<FileResource> celltable;
        private final MultiSelectionModel<FileResource> selectionModel;
-        
+       private final List<SortableHeader> allHeaders = new ArrayList<SortableHeader>();
+       SortableHeader nameHeader;
        /**
         * Construct the file list widget. This entails setting up the widget
         * layout, fetching the number of files in the current folder from the
@@ -276,42 +276,58 @@ public class FileList extends Composite {
               };
               celltable.addColumn(status,"");
                
-                       
-               celltable.addColumn(nameColumn,"Name");
+               
+               celltable.addColumn(nameColumn,nameHeader = new SortableHeader("Name"));
+               allHeaders.add(nameHeader);
+               nameHeader.setSorted(true);
+               nameHeader.toggleReverseSort();
+               nameHeader.setUpdater(new FileValueUpdater(nameHeader, "name"));
+               celltable.redrawHeaders();
+               SortableHeader aheader;
                celltable.addColumn(new TextColumn<FileResource>() {
                        @Override
                        public String getValue(FileResource object) {
                                // TODO Auto-generated method stub
                                return object.getOwner();
                        }                       
-               },"Owner");     
+               },aheader = new SortableHeader("Owner"));
+               allHeaders.add(aheader);
+               aheader.setUpdater(new FileValueUpdater(aheader, "owner"));
                celltable.addColumn(new TextColumn<FileResource>() {
                        @Override
                        public String getValue(FileResource object) {
                                // TODO Auto-generated method stub
                                return object.getPath();
                        }                       
-               },"Path");      
+               },aheader = new SortableHeader("Path"));
+               allHeaders.add(aheader);
+               aheader.setUpdater(new FileValueUpdater(aheader, "path"));      
                celltable.addColumn(new TextColumn<FileResource>() {
                        @Override
                        public String getValue(FileResource object) {
                                // TODO Auto-generated method stub
                                return object.getVersion().toString();
                        }                       
-               },"Version");   
+               },aheader = new SortableHeader("Version"));
+               allHeaders.add(aheader);
+               aheader.setUpdater(new FileValueUpdater(aheader, "version"));
                celltable.addColumn(new TextColumn<FileResource>() {
                        @Override
                        public String getValue(FileResource object) {
                                // TODO Auto-generated method stub
                                return object.getFileSizeAsString();
                        }                       
-               },"Size");      
+               },aheader = new SortableHeader("Size"));
+               allHeaders.add(aheader);
+               aheader.setUpdater(new FileValueUpdater(aheader, "size"));      
                celltable.addColumn(new TextColumn<FileResource>() {
                        @Override
                        public String getValue(FileResource object) {
                                return formatter.format(object.getModificationDate());
                        }                       
-               },"Last Modified");     
+               },aheader = new SortableHeader("Last Modified"));
+               allHeaders.add(aheader);
+               aheader.setUpdater(new FileValueUpdater(aheader, "date"));
                initWidget(celltable);
                setStyleName("gss-List");
                selectionModel = new MultiSelectionModel<FileResource>();
@@ -348,10 +364,10 @@ public class FileList extends Composite {
                GSS.preventIESelection();
        }
        public native void fireClickEvent(Element element) /*-{
-    var evObj = $doc.createEvent('MouseEvents');
-    evObj.initEvent('click', true, true);
-    element.dispatchEvent(evObj);
-  }-*/;
+           var evObj = $doc.createEvent('MouseEvents');
+           evObj.initEvent('click', true, true);
+           element.dispatchEvent(evObj);
+       }-*/;
 
         public List<FileResource> getSelectedFiles() {
          return new ArrayList<FileResource>(selectionModel.getSelectedSet());
@@ -429,9 +445,10 @@ public class FileList extends Composite {
                if (max > count)
                        max = count;
                folderTotalSize = 0;
-
+               
                celltable.setRowCount(files.size());
                celltable.setRowData(0,files);
+               celltable.redrawHeaders();
                if (folderFileCount == 0) {
                        showingStats = "no files";
                } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
@@ -838,5 +855,82 @@ public class FileList extends Composite {
        }
        
        
+       private void sortFiles(final String sortingProperty, final boolean sortingType){
+               Collections.sort(files, new Comparator<FileResource>() {
 
+            @Override
+            public int compare(FileResource arg0, FileResource arg1) {
+                    AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
+                    AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
+                    if (sortingType){
+                            if (sortingProperty.equals("version")) {
+                                    return arg0.getVersion().compareTo(arg1.getVersion());
+                            } else if (sortingProperty.equals("owner")) {
+                                    return arg0.getOwner().compareTo(arg1.getOwner());
+                            } else if (sortingProperty.equals("date")) {
+                                    return arg0.getModificationDate().compareTo(arg1.getModificationDate());
+                            } else if (sortingProperty.equals("size")) {
+                                    return arg0.getContentLength().compareTo(arg1.getContentLength());
+                            } else if (sortingProperty.equals("name")) {
+                                    return arg0.getName().compareTo(arg1.getName());
+                            } else if (sortingProperty.equals("path")) {
+                                    return arg0.getUri().compareTo(arg1.getUri());
+                            } else {
+                                    return arg0.getName().compareTo(arg1.getName());
+                            }
+                    }
+                    else if (sortingProperty.equals("version")) {
+                            
+                            return arg1.getVersion().compareTo(arg0.getVersion());
+                    } else if (sortingProperty.equals("owner")) {
+                            
+                            return arg1.getOwner().compareTo(arg0.getOwner());
+                    } else if (sortingProperty.equals("date")) {
+                            
+                            return arg1.getModificationDate().compareTo(arg0.getModificationDate());
+                    } else if (sortingProperty.equals("size")) {
+                            
+                            return arg1.getContentLength().compareTo(arg0.getContentLength());
+                    } else if (sortingProperty.equals("name")) {
+                            
+                            return arg1.getName().compareTo(arg0.getName());
+                    } else if (sortingProperty.equals("path")) {
+                            
+                            return arg1.getUri().compareTo(arg0.getUri());
+                    } else {
+                            
+                            return arg1.getName().compareTo(arg0.getName());
+                    }
+            }
+
+               });
+       }
+       
+       final class FileValueUpdater implements ValueUpdater<String>{
+               private String property;
+               private SortableHeader header;
+               /**
+                * 
+                */
+               public FileValueUpdater(SortableHeader header,String property) {
+                       this.property=property;
+                       this.header=header;
+               }
+               @Override
+               public void update(String value) {
+                       header.setSorted(true);
+                       header.toggleReverseSort();
+
+               for (SortableHeader otherHeader : allHeaders) {
+                 if (otherHeader != header) {
+                   otherHeader.setSorted(false);
+                   otherHeader.setReverseSort(true);
+                 }
+               }
+               celltable.redrawHeaders();
+               sortFiles(property, header.getReverseSort());
+               FileList.this.update(true);                     
+               }
+               
+       }
 }
diff --git a/src/gr/ebs/gss/client/SortableHeader.java b/src/gr/ebs/gss/client/SortableHeader.java
new file mode 100644 (file)
index 0000000..b119e40
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package gr.ebs.gss.client;
+
+import com.google.gwt.cell.client.Cell.Context;
+import com.google.gwt.cell.client.ClickableTextCell;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.safehtml.client.SafeHtmlTemplates;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+import com.google.gwt.safehtml.shared.SafeHtmlUtils;
+import com.google.gwt.user.cellview.client.Header;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+
+/**
+ * A {@link Header} subclass that maintains sorting state and displays an icon
+ * to indicate the sort direction.
+ */
+public class SortableHeader extends Header<String> {
+
+  interface Template extends SafeHtmlTemplates {
+    @Template("<div style=\"position:relative;cursor:hand;cursor:pointer;"
+        + "padding-right:{0}px;\">{1}<div>{2}</div></div>")
+    SafeHtml sorted(int imageWidth, SafeHtml arrow, String text);
+
+    @Template("<div style=\"position:relative;cursor:hand;cursor:pointer;"
+        + "padding-right:{0}px;\"><div style=\"position:absolute;display:none;"
+        + "\"></div><div>{1}</div></div>")
+    SafeHtml unsorted(int imageWidth, String text);
+  }
+
+  private static Template template;
+
+  /**
+   * Image resources.
+   */
+  public static interface Resources extends ClientBundle {
+
+    ImageResource downArrow();
+
+    ImageResource upArrow();
+  }
+
+  private static final Resources RESOURCES = GWT.create(Resources.class);
+  private static final int IMAGE_WIDTH = 16;
+  private static final SafeHtml DOWN_ARROW = makeImage(RESOURCES.downArrow());
+  private static final SafeHtml UP_ARROW = makeImage(RESOURCES.upArrow());
+
+  private static SafeHtml makeImage(ImageResource resource) {
+    AbstractImagePrototype proto = AbstractImagePrototype.create(resource);
+    String html = proto.getHTML().replace("style='",
+        "style='position:absolute;right:0px;top:0px;");
+    return SafeHtmlUtils.fromTrustedString(html);
+  }
+
+  private boolean reverseSort = false;
+  private boolean sorted = false;
+  private String text;
+
+  SortableHeader(String text) {
+    super(new ClickableTextCell());
+    if (template == null) {
+      template = GWT.create(Template.class);
+    }
+    this.text = text;
+  }
+
+  public boolean getReverseSort() {
+    return reverseSort;
+  }
+
+  @Override
+  public String getValue() {
+    return text;
+  }
+
+  @Override
+  public void render(Context context, SafeHtmlBuilder sb) {
+    if (sorted) {
+      sb.append(template.sorted(IMAGE_WIDTH, reverseSort ? DOWN_ARROW : UP_ARROW, text));
+    } else {
+      sb.append(template.unsorted(IMAGE_WIDTH, text));
+    }
+  }
+
+  public void setReverseSort(boolean reverseSort) {
+    this.reverseSort = reverseSort;
+  }
+
+  public void setSorted(boolean sorted) {
+    this.sorted = sorted;
+  }
+
+  public void toggleReverseSort() {
+    this.reverseSort = !this.reverseSort;
+  }
+}
diff --git a/src/gr/ebs/gss/client/downArrow.png b/src/gr/ebs/gss/client/downArrow.png
new file mode 100644 (file)
index 0000000..fd4012c
Binary files /dev/null and b/src/gr/ebs/gss/client/downArrow.png differ
diff --git a/src/gr/ebs/gss/client/upArrow.png b/src/gr/ebs/gss/client/upArrow.png
new file mode 100644 (file)
index 0000000..a336947
Binary files /dev/null and b/src/gr/ebs/gss/client/upArrow.png differ