You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/08/18 23:42:07 UTC

svn commit: r805593 - in /incubator/pivot/trunk: core/src/org/apache/pivot/collections/ core/src/org/apache/pivot/io/ wtk/src/org/apache/pivot/wtk/ wtk/src/org/apache/pivot/wtk/skin/terra/ wtk/test/org/apache/pivot/wtk/test/

Author: gbrown
Date: Tue Aug 18 21:42:06 2009
New Revision: 805593

URL: http://svn.apache.org/viewvc?rev=805593&view=rev
Log:
Finish file browser/sheet implementation.

Modified:
    incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredList.java
    incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredListListener.java
    incubator/pivot/trunk/core/src/org/apache/pivot/io/Folder.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.wtkx
    incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/FileBrowserSheetTest.java

Modified: incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredList.java?rev=805593&r1=805592&r2=805593&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredList.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredList.java Tue Aug 18 21:42:06 2009
@@ -47,6 +47,7 @@
 
     private List<T> source = null;
     private Filter<T> filter = null;
+    private Comparator<T> comparator = null;
 
     private ArrayList<T> view = null;
 
@@ -179,15 +180,11 @@
                 listListeners.listCleared(this);
             }
 
-            // Attach/detach list listeners
+            // Stop listening for changes
             if (previousSource != null) {
                 previousSource.getListListeners().remove(listListener);
             }
 
-            if (source != null) {
-                source.getListListeners().add(listListener);
-            }
-
             // Update source
             this.source = source;
             filteredListListeners.sourceChanged(this, previousSource);
@@ -205,6 +202,14 @@
                         listListeners.itemInserted(this, index);
                     }
                 }
+
+                // Re-apply comparator
+                view.setComparator(comparator);
+            }
+
+            // Listen for changes
+            if (source != null) {
+                source.getListListeners().add(listListener);
             }
         }
     }
@@ -462,18 +467,20 @@
 
     @Override
     public Comparator<T> getComparator() {
-        return (view == null) ? null : view.getComparator();
+        return comparator;
     }
 
     @Override
     public void setComparator(Comparator<T> comparator) {
-        if (view == null) {
-            throw new IllegalStateException();
-        }
-
         Comparator<T> previousComparator = view.getComparator();
+
         if (previousComparator != comparator) {
-            view.setComparator(comparator);
+            this.comparator = comparator;
+
+            if (view != null) {
+                view.setComparator(comparator);
+            }
+
             listListeners.comparatorChanged(this, previousComparator);
         }
     }

