You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by rw...@apache.org on 2013/05/24 23:22:40 UTC

svn commit: r1486223 [1/3] - in /pivot/trunk: ./ core/src/org/apache/pivot/io/ tests/src/org/apache/pivot/tests/ wtk-terra/src/org/apache/pivot/wtk/skin/terra/ wtk/lib/ wtk/src/org/apache/pivot/wtk/ wtk/src/org/apache/pivot/wtk/skin/

Author: rwhitcomb
Date: Fri May 24 21:22:39 2013
New Revision: 1486223

URL: http://svn.apache.org/r1486223
Log:
PIVOT-864: Adding a "pluggable" file system browser to Pivot based on
Apache Commons VFS (Virtual File System).

Basically this is a clone of the existing FileBrowser and FileBrowserSheet
components with the names changed and using the VFS2 FileObject instead
of File everywhere.  The skins are cloned and changed also.

Currently it has only been tested with local file system browsing and
it doesn't yet browse into local .zip archives (for instance).  There
are some other features I may add such as found in the Swing-based
VFSJFileChooser.

The Commons-VFS and supporting .jar files are only necessary to be
available on the classpath if the VFSBrowser or VFSBrowserSheet
classes are instantiated.

I have added the basic .jars (current as of 24-May-2013) to the
wtk/lib directory and added additional classpath references to this
directory to several of the Ant tasks so the compile and test tasks
will work out of the box.

Tested the "clean", "package", "doc" and "test" tasks to make sure
they are all clean.

There are a number of remaining basic tasks:
- Need to figure out "getFileRoots" replacement (doesn't exist
  right now in VFS API).
- Need a way to specify a different URI scheme to browse to remote
  systems (such as http:// or ftp://) (such as an input text field
  or an ancillary dialog)
- Similary we need to deal with authentication, when required, for
  remote systems.
- Enhance the browsing to be able to browse into archive files in
  addition to just directories.
- Address the TODO: items in the code.

Added:
    pivot/trunk/core/src/org/apache/pivot/io/FileObjectList.java
    pivot/trunk/tests/src/org/apache/pivot/tests/VFSBrowserTest.java
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.java
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_cs.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_de.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_es.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_fr.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_it.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_pl.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_ru.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_zh.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin.java
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin_cs.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin_de.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin_es.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin_fr.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin_it.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin_pl.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin_ru.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSkin_zh.json
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/terra_vfs_browser_sheet_skin.bxml
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/terra_vfs_browser_skin.bxml
    pivot/trunk/wtk/lib/commons-compress-1.5.jar   (with props)
    pivot/trunk/wtk/lib/commons-logging-1.1.3.jar   (with props)
    pivot/trunk/wtk/lib/commons-net-3.2.jar   (with props)
    pivot/trunk/wtk/lib/commons-vfs2-2.1-SNAPSHOT.jar   (with props)
    pivot/trunk/wtk/lib/httpclient-4.0.2.jar   (with props)
    pivot/trunk/wtk/lib/jackrabbit-webdav-1.6.5.jar   (with props)
    pivot/trunk/wtk/lib/jsch-0.1.49.jar   (with props)
    pivot/trunk/wtk/src/org/apache/pivot/wtk/VFSBrowser.java
    pivot/trunk/wtk/src/org/apache/pivot/wtk/VFSBrowserListener.java
    pivot/trunk/wtk/src/org/apache/pivot/wtk/VFSBrowserSheet.java
    pivot/trunk/wtk/src/org/apache/pivot/wtk/VFSBrowserSheetListener.java
    pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/VFSBrowserSkin.java
Modified:
    pivot/trunk/build.xml
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java

Modified: pivot/trunk/build.xml
URL: http://svn.apache.org/viewvc/pivot/trunk/build.xml?rev=1486223&r1=1486222&r2=1486223&view=diff
==============================================================================
--- pivot/trunk/build.xml (original)
+++ pivot/trunk/build.xml Fri May 24 21:22:39 2013
@@ -496,7 +496,9 @@ limitations under the License.
     </target>
 
     <target name="core">
