Finished folder permissions dialog
authorChristos Stathis <chstath@ebs.gr>
Thu, 11 Aug 2011 13:27:18 +0000 (16:27 +0300)
committerChristos Stathis <chstath@ebs.gr>
Thu, 11 Aug 2011 13:27:18 +0000 (16:27 +0300)
src/gr/grnet/pithos/web/client/DeleteFileDialog.java
src/gr/grnet/pithos/web/client/FilePropertiesDialog.java
src/gr/grnet/pithos/web/client/FileUploadDialog.java
src/gr/grnet/pithos/web/client/FolderPropertiesDialog.java
src/gr/grnet/pithos/web/client/Pithos.java
src/gr/grnet/pithos/web/client/commands/PasteCommand.java
src/gr/grnet/pithos/web/client/commands/ToTrashCommand.java
src/gr/grnet/pithos/web/client/foldertree/Folder.java
src/gr/grnet/pithos/web/client/foldertree/FolderTreeView.java
src/gr/grnet/pithos/web/client/foldertree/FolderTreeViewModel.java

index 8c0db5f..d169e17 100644 (file)
@@ -154,7 +154,7 @@ public class DeleteFileDialog extends DialogBox {
             Scheduler.get().scheduleDeferred(deleteFile);\r
         }\r
         else {\r
-            app.updateFolder(files.get(0).getParent());\r
+            app.updateFolder(files.get(0).getParent(), true);\r
         }\r
     }\r
 \r