Modified: incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredListListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredListListener.java?rev=805593&r1=805592&r2=805593&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredListListener.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/collections/FilteredListListener.java Tue Aug 18 21:42:06 2009
@@ -23,6 +23,19 @@
  */
 public interface FilteredListListener<T> {
     /**
+     * Filtered list listener adapter.
+     *
+     * @param <T>
+     */
+    public static class Adapter<T> implements FilteredListListener<T> {
+        public void sourceChanged(FilteredList<T> filteredList, List<T> previousSource) {
+        }
+
+        public void filterChanged(FilteredList<T> filteredList, Filter<T> previousFilter) {
+        }
+    }
+
+    /**
      * Called when a filtered list's source has changed.
      *
      * @param filteredList

Modified: incubator/pivot/trunk/core/src/org/apache/pivot/io/Folder.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/io/Folder.java?rev=805593&r1=805592&r2=805593&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/io/Folder.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/io/Folder.java Tue Aug 18 21:42:06 2009
@@ -251,6 +251,10 @@
     }
 
     public Iterator<File> iterator() {
+        if (files == null) {
+            refresh();
+        }
+
         return new ImmutableIterator<File>(files.iterator());
     }
 

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java?rev=805593&r1=805592&r2=805593&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java Tue Aug 18 21:42:06 2009
@@ -471,7 +471,7 @@
      * <p>
      * TODO Allow a caller to sort on multiple columns.
      */
-    public static final class RowComparator implements Comparator<Object> {
+    public static class RowComparator implements Comparator<Object> {
         private String columnName = null;
         private SortDirection sortDirection = null;
 

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java?rev=805593&r1=805592&r2=805593&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraFileBrowserSkin.java Tue Aug 18 21:42:06 2009
@@ -21,10 +21,14 @@
 import java.io.File;
 import java.io.IOException;
 import java.text.DateFormat;
+import java.util.Comparator;
 import java.util.Date;
 
 import org.apache.pivot.collections.ArrayList;
+import org.apache.pivot.collections.FilteredList;
+import org.apache.pivot.collections.FilteredListListener;
 import org.apache.pivot.collections.List;
+import org.apache.pivot.collections.ListListener;
 import org.apache.pivot.collections.Sequence;
 import org.apache.pivot.io.Folder;
 import org.apache.pivot.serialization.SerializationException;
@@ -36,12 +40,14 @@
 import org.apache.pivot.wtk.Button;
 import org.apache.pivot.wtk.ButtonPressListener;
 import org.apache.pivot.wtk.Component;
+import org.apache.pivot.wtk.ComponentKeyListener;
 import org.apache.pivot.wtk.ComponentMouseButtonListener;
 import org.apache.pivot.wtk.Dimensions;
 import org.apache.pivot.wtk.FileBrowser;
 import org.apache.pivot.wtk.HorizontalAlignment;
 import org.apache.pivot.wtk.ImageView;
 import org.apache.pivot.wtk.Insets;
+import org.apache.pivot.wtk.Keyboard;
 import org.apache.pivot.wtk.Label;
 import org.apache.pivot.wtk.ListButton;
 import org.apache.pivot.wtk.ListButtonSelectionListener;
@@ -49,9 +55,14 @@
 import org.apache.pivot.wtk.Mouse;
 import org.apache.pivot.wtk.PushButton;
 import org.apache.pivot.wtk.ScrollPane;
+import org.apache.pivot.wtk.SortDirection;
 import org.apache.pivot.wtk.Span;
 import org.apache.pivot.wtk.TableView;
+import org.apache.pivot.wtk.TableViewHeader;
+import org.apache.pivot.wtk.TableViewHeaderPressListener;
 import org.apache.pivot.wtk.TableViewSelectionListener;
+import org.apache.pivot.wtk.TextInput;
+import org.apache.pivot.wtk.TextInputTextListener;
 import org.apache.pivot.wtk.VerticalAlignment;
 import org.apache.pivot.wtk.media.Image;
 import org.apache.pivot.wtk.skin.FileBrowserSkin;
@@ -154,7 +165,7 @@
     }
 
     /**
-     * List view renderer for displaying file system contents.
+     * List view file renderer.
      */
     public static class ListViewFileRenderer extends FileRenderer implements ListView.ItemRenderer {
         public ListViewFileRenderer() {
@@ -202,6 +213,9 @@
         }
     }
 
+    /**
+     * Table view file renderer.
+     */
     public static class TableViewFileRenderer extends FileRenderer implements TableView.CellRenderer {
         public static final String NAME_KEY = "name";
         public static final String SIZE_KEY = "size";
@@ -268,16 +282,96 @@
         }
     }
 
+    public static class FileComparator implements Comparator<File> {
+        private String columnName = null;
+        private SortDirection sortDirection = null;
+
+        public FileComparator(String columnName, SortDirection sortDirection) {
+            this.columnName = columnName;
+            this.sortDirection = sortDirection;
+        }
+
+        public int compare(File file1, File file2) {
+            int result;
+
+            if (columnName.equals("name")) {
+                result = file1.getName().compareToIgnoreCase(file2.getName());
+            } else if (columnName.equals("size")) {
+                result = Long.signum(file1.length() - file2.length());
+            } else if (columnName.equals("lastModified")) {
+                result = Long.signum(file1.lastModified() - file2.lastModified());
+            } else {
+                throw new IllegalArgumentException();
+            }
+
+            result *= (sortDirection == SortDirection.ASCENDING) ? 1 : -1;
+
+            return result;
+        }
+    }
+
+    /**
+     * File sort handler.
+     */
+    public static class SortHandler implements TableViewHeaderPressListener {
+        @SuppressWarnings("unchecked")
+        public void headerPressed(TableViewHeader tableViewHeader, int index) {
+            TableView tableView = tableViewHeader.getTableView();
+            TableView.ColumnSequence columns = tableView.getColumns();
+            TableView.Column column = columns.get(index);
+
+            SortDirection sortDirection = column.getSortDirection();
+
+            if (sortDirection == null
+                || sortDirection == SortDirection.DESCENDING) {
+                sortDirection = SortDirection.ASCENDING;
+            } else {
+                sortDirection = SortDirection.DESCENDING;
+            }
+
+            List<File> files = (List<File>)tableView.getTableData();
+            files.setComparator(new FileComparator(column.getName(), sortDirection));
+
+            for (int i = 0, n = columns.getLength(); i < n; i++) {
+                column = columns.get(i);
+                column.setSortDirection(i == index ? sortDirection : null);
+            }
+        }
+    }
+
+    /**
+     * File name filter.
+     */
+    public static class FileNameFilter implements Filter<File> {
+        private String match;
+
+        public FileNameFilter(String match) {
+            this.match = match.toLowerCase();
+        }
+
+        public boolean include(File file) {
+            String name = file.getName();
+            name = name.toLowerCase();
+
+            return name.startsWith(match);
+        }
+    }
+
     private Component content = null;
 
     @WTKX private ListButton pathListButton = null;
     @WTKX private PushButton goUpButton = null;
     @WTKX private PushButton newFolderButton = null;
     @WTKX private PushButton goHomeButton = null;
+    @WTKX private TextInput searchTextInput = null;
 
     @WTKX private ScrollPane fileScrollPane = null;
     @WTKX private TableView fileTableView = null;
 
+    private FilteredList<File> files = new FilteredList<File>();
+
+    private boolean keyboardFolderTraversalEnabled = true;
+
     private boolean updatingSelection = false;
 
     @Override
@@ -338,25 +432,51 @@
             }
         });
 