-        <compile project="core"/>
+        <compile project="core">
+            <fileset dir="wtk" includes="lib/**/*.jar"/>
+        </compile>
     </target>
 
     <target name="demos" depends="core, wtk, wtk-terra, web">
@@ -510,7 +512,9 @@ limitations under the License.
     </target>
 
     <target name="tests" depends="core, web, wtk, wtk-terra">
-        <compile project="tests"/>
+        <compile project="tests">
+            <fileset dir="wtk" includes="lib/**/*.jar"/>
+        </compile>
     </target>
 
     <target name="tutorials" depends="core, wtk, web">
@@ -551,7 +555,9 @@ limitations under the License.
     </target>
 
     <target name="wtk-terra" depends="core, wtk">
-        <compile project="wtk-terra"/>
+        <compile project="wtk-terra">
+            <fileset dir="wtk" includes="lib/**/*.jar"/>
+        </compile>
     </target>
 
     <!-- Package source distribution -->

Added: pivot/trunk/core/src/org/apache/pivot/io/FileObjectList.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/io/FileObjectList.java?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/io/FileObjectList.java (added)
+++ pivot/trunk/core/src/org/apache/pivot/io/FileObjectList.java Fri May 24 21:22:39 2013
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 org.apache.pivot.io;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.apache.commons.vfs2.FileObject;
+import org.apache.pivot.collections.adapter.ListAdapter;
+
+
+/**
+ * Collection representing a list of files. Each entry in the list is unique;
+ * i.e. a single file can't be added to the list more than once.
+ * TODO: compute new serailVersionUIDs
+ */
+public class FileObjectList extends ListAdapter<FileObject> {
+    private static final long serialVersionUID = -6741822480264805279L;
+
+    private static class FilePathComparator implements Comparator<FileObject>, Serializable {
+        private static final long serialVersionUID = 6341769187574031281L;
+
+        @Override
+        public int compare(FileObject file1, FileObject file2) {
+            String path1 = file1.getName().getPath();
+            String path2 = file2.getName().getPath();
+
+            return path1.compareTo(path2);
+        }
+    }
+
+    private static final FilePathComparator filePathComparator = new FilePathComparator();
+
+    public FileObjectList() {
+        this(new java.util.ArrayList<FileObject>());
+    }
+
+    public FileObjectList(java.util.List<FileObject> files) {
+        super(files);
+
+        super.setComparator(filePathComparator);
+    }
+
+    @Override
+    public int add(FileObject file) {
+        int index = indexOf(file);
+
+        if (index == -1) {
+            index = super.add(file);
+        }
+
+        return index;
+    }
+
+    @Override
+    public void insert(FileObject file, int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FileObject update(int index, FileObject file) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setComparator(Comparator<FileObject> comparator) {
+        throw new UnsupportedOperationException();
+    }
+}

Added: pivot/trunk/tests/src/org/apache/pivot/tests/VFSBrowserTest.java
URL: http://svn.apache.org/viewvc/pivot/trunk/tests/src/org/apache/pivot/tests/VFSBrowserTest.java?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/tests/src/org/apache/pivot/tests/VFSBrowserTest.java (added)
+++ pivot/trunk/tests/src/org/apache/pivot/tests/VFSBrowserTest.java Fri May 24 21:22:39 2013
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 org.apache.pivot.tests;
+
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+
+import org.apache.pivot.collections.ArrayList;
+import org.apache.pivot.collections.Map;
+import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.wtk.Alert;
+import org.apache.pivot.wtk.Application;
+import org.apache.pivot.wtk.BoxPane;
+import org.apache.pivot.wtk.Button;
+import org.apache.pivot.wtk.ButtonPressListener;
+import org.apache.pivot.wtk.DesktopApplicationContext;
+import org.apache.pivot.wtk.Display;
+import org.apache.pivot.wtk.VFSBrowserSheet;
+import org.apache.pivot.wtk.Frame;
+import org.apache.pivot.wtk.Label;
+import org.apache.pivot.wtk.ListButton;
+import org.apache.pivot.wtk.ListView;
+import org.apache.pivot.wtk.MessageType;
+import org.apache.pivot.wtk.PushButton;
+import org.apache.pivot.wtk.Sheet;
+import org.apache.pivot.wtk.SheetCloseListener;
+import org.apache.pivot.wtk.VerticalAlignment;
+import org.apache.pivot.wtk.Window;
+import org.apache.pivot.wtk.skin.terra.TerraVFSBrowserSheetSkin;
+
+public class VFSBrowserTest implements Application
+{
+
+    public VFSBrowserTest() {
+    }
+
+
+    private Frame frame = null;
+
+    @Override
+    public void startup(Display display, Map<String, String> properties) throws Exception
+    {
+        BoxPane windowContent = new BoxPane();
+        PushButton button = new PushButton("Open Sheet");
+        button.getButtonPressListeners().add(new ButtonPressListener() {
+            @Override
+            public void buttonPressed(Button buttonArgument) {
+                try {
+                    final VFSBrowserSheet vfsBrowserSheet = new VFSBrowserSheet(VFSBrowserSheet.Mode.OPEN);
+
+                    vfsBrowserSheet.open(frame, new SheetCloseListener() {
+                        @Override
+                        public void sheetClosed(Sheet sheet) {
+                            if (sheet.getResult()) {
+                                Sequence<FileObject> selectedFiles = vfsBrowserSheet.getSelectedFiles();
+
+                                ListView listView = new ListView();
+                                listView.setListData(new ArrayList<FileObject>(selectedFiles));
+                                listView.setSelectMode(ListView.SelectMode.NONE);
+                                listView.getStyles().put("backgroundColor", null);
+
+                                Alert.alert(MessageType.INFO, "You selected:", listView, frame);
+                            } else {
+                                Alert.alert(MessageType.INFO, "You didn't select anything.", frame);
+                            }
+                        }
+                    });
+                }
+                catch (FileSystemException fse) {
+                    Alert.alert(MessageType.ERROR, String.format("File System Exception: %1$s", fse.getMessage()), frame);
+                }
+            }
+        });
+
+        windowContent.add(button);
+
+        frame = new Frame(windowContent);
+        frame.setMaximized(true);
+        frame.open(display);
+    }
+
+    @Override
+    public boolean shutdown(boolean optional) {
+        if (frame != null) {
+            frame.close();
+        }
+
+        return false;
+    }
+
+    @Override
+    public void resume() {
+        // empty block
+    }
+
+
+    @Override
+    public void suspend() {
+        // empty block
+    }
+
+    public static void main(String[] args) {
+        DesktopApplicationContext.main(VFSBrowserTest.class, args);
+    }
+
+}
+

Modified: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java?rev=1486223&r1=1486222&r2=1486223&view=diff
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java (original)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java Fri May 24 21:22:39 2013
@@ -83,6 +83,8 @@ import org.apache.pivot.wtk.TextPane;
 import org.apache.pivot.wtk.Theme;
 import org.apache.pivot.wtk.Tooltip;
 import org.apache.pivot.wtk.TreeView;
+import org.apache.pivot.wtk.VFSBrowser;
+import org.apache.pivot.wtk.VFSBrowserSheet;
 import org.apache.pivot.wtk.media.Image;
 
 /**
@@ -155,6 +157,8 @@ public final class TerraTheme extends Th
         componentSkinMap.put(TextInput.class, TerraTextInputSkin.class);
         componentSkinMap.put(Tooltip.class, TerraTooltipSkin.class);
         componentSkinMap.put(TreeView.class, TerraTreeViewSkin.class);
+        componentSkinMap.put(VFSBrowser.class, TerraVFSBrowserSkin.class);
+        componentSkinMap.put(VFSBrowserSheet.class, TerraVFSBrowserSheetSkin.class);
 
         componentSkinMap.put(TerraCalendarSkin.DateButton.class, TerraCalendarSkin.DateButtonSkin.class);
         componentSkinMap.put(TerraExpanderSkin.ShadeButton.class, TerraExpanderSkin.ShadeButtonSkin.class);

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.java?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.java (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.java Fri May 24 21:22:39 2013
@@ -0,0 +1,517 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin.terra;
+
+import java.io.IOException;
+
+import org.apache.commons.vfs2.FileName;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileType;
+import org.apache.pivot.beans.BXML;
+import org.apache.pivot.beans.BXMLSerializer;
+import org.apache.pivot.collections.ArrayList;
+import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.serialization.SerializationException;
+import org.apache.pivot.util.Filter;
+import org.apache.pivot.util.Vote;
+import org.apache.pivot.wtk.BoxPane;
+import org.apache.pivot.wtk.Button;
+import org.apache.pivot.wtk.ButtonPressListener;
+import org.apache.pivot.wtk.Component;
+import org.apache.pivot.wtk.ComponentMouseButtonListener;
+import org.apache.pivot.wtk.Container;
+import org.apache.pivot.wtk.VFSBrowser;
+import org.apache.pivot.wtk.VFSBrowserListener;
+import org.apache.pivot.wtk.VFSBrowserSheet;
+import org.apache.pivot.wtk.VFSBrowserSheetListener;
+import org.apache.pivot.wtk.Form;
+import org.apache.pivot.wtk.Mouse;
+import org.apache.pivot.wtk.PushButton;
+import org.apache.pivot.wtk.Sheet;
+import org.apache.pivot.wtk.TablePane;
+import org.apache.pivot.wtk.TextInput;
+import org.apache.pivot.wtk.TextInputContentListener;
+import org.apache.pivot.wtk.Window;
+
+/**
+ * Terra Commons VFS browser sheet skin.
+ */
+public class TerraVFSBrowserSheetSkin extends TerraSheetSkin implements VFSBrowserSheetListener {
+
+    private static class SaveToFileFilter implements Filter<FileObject> {
+        public final Filter<FileObject> sourceFilter;
+
+        public SaveToFileFilter(Filter<FileObject> sourceFilter) {
+            this.sourceFilter = sourceFilter;
+        }
+
+        @Override
+        public boolean include(FileObject file) {
+            return (file.getName().getType() != FileType.FOLDER
+                || (sourceFilter != null
+                    && sourceFilter.include(file)));
+        }
+    }
+
+    @BXML private TablePane tablePane = null;
+    @BXML private BoxPane saveAsBoxPane = null;
+    @BXML private TextInput saveAsTextInput = null;
+    @BXML private VFSBrowser fileBrowser = null;
+    @BXML private PushButton okButton = null;
+    @BXML private PushButton cancelButton = null;
+
+    private boolean updatingSelection = false;
+    private int selectedDirectoryCount = 0;
+
+    public TerraVFSBrowserSheetSkin() {
+        setResizable(true);
+    }
+
+    @Override
+    public void install(Component component) {
+        super.install(component);
+
+        final VFSBrowserSheet fileBrowserSheet = (VFSBrowserSheet)component;
+        fileBrowserSheet.setMinimumWidth(360);
+        fileBrowserSheet.setMinimumHeight(180);
+
+        // Load the sheet content
+        BXMLSerializer bxmlSerializer = new BXMLSerializer();
+
+        Component content;
+        try {
+            content = (Component)bxmlSerializer.readObject(TerraVFSBrowserSheetSkin.class,
+                "terra_vfs_browser_sheet_skin.bxml", true);
+        } catch (IOException exception) {
+            throw new RuntimeException(exception);
+        } catch (SerializationException exception) {
+            throw new RuntimeException(exception);
+        }
+
+        fileBrowserSheet.setContent(content);
+
+        bxmlSerializer.bind(this, TerraVFSBrowserSheetSkin.class);
+
+        // set the same rootDirectory to fileBrowser
+        try {
+            fileBrowser.setRootDirectory(fileBrowserSheet.getRootDirectory());
+        } catch (FileSystemException fse) {
+            throw new RuntimeException(fse);
+        }
+
+        saveAsTextInput.getTextInputContentListeners().add(new TextInputContentListener.Adapter() {
+            @Override
+            public void textChanged(TextInput textInput) {
+                Form.clearFlag(saveAsBoxPane);
+                updateOKButtonState();
+            }
+        });
+
+        fileBrowser.getFileBrowserListeners().add(new VFSBrowserListener.Adapter() {
+            @Override
+            public void rootDirectoryChanged(VFSBrowser fileBrowserArgument,
+                FileObject previousRootDirectory) {
+                updatingSelection = true;
+
+                try {
+                    fileBrowserSheet.setRootDirectory(fileBrowserArgument.getRootDirectory());
+                } catch (FileSystemException fse) {
+                    throw new RuntimeException(fse);
+                }
+
+                updatingSelection = false;
+
+                selectedDirectoryCount = 0;
+                updateOKButtonState();
+            }
+
+            @Override
+            public void selectedFileAdded(VFSBrowser fileBrowserArgument, FileObject file) {
+                if (file.getName().getType() == FileType.FOLDER) {
+                    selectedDirectoryCount++;
+                }
+
+                updateOKButtonState();
+            }
+
+            @Override
+            public void selectedFileRemoved(VFSBrowser fileBrowserArgument, FileObject file) {
+                if (file.getName().getType() == FileType.FOLDER) {
+                    selectedDirectoryCount--;
+                }
+
+                updateOKButtonState();
+            }
+
+            @Override
+            public void selectedFilesChanged(VFSBrowser fileBrowserArgument,
+                Sequence<FileObject> previousSelectedFiles) {
+                selectedDirectoryCount = 0;
+
+                Sequence<FileObject> selectedFiles = fileBrowserArgument.getSelectedFiles();
+                for (int i = 0, n = selectedFiles.getLength(); i < n; i++) {
+                    FileObject selectedFile = selectedFiles.get(i);
+
+                    if (selectedFile.getName().getType() == FileType.FOLDER) {
+                        selectedDirectoryCount++;
+                    }
+                }
+
+                if (!fileBrowserArgument.isMultiSelect()) {
+                    FileObject selectedFile = fileBrowserArgument.getSelectedFile();
+
+                    if (selectedFile != null
+                        && selectedFile.getName().getType() != FileType.FOLDER) {
+                        saveAsTextInput.setText(selectedFile.getName().getPath());
+                    }
+                }
+
+                updateOKButtonState();
+            }
+        });
+
+        fileBrowser.getComponentMouseButtonListeners().add(new ComponentMouseButtonListener.Adapter() {
+            private FileObject file = null;
+
+            @Override
+            public boolean mouseClick(Component componentArgument, Mouse.Button button, int x, int y, int count) {
+                boolean consumed = super.mouseClick(componentArgument, button, x, y, count);
+
+                VFSBrowserSheet.Mode mode = fileBrowserSheet.getMode();
+
+                if (count == 1) {
+                    file = fileBrowser.getFileAt(x, y);
+                } else if (count == 2) {
+                    FileObject fileLocal = fileBrowser.getFileAt(x, y);
+
+                    if (fileLocal != null
+                        && this.file != null
+                        && fileLocal.equals(this.file)
+                        && fileBrowser.isFileSelected(fileLocal)) {
+                        if (mode == VFSBrowserSheet.Mode.OPEN
+                            || mode == VFSBrowserSheet.Mode.OPEN_MULTIPLE) {
+                            if (fileLocal.getName().getType() != FileType.FOLDER) {
+                                fileBrowserSheet.close(true);
+                                consumed = true;
+                            }
+                        }
+                    }
+                }
+
+                return consumed;
+            }
+        });
+
+        okButton.getButtonPressListeners().add(new ButtonPressListener() {
+            @Override
+            public void buttonPressed(Button button) {
+                fileBrowserSheet.close(true);
+            }
+        });
+
+        cancelButton.getButtonPressListeners().add(new ButtonPressListener() {
+            @Override
+            public void buttonPressed(Button button) {
+                fileBrowserSheet.close(false);
+            }
+        });
+
+        // Add this as a file browser sheet listener
+        fileBrowserSheet.getFileBrowserSheetListeners().add(this);
+
+        modeChanged(fileBrowserSheet, null);
+        rootDirectoryChanged(fileBrowserSheet, null);
+        selectedFilesChanged(fileBrowserSheet, null);
+    }
+
+    public boolean isHideDisabledFiles() {
+        return (Boolean)fileBrowser.getStyles().get("hideDisabledFiles");
+    }
+
+    public void setHideDisabledFiles(boolean hideDisabledFiles) {
+        fileBrowser.getStyles().put("hideDisabledFiles", hideDisabledFiles);
+    }
+
+    public boolean getShowOKButtonFirst() {
+        Container parent = okButton.getParent();
+        return parent.indexOf(okButton) < parent.indexOf(cancelButton);
+    }
+
+    public void setShowOKButtonFirst(boolean showOKButtonFirst) {
+        if (showOKButtonFirst != getShowOKButtonFirst()) {
+            Container parent = okButton.getParent();
+            parent.remove(okButton);
+            parent.remove(cancelButton);
+
+            if (showOKButtonFirst) {
+                parent.add(okButton);
+                parent.add(cancelButton);
+            } else {
+                parent.add(cancelButton);
+                parent.add(okButton);
+            }
+        }
+    }
+
+    @Override
+    public void windowOpened(Window window) {
+        super.windowOpened(window);
+        window.requestFocus();
+    }
+
+    @Override
+    public Vote previewSheetClose(final Sheet sheet, final boolean result) {
+        Vote vote = null;
+
+        if (result
+            && !okButton.isEnabled()) {
+            vote = Vote.DENY;
+        } else {
+            if (result) {
+                updatingSelection = true;
+
+                VFSBrowserSheet fileBrowserSheet = (VFSBrowserSheet)sheet;
+                VFSBrowserSheet.Mode mode = fileBrowserSheet.getMode();
+                FileSystemManager manager = fileBrowserSheet.getManager();
+                FileName baseFileName = fileBrowserSheet.getBaseFileName();
+
+                switch (mode) {
+                    case OPEN:
+                    case OPEN_MULTIPLE:
+                    case SAVE_TO: {
+                        try {
+                            fileBrowserSheet.setSelectedFiles(fileBrowser.getSelectedFiles());
+                        } catch (FileSystemException fse) {
+                            throw new RuntimeException(fse);
+                        }
+                        break;
+                    }
+
+                    case SAVE_AS: {
+                        String fileName = saveAsTextInput.getText();
+                        // Contents of the entry field could be:
+                        // 1. Just a new file name in the current root directory
+                        // 2. A relative or absolute path that is an existing directory
+                        //    to navigate to
+                        // 3. A relative or absolute path including the new file name
+                        //    in an existing directory
+                        // So, first make it an absolute path
+                        // TODO: all this logic needs changing (not sure how) with VFS
+                        // because you could type in a whole new URI and have to change
+                        // managers
+                        try {
+                            FileObject selectedFile = manager.resolveFile(fileName);
+                            //if (!selectedFile.isAbsolute() && !fileName.startsWith(File.separator)) {
+                            if (!baseFileName.isDescendent(selectedFile.getName())) {
+                                selectedFile = manager.resolveFile(fileBrowser.getRootDirectory(), fileName);
+                            } else {
+                                // TODO: is there really anything to do here?
+                                //selectedFile = selectedFile.getAbsoluteFile();
+                            }
+                            if (selectedFile.exists() && selectedFile.getType() == FileType.FOLDER) {
+                                try {
+                                    // TODO: what to do about canonical file representations?
+                                    FileObject root = /* selectedFile.getCanonicalFile(); */selectedFile;
+                                    fileBrowserSheet.setRootDirectory(root);
+                                    fileBrowser.setRootDirectory(root);
+                                    saveAsTextInput.setText("");
+                                } catch (IOException ioe) {
+                                    Form.setFlag(saveAsBoxPane, new Form.Flag());
+                                }
+                                selectedFile = null;
+                                vote = Vote.DENY;
+                            } else {
+                                FileObject root = selectedFile.getParent();
+                                if (root != null && root.exists() && root.getType() == FileType.FOLDER) {
+                                    try {
+                                        // TODO: canonical file again
+                                        //fileBrowserSheet.setRootDirectory(root.getCanonicalFile());
+                                        fileBrowserSheet.setRootDirectory(root);
+                                        selectedFile = manager.resolveFile(selectedFile.getName().getPath());
+                                    }
+                                    catch (IOException ioe) {
+                                        Form.setFlag(saveAsBoxPane, new Form.Flag());
+                                        selectedFile = null;
+                                        vote = Vote.DENY;
+                                    }
+                                } else {
+                                    // Could be an error message here ("Directory does not exist")
+                                    Form.setFlag(saveAsBoxPane, new Form.Flag());
+                                    selectedFile = null;
+                                    vote = Vote.DENY;
+                                }
+                            }
+                            if (selectedFile != null) {
+                                fileBrowserSheet.setSelectedFiles(new ArrayList<FileObject>(selectedFile));
+                            }
+                        } catch (FileSystemException fse) {
+                            Form.setFlag(saveAsBoxPane, new Form.Flag());
+                            vote = Vote.DENY;
+                        }
+                        break;
+                    }
+                }
+
+                updatingSelection = false;
+            }
+            if (vote == null) {
+                vote = super.previewSheetClose(sheet, result);
+            }
+        }
+
+        return vote;
+    }
+
+    @Override
+    public void managerChanged(VFSBrowserSheet fileBrowserSheet,
+        FileSystemManager previousManager) {
+        // TODO: what to do here?
+    }
+
+    @Override
+    public void modeChanged(VFSBrowserSheet fileBrowserSheet,
+        VFSBrowserSheet.Mode previousMode) {
+        VFSBrowserSheet.Mode mode = fileBrowserSheet.getMode();
+
+        fileBrowser.getStyles().put("keyboardFolderTraversalEnabled",
+            (mode != VFSBrowserSheet.Mode.SAVE_TO));
+
+        switch (mode) {
+            case OPEN: {
+                saveAsBoxPane.setVisible(false);
+                fileBrowser.setMultiSelect(false);
+                break;
+            }
+
+            case OPEN_MULTIPLE: {
+                saveAsBoxPane.setVisible(false);
+                fileBrowser.setMultiSelect(true);
+                break;
+            }
+
+            case SAVE_AS: {
+                saveAsBoxPane.setVisible(true);
+                fileBrowser.setMultiSelect(false);
+                break;
+            }
+
+            case SAVE_TO: {
+                saveAsBoxPane.setVisible(false);
+                fileBrowser.setMultiSelect(false);
+                break;
+            }
+        }
+
+        updateDisabledFileFilter();
+        updateOKButtonState();
+    }
+
+    @Override
+    public void rootDirectoryChanged(VFSBrowserSheet fileBrowserSheet,
+        FileObject previousRootDirectory) {
+        if (!updatingSelection) {
+            try {
+                fileBrowser.setRootDirectory(fileBrowserSheet.getRootDirectory());
+            } catch (FileSystemException fse) {
+                throw new RuntimeException(fse);
+            }
+        }
+    }
+
+    @Override
+    public void selectedFilesChanged(VFSBrowserSheet fileBrowserSheet,
+        Sequence<FileObject> previousSelectedFiles) {
+        if (!updatingSelection) {
+            Sequence<FileObject> selectedFiles = fileBrowserSheet.getSelectedFiles();
+            try {
+                fileBrowser.setSelectedFiles(selectedFiles);
+            } catch (FileSystemException fse) {
+                throw new RuntimeException(fse);
+            }
+
+            if (fileBrowser.getSelectedFiles().getLength() == 0
+                && selectedFiles.getLength() == 1) {
+                // The file does not currently exist; set the file name in the
+                // text input if the parent directory is the same as the root
+                // directory
+                FileObject selectedFile = selectedFiles.get(0);
+
+                try {
+                    FileObject rootDirectory = fileBrowser.getRootDirectory();
+                    if (rootDirectory.equals(selectedFile.getParent())) {
+                        saveAsTextInput.setText(selectedFile.getName().getPath());
+                    }
+                } catch (FileSystemException fse) {
+                    throw new RuntimeException(fse);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void disabledFileFilterChanged(VFSBrowserSheet fileBrowserSheet,
+        Filter<FileObject> previousDisabledFileFilter) {
+        updateDisabledFileFilter();
+    }
+
+    private void updateDisabledFileFilter() {
+        VFSBrowserSheet fileBrowserSheet = (VFSBrowserSheet)getComponent();
+        Filter<FileObject> disabledFileFilter = fileBrowserSheet.getDisabledFileFilter();
+
+        VFSBrowserSheet.Mode mode = fileBrowserSheet.getMode();
+        if (mode == VFSBrowserSheet.Mode.SAVE_TO) {
+            disabledFileFilter = new SaveToFileFilter(disabledFileFilter);
+        }
+
+        fileBrowser.setDisabledFileFilter(disabledFileFilter);
+    }
+
+    private void updateOKButtonState() {
+        VFSBrowserSheet fileBrowserSheet = (VFSBrowserSheet)getComponent();
+
+        VFSBrowserSheet.Mode mode = fileBrowserSheet.getMode();
+        Sequence<FileObject> selectedFiles = fileBrowser.getSelectedFiles();
+
+        switch (mode) {
+            case OPEN:
+            case OPEN_MULTIPLE: {
+                okButton.setEnabled(selectedFiles.getLength() > 0
+                    && selectedDirectoryCount == 0);
+                break;
+            }
+
+            case SAVE_AS: {
+                okButton.setEnabled(saveAsTextInput.getCharacterCount() > 0);
+                break;
+            }
+
+            case SAVE_TO: {
+                okButton.setEnabled(selectedDirectoryCount > 0);
+                break;
+            }
+        }
+    }
+
+    public void addComponent(Component component) {
+        TablePane.Row row = new TablePane.Row(-1);
+        row.add(component);
+        Sequence<TablePane.Row> rows = tablePane.getRows();
+        rows.insert(row, rows.getLength() - 1);
+    }
+}

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.json
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.json?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.json (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin.json Fri May 24 21:22:39 2013
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+{   saveAs: "Save as:",
+    ok: "OK",
+    cancel: "Cancel"
+}
+

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_cs.json
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_cs.json?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_cs.json (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_cs.json Fri May 24 21:22:39 2013
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+{   saveAs: "Uložit jako:",
+    ok: "OK",
+    cancel: "Zrušit"
+}
+

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_de.json
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_de.json?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_de.json (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_de.json Fri May 24 21:22:39 2013
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+{   saveAs: "Speichern als:",
+    ok: "OK",
+    cancel: "Abbruch"
+}
+

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_es.json
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_es.json?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_es.json (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_es.json Fri May 24 21:22:39 2013
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+{   saveAs: "Guardar como:",
+    ok: "Aceptar",
+    cancel: "Cancelar"
+}
+

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_fr.json
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_fr.json?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_fr.json (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_fr.json Fri May 24 21:22:39 2013
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+{   saveAs: "Sauvegarder sous:",
+    ok: "OK",
+    cancel: "Annuler"
+}

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_it.json
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_it.json?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_it.json (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_it.json Fri May 24 21:22:39 2013
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+{   saveAs: "Salva come:",
+    ok: "OK",
+    cancel: "Annulla"
+}
+

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_pl.json
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_pl.json?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_pl.json (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_pl.json Fri May 24 21:22:39 2013
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+{   saveAs: "Zapisz jako:",
+    ok: "OK",
+    cancel: "Anuluj"
+}
+

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_ru.json
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_ru.json?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_ru.json (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_ru.json Fri May 24 21:22:39 2013
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+{   saveAs: "Сохранить как:",
+    ok: "OK",
+    cancel: "Отмена"
+}
+

Added: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_zh.json
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_zh.json?rev=1486223&view=auto
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_zh.json (added)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraVFSBrowserSheetSkin_zh.json Fri May 24 21:22:39 2013
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+{   saveAs: "保存为:",
+    ok: "确定",
+    cancel: "取消"
+}
+