index f3c3194..b574bbc 100644 (file)
@@ -398,6 +398,7 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog {
                String newFilename = null;\r
 \r
                final Map<String, Boolean[]> perms = (permList.hasChanges() ? permList.getPermissions() : null);\r
+\r
                if (!name.getText().trim().equals(file.getName())) {\r
                        newFilename = name.getText().trim();\r
                }\r
@@ -442,7 +443,7 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog {
             PostRequest updateFile = new PostRequest(api, owner, path) {\r
                 @Override\r
                 public void onSuccess(Resource result) {\r
-                    app.updateFolder(file.getParent());\r
+                    app.updateFolder(file.getParent(), true);\r
                 }\r
 \r
                 @Override\r
@@ -458,8 +459,8 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog {
             if (published != null)\r
                 updateFile.setHeader("X-Object-Public", published.toString());\r
             if (newPermissions != null) {\r
-                String readPermHeader = "read=" + app.getUsername() + ",";\r
-                String writePermHeader = "write=" + app.getUsername() + ",";\r
+                String readPermHeader = "read=" + owner + ",";\r
+                String writePermHeader = "write=" + owner + ",";\r
                 for (String u : newPermissions.keySet()) {\r
                     Boolean[] p = newPermissions.get(u);\r
                     if (p[0] != null && p[0])\r
@@ -477,7 +478,7 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog {
             Scheduler.get().scheduleDeferred(updateFile);\r
         }\r
         else\r
-            app.updateFolder(file.getParent());\r
+            app.updateFolder(file.getParent(), true);\r
     }\r
 \r
        private void removeAllOldVersions() {\r
index 89b7e02..2143f26 100644 (file)
@@ -178,7 +178,7 @@ public class FileUploadDialog extends DialogBox {
                                        GWT.log(results, null);
                                        app.displayError(results);
                                }
-                app.updateFolder(folder);
+                app.updateFolder(folder, true);
                                hide();
                        }
                });
index 19193fd..5799892 100644 (file)
@@ -37,10 +37,10 @@ package gr.grnet.pithos.web.client;
 import com.google.gwt.core.client.Scheduler;\r
 import com.google.gwt.event.dom.client.KeyDownEvent;\r
 import com.google.gwt.user.client.Command;\r
-import gr.grnet.pithos.web.client.FilePropertiesDialog.Images;\r
 import gr.grnet.pithos.web.client.foldertree.File;\r
 import gr.grnet.pithos.web.client.foldertree.Folder;\r
 import gr.grnet.pithos.web.client.foldertree.Resource;\r
+import gr.grnet.pithos.web.client.rest.PostRequest;\r
 import gr.grnet.pithos.web.client.rest.PutRequest;\r
 import gr.grnet.pithos.web.client.rest.RestException;\r
 \r
@@ -52,7 +52,6 @@ import com.google.gwt.event.dom.client.KeyCodes;
 import com.google.gwt.i18n.client.DateTimeFormat;\r
 import com.google.gwt.user.client.Event.NativePreviewEvent;\r
 import com.google.gwt.user.client.ui.Button;\r
-import com.google.gwt.user.client.ui.CheckBox;\r
 import com.google.gwt.user.client.ui.DecoratedTabPanel;\r
 import com.google.gwt.user.client.ui.DialogBox;\r
 import com.google.gwt.user.client.ui.FlexTable;\r
@@ -62,6 +61,7 @@ import com.google.gwt.user.client.ui.TabPanel;
 import com.google.gwt.user.client.ui.TextBox;\r
 import com.google.gwt.user.client.ui.VerticalPanel;\r
 import java.util.Iterator;\r
+import java.util.Map;\r
 \r
 /**\r
  * The 'Folder properties' dialog box implementation.\r
@@ -70,8 +70,6 @@ public class FolderPropertiesDialog extends DialogBox {
 \r
     private Pithos app;\r
 \r
-       private CheckBox readForAll;\r
-\r
        /**\r
         * The widget that holds the folderName of the folder.\r
         */\r
@@ -150,8 +148,6 @@ public class FolderPropertiesDialog extends DialogBox {
         boolean permsReadonly = folder.getInheritedPermissionsFrom() != null || folder.existChildrenPermissions();\r
         permList = new PermissionsList(images, folder.getPermissions(), folder.getOwner(), permsReadonly);\r
         permPanel.add(permList);\r
-        final HorizontalPanel permForAll = new HorizontalPanel();\r
-        final HorizontalPanel pathPanel = new HorizontalPanel();\r
 \r
         if (!permsReadonly) {\r
             HorizontalPanel permButtons = new HorizontalPanel();\r
@@ -267,7 +263,7 @@ public class FolderPropertiesDialog extends DialogBox {
         PutRequest createFolder = new PutRequest(app.getApiPath(), app.getUsername(), path) {\r
             @Override\r
             public void onSuccess(Resource result) {\r
-                app.updateFolder(folder);\r
+                app.updateFolder(folder, true);\r
             }\r
 \r
             @Override\r
@@ -301,84 +297,8 @@ public class FolderPropertiesDialog extends DialogBox {
        }\r
 \r
        private void updateFolder() {\r
-//             permList.updatePermissionsAccordingToInput();\r
-//             Set<PermissionHolder> perms = permList.getPermissions();\r
-//             JSONObject json = new JSONObject();\r
-//             if(!folder.getName().equals(folderName.getText()))\r
-//                     json.put("name", new JSONString(folderName.getText()));\r
-//             //only update the read for all perm if the user is the owner\r
-//             if (readForAll.getValue() != folder.isReadForAll())\r
-//                     if (folder.getOwner().equals(app.getCurrentUserResource().getUsername()))\r
-//                             json.put("readForAll", JSONBoolean.getInstance(readForAll.getValue()));\r
-//             if (permList.hasChanges()) {\r
-//                     JSONArray perma = new JSONArray();\r
-//                     int i=0;\r
-//                     for(PermissionHolder p : perms){\r
-//                             JSONObject po = new JSONObject();\r
-//                             if(p.getUser() != null)\r
-//                                     po.put("user", new JSONString(p.getUser()));\r
-//                             if(p.getGroup() != null)\r
-//                                     po.put("group", new JSONString(p.getGroup()));\r
-//                             po.put("read", JSONBoolean.getInstance(p.isRead()));\r
-//                             po.put("write", JSONBoolean.getInstance(p.isWrite()));\r
-//                             po.put("modifyACL", JSONBoolean.getInstance(p.isModifyACL()));\r
-//                             perma.set(i,po);\r
-//                             i++;\r
-//                     }\r
-//                     json.put("permissions", perma);\r
-//                     GWT.log(json.toString(), null);\r
-//             }\r
-//             PostCommand ep = new PostCommand(folder.getUri()+"?update=", json.toString(), 200){\r
-//\r
-//                     @Override\r
-//                     public void onComplete() {\r
-//                             //TODO:CELLTREE\r
-//\r
-//                             if(getPostBody() != null && !"".equals(getPostBody().trim())){\r
-//\r
-//\r
-//                                     FolderResource fres = ((RestResourceWrapper) app.getTreeView().getSelection()).getResource();\r
-//                                     String initialPath = fres.getUri();\r
-//                                     String newPath =  getPostBody().trim();\r
-//                                     fres.setUri(newPath);\r
-//                                     ((RestResourceWrapper) app.getTreeView().getSelection()).getResource().setUri(newPath);\r
-//                                     ((RestResourceWrapper) app.getTreeView().getSelection()).setUri(newPath);\r
-//                                     app.getTreeView().updateNodeChildren(fres.getParentURI());\r
-//                                     if (permList.hasChanges()) {\r
-//                                             app.getTreeView().updateMySharedNode();\r
-//                                     }\r
-//                                     /*\r
-//                                     if(folderItem.getParentItem() != null && ((DnDTreeItem)folderItem.getParentItem()).getFolderResource() != null){\r
-//                                             ((DnDTreeItem)folderItem.getParentItem()).getFolderResource().removeSubfolderPath(initialPath);\r
-//                                             ((DnDTreeItem)folderItem.getParentItem()).getFolderResource().getSubfolderPaths().add(newPath);\r
-//                                     }*/\r
-//                             }\r
-//                             //app.getFolders().updateFolder( (DnDTreeItem) app.getFolders().getCurrent());\r
-//\r
-//                             app.get().showFileList(true);\r
-//                     }\r
-//\r
-//                     @Override\r
-//                     public void onError(Throwable t) {\r
-//                             GWT.log("", t);\r
-//                             if(t instanceof RestException){\r
-//                                     int statusCode = ((RestException)t).getHttpStatusCode();\r
-//                                     if(statusCode == 405)\r
-//                                             app.displayError("You don't have the necessary permissions or" +\r
-//                                                             " a folder with same name already exists");\r
-//                                     else if(statusCode == 404)\r
-//                                             app.displayError("Resource not found, or user specified in sharing does not exist");\r
-//                                     else\r
-//                                             app.displayError("Unable to update folder: "+((RestException)t).getHttpStatusText());\r
-//                             }\r
-//                             else\r
-//                                     app.displayError("System error moifying file: "+t.getMessage());\r
-//                             //TODO:CELLTREE\r
-//                             //app.getFolders().updateFolder( (DnDTreeItem) app.getFolders().getCurrent());\r
-//                     }\r
-//             };\r
-//             DeferredCommand.addCommand(ep);\r
-        final String newName = folderName.getText();\r
+        final Map<String, Boolean[]> perms = (permList.hasChanges() ? permList.getPermissions() : null);\r
+        final String newName = folderName.getText().trim();\r
         if (!folder.isContainer() && !folder.getName().equals(newName)) {\r
             final String path = folder.getParent().getUri() + "/" + newName;\r
             PutRequest newFolder = new PutRequest(app.getApiPath(), app.getUsername(), path) {\r
@@ -393,7 +313,7 @@ public class FolderPropertiesDialog extends DialogBox {
                                 @Override\r
                                 public void execute() {\r
                                     app.deleteFolder(folder);\r
-                                    app.updateFolder(folder.getParent());\r
+                                    updateMetadata(path + "?update=", perms);\r
                                 }\r
                             });\r
                         }\r
@@ -416,8 +336,48 @@ public class FolderPropertiesDialog extends DialogBox {
             newFolder.setHeader("Content-Length", "0");\r
             Scheduler.get().scheduleDeferred(newFolder);\r
         }\r
+        else\r
+            updateMetadata(folder.getUri() + "?update=", perms);\r
        }\r
 \r
+    private void updateMetadata(String path, Map<String, Boolean[]> newPermissions) {\r
+        if (newPermissions != null) {\r
+            PostRequest updateFolder = new PostRequest(app.getApiPath(), folder.getOwner(), path) {\r
+                @Override\r
+                public void onSuccess(Resource result) {\r
+                    app.updateFolder(folder.getParent(), false);\r
+                }\r
+\r
+                @Override\r
+                public void onError(Throwable t) {\r
+                    GWT.log("", t);\r
+                    app.displayError("System error modifying folder: " + t.getMessage());\r
+                }\r
+            };\r
+            updateFolder.setHeader("X-Auth-Token", app.getToken());\r
+            if (newPermissions != null) {\r
+                String readPermHeader = "read=" + folder.getOwner() + ",";\r
+                String writePermHeader = "write=" + folder.getOwner() + ",";\r
+                for (String u : newPermissions.keySet()) {\r
+                    Boolean[] p = newPermissions.get(u);\r
+                    if (p[0] != null && p[0])\r
+                        readPermHeader += u + ",";\r
+                    if (p[1] != null && p[1])\r
+                        writePermHeader += u + ",";\r
+                }\r
+                if (readPermHeader.endsWith(","))\r
+                    readPermHeader = readPermHeader.substring(0, readPermHeader.length() - 1);\r
+                if (writePermHeader.endsWith(","))\r
+                    writePermHeader = writePermHeader.substring(0, writePermHeader.length() - 1);\r
+                String permHeader = readPermHeader +  ";" + writePermHeader;\r
+                updateFolder.setHeader("X-Object-Sharing", permHeader);\r
+            }\r
+            Scheduler.get().scheduleDeferred(updateFolder);\r
+        }\r
+        else\r
+            app.updateFolder(folder.getParent(), false);\r
+    }\r
+\r
        public void selectTab(int _tab) {\r
                inner.selectTab(_tab);\r
        }\r
index fb16b0b..524adaf 100644 (file)
@@ -133,8 +133,8 @@ public class Pithos implements EntryPoint, ResizeHandler {
         return account;
     }
 
-    public void updateFolder(Folder f) {
-        folderTreeView.updateFolder(f);
+    public void updateFolder(Folder f, boolean showfiles) {
+        folderTreeView.updateFolder(f, showfiles);
     }
 
     public void updateTag(Tag t) {
@@ -301,7 +301,7 @@ public class Pithos implements EntryPoint, ResizeHandler {
                 if (folderTreeSelectionModel.getSelectedObject() != null) {
                     tagTreeSelectionModel.setSelected(tagTreeSelectionModel.getSelectedObject(), false);
                     Folder f = folderTreeSelectionModel.getSelectedObject();
-                    updateFolder(f);
+                    updateFolder(f, true);
                 }
             }
         });
@@ -948,7 +948,7 @@ public class Pithos implements EntryPoint, ResizeHandler {
             DeleteRequest deleteFolder = new DeleteRequest(getApiPath(), getUsername(), path) {
                 @Override
                 public void onSuccess(Resource result) {
-                    updateFolder(folder.getParent());
+                    updateFolder(folder.getParent(), true);
                 }
 
                 @Override
index 35980bb..7223107 100644 (file)
@@ -78,7 +78,7 @@ public class PasteCommand implements Command {
                     @Override
                     public void execute() {
                         app.getClipboard().clear();
-                        app.updateFolder(folder);
+                        app.updateFolder(folder, true);
                     }
                 });
             }
@@ -88,7 +88,7 @@ public class PasteCommand implements Command {
                     public void execute() {
                         app.getClipboard().clear();
                         app.deleteFolder(tobeCopied);
-                        app.updateFolder(folder);
+                        app.updateFolder(folder, true);
                     }
                 });
             }
@@ -101,7 +101,7 @@ public class PasteCommand implements Command {
                     @Override
                     public void execute() {
                         app.getClipboard().clear();
-                        app.updateFolder(folder);
+                        app.updateFolder(folder, true);
                     }
                 });
             }
@@ -110,7 +110,7 @@ public class PasteCommand implements Command {
                     @Override
                     public void execute() {
                         app.getClipboard().clear();
-                        app.updateFolder(folder);
+                        app.updateFolder(folder, true);
                     }
                 });
             }
index 6795ac8..7cc1b6c 100644 (file)
@@ -76,7 +76,7 @@ public class ToTrashCommand implements Command{
             trashFiles(iter, new Command() {
                 @Override
                 public void execute() {
-                    app.updateFolder(((List<File>) resource).get(0).getParent());
+                    app.updateFolder(((List<File>) resource).get(0).getParent(), true);
                 }
             });
         }
@@ -85,7 +85,7 @@ public class ToTrashCommand implements Command{
             trashFolder(toBeTrashed, new Command() {
                 @Override
                 public void execute() {
-                    app.updateFolder(toBeTrashed.getParent());
+                    app.updateFolder(toBeTrashed.getParent(), true);
                 }
             });
 
index 960c852..30badae 100644 (file)
@@ -266,14 +266,14 @@ public class Folder extends Resource {
     public boolean equals(Object other) {
         if (other instanceof Folder) {
             Folder o = (Folder) other;
-            return (container + prefix).equals(o.getContainer() + o.getPrefix());
+            return getUri().equals(o.getUri());
         }
         return false;
     }
 
     @Override
     public int hashCode() {
-        return (container + prefix).hashCode();
+        return getUri().hashCode();
     }
 
     public Set<File> getFiles() {
index 600dfda..7b01738 100644 (file)
@@ -43,12 +43,33 @@ import com.google.gwt.safehtml.client.SafeHtmlTemplates;
 import com.google.gwt.safehtml.shared.SafeHtml;
 import com.google.gwt.user.cellview.client.CellTree;
 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
+import com.google.gwt.user.cellview.client.TreeNode;
 import com.google.gwt.user.client.ui.Composite;
 import com.google.gwt.user.client.ui.Tree;
 import gr.grnet.pithos.web.client.FolderContextMenu;
 
 public class FolderTreeView extends Composite {
 
+    public void updateChildren(Folder folder) {
+        TreeNode root = ((CellTree) getWidget()).getRootTreeNode();
+        updateChildren(root, folder);
+    }
+
+    private void updateChildren(TreeNode node, Folder folder) {
+        for (int i=0; i<node.getChildCount(); i++) {
+            if (node.isChildOpen(i)) {
+                if (folder.equals(node.getChildValue(i))) {
+                    node.setChildOpen(i, false, true);
+                    node.setChildOpen(i, true, true);
+                }
+                else {
+                    TreeNode n = node.setChildOpen(i, true);
+                    updateChildren(n, folder);
+                }
+            }
+        }
+    }
+
     static interface BasicResources extends CellTree.Resources {
 
         @ImageOptions(flipRtl = true)
@@ -96,7 +117,6 @@ public class FolderTreeView extends Composite {
          */
         CellTree.Resources res = GWT.create(BasicResources.class);
         CellTree tree = new CellTree(model, null, res);
-
         tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
 
         initWidget(tree);
@@ -107,7 +127,7 @@ public class FolderTreeView extends Composite {
        return model.getSelection();
     }
 
-    public void updateFolder(Folder folder) {
-        model.updateFolder(folder);
+    public void updateFolder(Folder folder, boolean showfiles) {
+        model.updateFolder(folder, showfiles);
     }
 }
index 4c65304..95d471b 100644 (file)
@@ -37,13 +37,18 @@ package gr.grnet.pithos.web.client.foldertree;
 
 import com.google.gwt.cell.client.AbstractCell;
 import com.google.gwt.cell.client.Cell;
+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.ScheduledCommand;
 import com.google.gwt.event.dom.client.ContextMenuEvent;
 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.view.client.CellPreviewEvent;
+import com.google.gwt.view.client.CellPreviewEvent.Handler;
 import com.google.gwt.view.client.ListDataProvider;
+import com.google.gwt.view.client.ProvidesKey;
 import com.google.gwt.view.client.SingleSelectionModel;
 import com.google.gwt.view.client.TreeViewModel;
 import gr.grnet.pithos.web.client.FolderContextMenu;
@@ -107,10 +112,15 @@ public class FolderTreeViewModel implements TreeViewModel {
         else {
             final Folder f = (Folder) value;
             if (dataProviderMap.get(f) == null) {
-                dataProviderMap.put(f, new ListDataProvider<Folder>());
+                dataProviderMap.put(f, new ListDataProvider<Folder>(new ProvidesKey<Folder>() {
+                    @Override
+                    public Object getKey(Folder item) {
+                        return item;
+                    }
+                }));
             }
             final ListDataProvider<Folder> dataProvider = dataProviderMap.get(f);
-            fetchFolder(f, dataProvider);
+            fetchFolder(f, dataProvider, false);
             return new DefaultNodeInfo<Folder>(dataProvider, folderCell, selectionModel, null);
         }
     }
@@ -124,7 +134,7 @@ public class FolderTreeViewModel implements TreeViewModel {
         return false;
     }
 
-    private void fetchFolder(final Iterator<Folder> iter, final ListDataProvider<Folder> dataProvider, final Set<Folder> folders) {
+    private void fetchFolder(final Iterator<Folder> iter, final Command callback) {
         if (iter.hasNext()) {
             final Folder f = iter.next();
 
@@ -132,7 +142,7 @@ public class FolderTreeViewModel implements TreeViewModel {
             GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, app.getApiPath(), app.getUsername(), path, f) {
                 @Override
                 public void onSuccess(Folder result) {
-                    fetchFolder(iter, dataProvider, folders);
+                    fetchFolder(iter, callback);
                 }
 
                 @Override
@@ -147,52 +157,61 @@ public class FolderTreeViewModel implements TreeViewModel {
             getFolder.setHeader("X-Auth-Token", app.getToken());
             Scheduler.get().scheduleDeferred(getFolder);
         }
-        else {
-            dataProvider.getList().clear();
-            dataProvider.getList().addAll(folders);
-            if (dataProvider.equals(rootDataProvider)) {
-                selectionModel.setSelected(dataProvider.getList().get(0), true);
+        else if (callback != null)
+            callback.execute();
+    }
+
+    public void initialize(final AccountResource account) {
+        Iterator<Folder> iter = account.getContainers().iterator();
+        fetchFolder(iter, new Command() {
+            @Override
+            public void execute() {
+                rootDataProvider.getList().clear();
+                rootDataProvider.getList().addAll(account.getContainers());
+                selectionModel.setSelected(rootDataProvider.getList().get(0), true);
                 Folder f = new Folder("Trash");
                 f.setTrash(true);
                 f.setContainer("trash");
-                dataProvider.getList().add(f);
+                rootDataProvider.getList().add(f);
                 app.updateTags();
             }
-        }
-    }
-
-    public void initialize(AccountResource account) {
-        Iterator<Folder> iter = account.getContainers().iterator();
-        fetchFolder(iter, rootDataProvider, account.getContainers());
+        });
     }
 
     public Folder getSelection() {
         return selectionModel.getSelectedObject();
     }
 
-    public void updateFolder(Folder folder) {
+    public void updateFolder(Folder folder, boolean showfiles) {
         if (dataProviderMap.get(folder) == null) {
             dataProviderMap.put(folder, new ListDataProvider<Folder>());
         }
         final ListDataProvider<Folder> dataProvider = dataProviderMap.get(folder);
         if (!folder.isTrash())
-            fetchFolder(folder, dataProvider);
+            fetchFolder(folder, dataProvider, showfiles);
         else
             app.showFiles(folder);
     }
 
-    public void fetchFolder(final Folder f, final ListDataProvider<Folder> dataProvider) {
-        dataProvider.flush();
+    public void fetchFolder(final Folder f, final ListDataProvider<Folder> dataProvider, final boolean showfiles) {
         Scheduler.get().scheduleDeferred(new ScheduledCommand() {
             @Override
             public void execute() {
                 String path = "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + f.getPrefix();
                 GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, app.getApiPath(), app.getUsername(), path, f) {
                     @Override
-                    public void onSuccess(Folder result) {
-                        app.showFiles(result);
+                    public void onSuccess(final Folder result) {
+                        if (showfiles)
+                            app.showFiles(result);
                         Iterator<Folder> iter = result.getSubfolders().iterator();
-                        fetchFolder(iter, dataProvider, result.getSubfolders());
+                        fetchFolder(iter, new Command() {
+                            @Override
+                            public void execute() {
+                                dataProvider.getList().clear();
+                                dataProvider.getList().addAll(result.getSubfolders());
+                                app.getFolderTreeView().updateChildren(f);
+                            }
+                        });
                     }
 
                     @Override