+        searchTextInput.getComponentKeyListeners().add(new ComponentKeyListener.Adapter() {
+            @Override
+            public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+                boolean consumed = super.keyPressed(component, keyCode, keyLocation);
+
+                if (keyCode == Keyboard.KeyCode.ESCAPE) {
+                    searchTextInput.setText("");
+                    consumed = true;
+                }
+
+                return consumed;
+            }
+        });
+
+        searchTextInput.getTextInputTextListeners().add(new TextInputTextListener() {
+            public void textChanged(TextInput textInput) {
+                String text = textInput.getText();
+
+                if (text.length() == 0) {
+                    files.setFilter(null);
+                } else {
+                    files.setFilter(new FileNameFilter(text));
+                }
+            }
+        });
+
         fileTableView.getTableViewSelectionListeners().add(new TableViewSelectionListener() {
+            @SuppressWarnings("unchecked")
             public void selectedRangeAdded(TableView tableView, int rangeStart, int rangeEnd) {
                 updatingSelection = true;
 
-                Folder selectedFolder = (Folder)tableView.getTableData();
                 for (int i = rangeStart; i <= rangeEnd; i++) {
-                    File file = selectedFolder.get(i);
+                    File file = files.get(i);
                     fileBrowser.addSelectedFile(file);
                 }
 
                 updatingSelection = false;
             }
 
+            @SuppressWarnings("unchecked")
             public void selectedRangeRemoved(TableView tableView, int rangeStart, int rangeEnd) {
                 updatingSelection = true;
 
-                Folder selectedFolder = (Folder)tableView.getTableData();
                 for (int i = rangeStart; i <= rangeEnd; i++) {
-                    File file = selectedFolder.get(i);
+                    File file = files.get(i);
                     fileBrowser.removeSelectedFile(file);
                 }
 
@@ -383,6 +503,7 @@
             private int index = -1;
 
             @Override
+            @SuppressWarnings("unchecked")
             public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
                 if (count == 1) {
                     index = fileTableView.getRowAt(y);
@@ -391,7 +512,7 @@
                     if (index != -1
                         && index == this.index
                         && fileTableView.isRowSelected(index)) {
-                        File selectedDirectory = (File)fileTableView.getTableData().get(index);
+                        File selectedDirectory = files.get(index);
                         fileBrowser.setSelectedFolder(new Folder(selectedDirectory.getPath()));
                     }
                 }
@@ -400,6 +521,20 @@
             }
         });
 
+        files.getListListeners().add(new ListListener.Adapter<File>() {
+            public void comparatorChanged(List<File> list, Comparator<File> previousComparator) {
+                fileBrowser.clearSelection();
+            }
+        });
+
+        files.getFilteredListListeners().add(new FilteredListListener.Adapter<File>() {
+            public void filterChanged(FilteredList<File> filteredList, Filter<File> previousFilter) {
+                fileBrowser.clearSelection();
+            }
+        });
+
+        fileTableView.setTableData(files);
+
         selectedFolderChanged(fileBrowser, null);
         selectedFilesChanged(fileBrowser, null);
     }
@@ -438,11 +573,56 @@
         content.setSize(width, height);
     }
 
+
+    public boolean getKeyboardFolderTraversalEnabled() {
+        return keyboardFolderTraversalEnabled;
+    }
+
+    public void setKeyboardFolderTraversalEnabled(boolean keyboardFolderTraversalEnabled) {
+        this.keyboardFolderTraversalEnabled = keyboardFolderTraversalEnabled;
+    }
+
+    @Override
+    public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+        boolean consumed = super.keyPressed(component, keyCode, keyLocation);
+
+        FileBrowser fileBrowser = (FileBrowser)getComponent();
+
+        if (keyCode == Keyboard.KeyCode.ENTER
+            && keyboardFolderTraversalEnabled) {
+            Sequence<File> selectedFiles = fileBrowser.getSelectedFiles();
+
+            if (selectedFiles.getLength() == 1) {
+                File selectedFile = selectedFiles.get(0);
+                if (selectedFile.isDirectory()) {
+                    fileBrowser.setSelectedFolder(new Folder(selectedFile.getPath()));
+                    consumed = true;
+                }
+            }
+        }
+
+        return consumed;
+    }
+
+    @Override
+    public boolean keyReleased(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+        boolean consumed = super.keyReleased(component, keyCode, keyLocation);
+
+        if (keyCode == Keyboard.KeyCode.S
+            && Keyboard.isPressed(Keyboard.Modifier.META)) {
+            searchTextInput.requestFocus();
+            consumed = true;
+        }
+
+        return consumed;
+    }
+
     public void multiSelectChanged(FileBrowser fileBrowser) {
         fileTableView.setSelectMode(fileBrowser.isMultiSelect() ?
             TableView.SelectMode.MULTI : TableView.SelectMode.SINGLE);
     }
 
+    @SuppressWarnings("unchecked")
     public void selectedFolderChanged(FileBrowser fileBrowser, Folder previousSelectedFolder) {
         ArrayList<File> path = new ArrayList<File>();
 
@@ -462,9 +642,12 @@
         File homeDirectory = new File(System.getProperty("user.home"));
         goHomeButton.setEnabled(!selectedFolder.equals(homeDirectory));
 
+        searchTextInput.setText("");
+
         fileScrollPane.setScrollTop(0);
         fileScrollPane.setScrollLeft(0);
-        fileTableView.setTableData(selectedFolder);
+
+        files.setSource(selectedFolder);
 
         fileTableView.requestFocus();
     }
@@ -472,9 +655,7 @@
     @SuppressWarnings("unchecked")
     public void selectedFileAdded(FileBrowser fileBrowser, File file) {
         if (!updatingSelection) {
-            List<File> fileTableData = (List<File>)fileTableView.getTableData();
-
-            int index = fileTableData.indexOf(file);
+            int index = files.indexOf(file);
             if (index != -1) {
                 fileTableView.addSelectedIndex(index);
             }
@@ -484,9 +665,7 @@
     @SuppressWarnings("unchecked")
     public void selectedFileRemoved(FileBrowser fileBrowser, File file) {
         if (!updatingSelection) {
-            List<File> fileTableData = (List<File>)fileTableView.getTableData();
-
-            int index = fileTableData.indexOf(file);
+            int index = files.indexOf(file);
             if (index != -1) {
                 fileTableView.removeSelectedIndex(index);
             }
@@ -498,13 +677,12 @@
         if (!updatingSelection) {
             fileTableView.clearSelection();
 
-            List<File> fileTableData = (List<File>)fileTableView.getTableData();
             Sequence<File> selectedFiles = fileBrowser.getSelectedFiles();
 
             for (int i = 0, n = selectedFiles.getLength(); i < n; i++) {
                 File selectedFile = selectedFiles.get(i);
 
-                int index = fileTableData.indexOf(selectedFile);
+                int index = files.indexOf(selectedFile);
                 if (index != -1) {
                     fileTableView.addSelectedIndex(index);
                 }

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.wtkx?rev=805593&r1=805592&r2=805593&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.wtkx (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/terra_file_browser_skin.wtkx Tue Aug 18 21:42:06 2009
@@ -107,7 +107,11 @@
                             </TableView>
                         </view>
                         <columnHeader>
-                            <TableViewHeader tableView="$fileTableView"/>
+                            <TableViewHeader tableView="$fileTableView">
+                                <tableViewHeaderPressListeners>
+                                    <terra:TerraFileBrowserSkin.SortHandler/>
+                                </tableViewHeaderPressListeners>
+                            </TableViewHeader>
                         </columnHeader>
                     </ScrollPane>
                 </content>

Modified: incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/FileBrowserSheetTest.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/FileBrowserSheetTest.java?rev=805593&r1=805592&r2=805593&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/FileBrowserSheetTest.java (original)
+++ incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/FileBrowserSheetTest.java Tue Aug 18 21:42:06 2009
@@ -31,7 +31,7 @@
         throws Exception {
         WTKXSerializer wtkxSerializer = new WTKXSerializer();
 
-        FileBrowserSheet fileOpenSheet = new FileBrowserSheet(FileBrowserSheet.Mode.SAVE_TO);
+        FileBrowserSheet fileOpenSheet = new FileBrowserSheet(FileBrowserSheet.Mode.OPEN);
         wtkxSerializer.put("fileOpenSheet", fileOpenSheet);
 
         frame = (Frame)wtkxSerializer.readObject(getClass().getResource("file_browser_sheet_test.wtkx"));