Statistics
| Branch: | Tag: | Revision:

root / src / gr / grnet / pithos / web / client / Pithos.java @ 9ec085e2

History | View | Annotate | Download (44.3 kB)

1
/*
2
 * Copyright 2011-2012 GRNET S.A. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *
12
 *   2. Redistributions in binary form must reproduce the above
13
 *      copyright notice, this list of conditions and the following
14
 *      disclaimer in the documentation and/or other materials
15
 *      provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * The views and conclusions contained in the software and
31
 * documentation are those of the authors and should not be
32
 * interpreted as representing official policies, either expressed
33
 * or implied, of GRNET S.A.
34
 */
35
package gr.grnet.pithos.web.client;
36

    
37
import gr.grnet.pithos.web.client.commands.UploadFileCommand;
38
import gr.grnet.pithos.web.client.foldertree.AccountResource;
39
import gr.grnet.pithos.web.client.foldertree.File;
40
import gr.grnet.pithos.web.client.foldertree.Folder;
41
import gr.grnet.pithos.web.client.foldertree.FolderTreeView;
42
import gr.grnet.pithos.web.client.foldertree.FolderTreeViewModel;
43
import gr.grnet.pithos.web.client.foldertree.Resource;
44
import gr.grnet.pithos.web.client.grouptree.Group;
45
import gr.grnet.pithos.web.client.grouptree.GroupTreeView;
46
import gr.grnet.pithos.web.client.grouptree.GroupTreeViewModel;
47
import gr.grnet.pithos.web.client.mysharedtree.MysharedTreeView;
48
import gr.grnet.pithos.web.client.mysharedtree.MysharedTreeViewModel;
49
import gr.grnet.pithos.web.client.othersharedtree.OtherSharedTreeView;
50
import gr.grnet.pithos.web.client.othersharedtree.OtherSharedTreeViewModel;
51
import gr.grnet.pithos.web.client.rest.DeleteRequest;
52
import gr.grnet.pithos.web.client.rest.GetRequest;
53
import gr.grnet.pithos.web.client.rest.HeadRequest;
54
import gr.grnet.pithos.web.client.rest.PutRequest;
55
import gr.grnet.pithos.web.client.rest.RestException;
56

    
57
import java.util.ArrayList;
58
import java.util.Date;
59
import java.util.HashMap;
60
import java.util.Iterator;
61
import java.util.List;
62
import java.util.Set;
63

    
64
import org.apache.http.HttpStatus;
65

    
66
import com.google.gwt.core.client.EntryPoint;
67
import com.google.gwt.core.client.GWT;
68
import com.google.gwt.core.client.JsArrayString;
69
import com.google.gwt.core.client.Scheduler;
70
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
71
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
72
import com.google.gwt.event.dom.client.ClickEvent;
73
import com.google.gwt.event.dom.client.ClickHandler;
74
import com.google.gwt.event.logical.shared.ResizeEvent;
75
import com.google.gwt.event.logical.shared.ResizeHandler;
76
import com.google.gwt.http.client.Response;
77
import com.google.gwt.http.client.URL;
78
import com.google.gwt.i18n.client.DateTimeFormat;
79
import com.google.gwt.i18n.client.Dictionary;
80
import com.google.gwt.i18n.client.TimeZone;
81
import com.google.gwt.resources.client.ClientBundle;
82
import com.google.gwt.resources.client.CssResource;
83
import com.google.gwt.resources.client.ImageResource;
84
import com.google.gwt.resources.client.ImageResource.ImageOptions;
85
import com.google.gwt.user.client.Command;
86
import com.google.gwt.user.client.Cookies;
87
import com.google.gwt.user.client.Event;
88
import com.google.gwt.user.client.History;
89
import com.google.gwt.user.client.Window;
90
import com.google.gwt.user.client.ui.AbstractImagePrototype;
91
import com.google.gwt.user.client.ui.Button;
92
import com.google.gwt.user.client.ui.Composite;
93
import com.google.gwt.user.client.ui.FlowPanel;
94
import com.google.gwt.user.client.ui.HTML;
95
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
96
import com.google.gwt.user.client.ui.HasVerticalAlignment;
97
import com.google.gwt.user.client.ui.HorizontalPanel;
98
import com.google.gwt.user.client.ui.HorizontalSplitPanel;
99
import com.google.gwt.user.client.ui.PopupPanel;
100
import com.google.gwt.user.client.ui.RootPanel;
101
import com.google.gwt.user.client.ui.VerticalPanel;
102
import com.google.gwt.view.client.SelectionChangeEvent;
103
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
104
import com.google.gwt.view.client.SingleSelectionModel;
105

    
106
/**
107
 * Entry point classes define <code>onModuleLoad()</code>.
108
 */
109
public class Pithos implements EntryPoint, ResizeHandler {
110

    
111
        public static final String HOME_CONTAINER = "pithos";
112

    
113
        public static final String TRASH_CONTAINER = "trash";
114

    
115
        public static final Configuration config = GWT.create(Configuration.class);
116
        
117
        public interface Style extends CssResource {
118
                String commandAnchor();
119
                
120
                String statistics();
121
                
122
                @ClassName("gwt-HTML")
123
                String html();
124
                
125
                String uploadAlert();
126

    
127
                String uploadAlertLink();
128

    
129
                String uploadAlertProgress();
130
                
131
                String uploadAlertPercent();
132
                
133
                String uploadAlertClose();
134
        }
135
        
136
        public interface Resources extends ClientBundle {
137
                @Source("Pithos.css")
138
                Style pithosCss();
139
                
140
                @Source("gr/grnet/pithos/resources/close-popup.png")
141
                ImageResource closePopup();
142
        }
143

    
144
        public static Resources resources = GWT.create(Resources.class);
145
        
146
        /**
147
         * Instantiate an application-level image bundle. This object will provide
148
         * programmatic access to all the images needed by widgets.
149
         */
150
        static Images images = (Images) GWT.create(Images.class);
151

    
152
    public String getUsername() {
153
        return username;
154
    }
155

    
156
    public void setAccount(AccountResource acct) {
157
        account = acct;
158
    }
159

    
160
    public AccountResource getAccount() {
161
        return account;
162
    }
163

    
164
    public void updateFolder(Folder f, boolean showfiles, Command callback, final boolean openParent) {
165
        folderTreeView.updateFolder(f, showfiles, callback, openParent);
166
    }
167

    
168
    public void updateGroupNode(Group group) {
169
        groupTreeView.updateGroupNode(group);
170
    }
171

    
172
    public void updateMySharedRoot() {
173
            mysharedTreeView.updateRoot();
174
    }
175
    
176
    public void updateSharedFolder(Folder f, boolean showfiles, Command callback) {
177
            mysharedTreeView.updateFolder(f, showfiles, callback);
178
    }
179
    
180
    public void updateSharedFolder(Folder f, boolean showfiles) {
181
            updateSharedFolder(f, showfiles, null);
182
    }
183

    
184
    public void updateOtherSharedFolder(Folder f, boolean showfiles, Command callback) {
185
            otherSharedTreeView.updateFolder(f, showfiles, callback);
186
    }
187

    
188
    public MysharedTreeView getMySharedTreeView() {
189
        return mysharedTreeView;
190
    }
191

    
192
    /**
193
         * An aggregate image bundle that pulls together all the images for this
194
         * application into a single bundle.
195
         */
196
        public interface Images extends TopPanel.Images, FileList.Images, ToolsMenu.Images {
197

    
198
                @Source("gr/grnet/pithos/resources/document.png")
199
                ImageResource folders();
200

    
201
                @Source("gr/grnet/pithos/resources/advancedsettings.png")
202
                @ImageOptions(width=32, height=32)
203
                ImageResource tools();
204
        }
205

    
206
        private Throwable error;
207
        
208
        /**
209
         * The Application Clipboard implementation;
210
         */
211
        private Clipboard clipboard = new Clipboard();
212

    
213
        /**
214
         * The top panel that contains the menu bar.
215
         */
216
        private TopPanel topPanel;
217

    
218
        /**
219
         * The panel that contains the various system messages.
220
         */
221
        private MessagePanel messagePanel = new MessagePanel(this, Pithos.images);
222

    
223
        /**
224
         * The bottom panel that contains the status bar.
225
         */
226
        StatusPanel statusPanel = null;
227

    
228
        /**
229
         * The file list widget.
230
         */
231
        private FileList fileList;
232

    
233
        /**
234
         * The tab panel that occupies the right side of the screen.
235
         */
236
        private VerticalPanel inner = new VerticalPanel();
237

    
238

    
239
        /**
240
         * The split panel that will contain the left and right panels.
241
         */
242
        private HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
243

    
244
        /**
245
         * The currently selected item in the application, for use by the Edit menu
246
         * commands. Potential types are Folder, File, User and Group.
247
         */
248
        private Object currentSelection;
249

    
250
        public HashMap<String, String> userFullNameMap = new HashMap<String, String>();
251

    
252
    private String username = null;
253

    
254
    /**
255
     * The authentication token of the current user.
256
     */
257
    private String token;
258

    
259
    VerticalPanel trees;
260
    
261
    SingleSelectionModel<Folder> folderTreeSelectionModel;
262
    FolderTreeViewModel folderTreeViewModel;
263
    FolderTreeView folderTreeView;
264

    
265
    SingleSelectionModel<Folder> mysharedTreeSelectionModel;
266
    MysharedTreeViewModel mysharedTreeViewModel;
267
    MysharedTreeView mysharedTreeView = null;;
268

    
269
    protected SingleSelectionModel<Folder> otherSharedTreeSelectionModel;
270
    OtherSharedTreeViewModel otherSharedTreeViewModel;
271
    OtherSharedTreeView otherSharedTreeView = null;
272

    
273
    GroupTreeViewModel groupTreeViewModel;
274
    GroupTreeView groupTreeView;
275

    
276
    TreeView selectedTree;
277
    protected AccountResource account;
278
    
279
    Folder trash;
280
    
281
    List<Composite> treeViews = new ArrayList<Composite>();
282

    
283
    @SuppressWarnings("rawtypes") List<SingleSelectionModel> selectionModels = new ArrayList<SingleSelectionModel>();
284
    
285
    public Button upload;
286
    
287
    private HTML numOfFiles;
288
    
289
    private Toolbar toolbar;
290
    
291
    private FileUploadDialog fileUploadDialog = new FileUploadDialog(this);
292

    
293
        UploadAlert uploadAlert;
294
        
295
        Date lastModified;
296

    
297
        @Override
298
        public void onModuleLoad() {
299
                if (parseUserCredentials())
300
            initialize();
301
        }
302

    
303
    private void initialize() {
304
            lastModified = new Date(); //Initialize if-modified-since value with now.
305
            resources.pithosCss().ensureInjected();
306
            boolean bareContent = Window.Location.getParameter("noframe") != null;
307
            String contentWidth = bareContent ? "100%" : "75%";
308

    
309
            VerticalPanel outer = new VerticalPanel();
310
        outer.setWidth("100%");
311
            if (!bareContent) {
312
                    outer.addStyleName("pithos-outer");
313
            }
314

    
315
        if (!bareContent) {
316
                topPanel = new TopPanel(this, Pithos.images);
317
                topPanel.setWidth("100%");
318
                outer.add(topPanel);
319
                outer.setCellHorizontalAlignment(topPanel, HasHorizontalAlignment.ALIGN_CENTER);
320
        }
321
        
322
        messagePanel.setVisible(false);
323
        outer.add(messagePanel);
324
        outer.setCellHorizontalAlignment(messagePanel, HasHorizontalAlignment.ALIGN_CENTER);
325
        outer.setCellVerticalAlignment(messagePanel, HasVerticalAlignment.ALIGN_MIDDLE);
326

    
327
        HorizontalPanel header = new HorizontalPanel();
328
        header.addStyleName("pithos-header");
329
        header.setWidth(contentWidth);
330
        if (bareContent)
331
                header.addStyleName("pithos-header-noframe");
332
        upload = new Button("Upload", new ClickHandler() {
333
            @Override
334
            public void onClick(ClickEvent event) {
335
                    if (getSelection() != null)
336
                            new UploadFileCommand(Pithos.this, null, getSelection()).execute();
337
            }
338
        });
339
        upload.addStyleName("pithos-uploadButton");
340
        header.add(upload);
341
        header.setCellHorizontalAlignment(upload, HasHorizontalAlignment.ALIGN_LEFT);
342
        header.setCellVerticalAlignment(upload, HasVerticalAlignment.ALIGN_MIDDLE);
343

    
344
        toolbar = new Toolbar(this);
345
        header.add(toolbar);
346
        header.setCellHorizontalAlignment(toolbar, HasHorizontalAlignment.ALIGN_CENTER);
347
        header.setCellVerticalAlignment(toolbar, HasVerticalAlignment.ALIGN_MIDDLE);
348
        
349
        HorizontalPanel folderStatistics = new HorizontalPanel();
350
        folderStatistics.addStyleName("pithos-folderStatistics");
351
        numOfFiles = new HTML();
352
        folderStatistics.add(numOfFiles);
353
        folderStatistics.setCellVerticalAlignment(numOfFiles, HasVerticalAlignment.ALIGN_MIDDLE);
354
        HTML numOfFilesLabel = new HTML("&nbsp;Files");
355
        folderStatistics.add(numOfFilesLabel);
356
        folderStatistics.setCellVerticalAlignment(numOfFilesLabel, HasVerticalAlignment.ALIGN_MIDDLE);
357
        header.add(folderStatistics);
358
        header.setCellHorizontalAlignment(folderStatistics, HasHorizontalAlignment.ALIGN_RIGHT);
359
        header.setCellVerticalAlignment(folderStatistics, HasVerticalAlignment.ALIGN_MIDDLE);
360
        header.setCellWidth(folderStatistics, "40px");
361
        outer.add(header);
362
        outer.setCellHorizontalAlignment(header, HasHorizontalAlignment.ALIGN_CENTER);
363
        // Inner contains the various lists
364
        inner.sinkEvents(Event.ONCONTEXTMENU);
365
        inner.setWidth("100%");
366

    
367
        folderTreeSelectionModel = new SingleSelectionModel<Folder>();
368
        folderTreeSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
369
            @Override
370
            public void onSelectionChange(SelectionChangeEvent event) {
371
                if (folderTreeSelectionModel.getSelectedObject() != null) {
372
                    deselectOthers(folderTreeView, folderTreeSelectionModel);
373
                    applyPermissions(folderTreeSelectionModel.getSelectedObject());
374
                    Folder f = folderTreeSelectionModel.getSelectedObject();
375
                            updateFolder(f, true, new Command() {
376
                                    
377
                                    @Override
378
                                    public void execute() {
379
                                            updateStatistics();
380
                                    }
381
                            }, true);
382
                            showRelevantToolbarButtons();
383
                }
384
                                else {
385
                                        if (getSelectedTree().equals(folderTreeView))
386
                                                setSelectedTree(null);
387
                                        if (getSelectedTree() == null)
388
                                                showRelevantToolbarButtons();
389
                                }
390
            }
391
        });
392
        selectionModels.add(folderTreeSelectionModel);
393

    
394
        folderTreeViewModel = new FolderTreeViewModel(this, folderTreeSelectionModel);
395
        folderTreeView = new FolderTreeView(folderTreeViewModel);
396
        treeViews.add(folderTreeView);
397
        
398
        fileList = new FileList(this, images);
399
        inner.add(fileList);
400

    
401
        trees = new VerticalPanel();
402
        trees.setWidth("100%");
403
        
404
        // Add the left and right panels to the split panel.
405
        splitPanel.setLeftWidget(trees);
406
        FlowPanel right = new FlowPanel();
407
        right.getElement().setId("rightPanel");
408
        right.add(inner);
409
        splitPanel.setRightWidget(right);
410
        splitPanel.setSplitPosition("219px");
411
        splitPanel.setSize("100%", "100%");
412
        splitPanel.addStyleName("pithos-splitPanel");
413
        splitPanel.setWidth(contentWidth);
414
        outer.add(splitPanel);
415
        outer.setCellHorizontalAlignment(splitPanel, HasHorizontalAlignment.ALIGN_CENTER);
416

    
417
        if (!bareContent) {
418
                statusPanel = new StatusPanel();
419
                statusPanel.setWidth("100%");
420
                outer.add(statusPanel);
421
                outer.setCellHorizontalAlignment(statusPanel, HasHorizontalAlignment.ALIGN_CENTER);
422
        }
423
        else
424
                splitPanel.addStyleName("pithos-splitPanel-noframe");
425

    
426
        // Hook the window resize event, so that we can adjust the UI.
427
        Window.addResizeHandler(this);
428
        // Clear out the window's built-in margin, because we want to take
429
        // advantage of the entire client area.
430
        Window.setMargin("0px");
431
        // Finally, add the outer panel to the RootPanel, so that it will be
432
        // displayed.
433
        RootPanel.get().add(outer);
434
        // Call the window resized handler to get the initial sizes setup. Doing
435
        // this in a deferred command causes it to occur after all widgets'
436
        // sizes have been computed by the browser.
437
        Scheduler.get().scheduleIncremental(new RepeatingCommand() {
438
                        
439
                        @Override
440
                        public boolean execute() {
441
                                if (!isCloudbarReady())
442
                                        return true;
443
                onWindowResized(Window.getClientHeight());
444
                                return false;
445
                        }
446
                });
447
        
448
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
449
            @Override
450
            public void execute() {
451
                fetchAccount(new Command() {
452
                                        
453
                                        @Override
454
                                        public void execute() {
455
                                if (!account.hasHomeContainer())
456
                                    createHomeContainer(account, this);
457
                                else if (!account.hasTrashContainer())
458
                                        createTrashContainer(this);
459
                                else {
460
                                        for (Folder f : account.getContainers())
461
                                                if (f.getName().equals(Pithos.TRASH_CONTAINER)) {
462
                                                        trash = f;
463
                                                        break;
464
                                                }
465
                                    trees.add(folderTreeView);
466
                                    folderTreeViewModel.initialize(account, new Command() {
467
                                                                
468
                                                                @Override
469
                                                                public void execute() {
470
                                                    createMySharedTree();
471
                                                                }
472
                                                        });
473

    
474
                                    HorizontalPanel separator = new HorizontalPanel();
475
                                    separator.addStyleName("pithos-statisticsSeparator");
476
                                    separator.add(new HTML(""));
477
                                    trees.add(separator);
478

    
479
                                    groupTreeViewModel = new GroupTreeViewModel(Pithos.this);
480
                                    groupTreeView = new GroupTreeView(groupTreeViewModel);
481
                                    treeViews.add(groupTreeView);
482
                                    trees.add(groupTreeView);
483
                                    folderTreeView.showStatistics(account);
484
                                }
485
                                        }
486
                                });
487
            }
488
        });
489
    }
490
    
491
    public void scheduleResfresh() {
492
                Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
493
                        
494
                        @Override
495
                        public boolean execute() {
496
                                final Folder f = getSelection();
497
                                if (f == null)
498
                                        return true;
499
                                
500
                            HeadRequest<Folder> head = new HeadRequest<Folder>(Folder.class, getApiPath(), getUsername(), "/" + f.getContainer()) {
501

    
502
                                        @Override
503
                                        public void onSuccess(Folder _result) {
504
                                                lastModified = new Date();
505
                                                if (getSelectedTree().equals(folderTreeView))
506
                                                        updateFolder(f, true, new Command() {
507
        
508
                                                                @Override
509
                                                                public void execute() {
510
                                                                        scheduleResfresh();
511
                                                                }
512
                                                                
513
                                                        }, false);
514
                                                else if (getSelectedTree().equals(mysharedTreeView))
515
                                                        updateSharedFolder(f, true, new Command() {
516
        
517
                                                                @Override
518
                                                                public void execute() {
519
                                                                        scheduleResfresh();
520
                                                                }
521
                                                        });
522
                                        }
523

    
524
                                        @Override
525
                                        public void onError(Throwable t) {
526
                                                if (t instanceof RestException && ((RestException) t).getHttpStatusCode() == HttpStatus.SC_NOT_MODIFIED)
527
                                                        scheduleResfresh();
528
                                                else if (retries >= MAX_RETRIES) {
529
                                        GWT.log("Error heading folder", t);
530
                                                        setError(t);
531
                                        if (t instanceof RestException)
532
                                            displayError("Error heading folder: " + ((RestException) t).getHttpStatusText());
533
                                        else
534
                                            displayError("System error heading folder: " + t.getMessage());
535
                                    }
536
                                    else {//retry
537
                                            GWT.log("Retry " + retries);
538
                                            Scheduler.get().scheduleDeferred(this);
539
                                    }
540
                                        }
541

    
542
                                        @Override
543
                                        protected void onUnauthorized(Response response) {
544
                                                if (retries >= MAX_RETRIES)
545
                                                        sessionExpired();
546
                                    else //retry
547
                                            Scheduler.get().scheduleDeferred(this);
548
                                        }
549
                                };
550
                                head.setHeader("X-Auth-Token", getToken());
551
                                head.setHeader("If-Modified-Since", DateTimeFormat.getFormat("EEE, dd MMM yyyy HH:mm:ss").format(lastModified, TimeZone.createTimeZone(0)) + " GMT");
552
                                Scheduler.get().scheduleDeferred(head);
553
                                
554
                                return false;
555
                        }
556
                }, 3000);
557
    }
558

    
559
    public void applyPermissions(Folder f) {
560
            if (f != null) {
561
                    if (f.isInTrash()) {
562
                            upload.setEnabled(false);
563
                            disableUploadArea();
564
                    }
565
                    else {
566
                            Boolean[] perms = f.getPermissions().get(username);
567
                            if (f.getOwner().equals(username) || (perms != null && perms[1] != null && perms[1])) {
568
                                    upload.setEnabled(true);
569
                                    enableUploadArea();
570
                            }
571
                            else {
572
                                    upload.setEnabled(false);
573
                                    disableUploadArea();
574
                            }
575
                    }
576
            }
577
            else {
578
                    upload.setEnabled(false);
579
                    disableUploadArea();
580
            }
581
        }
582

    
583
        @SuppressWarnings({ "rawtypes", "unchecked" })
584
        public void deselectOthers(TreeView _selectedTree, SingleSelectionModel model) {
585
            selectedTree = _selectedTree;
586
            
587
        for (SingleSelectionModel s : selectionModels)
588
            if (!s.equals(model) && s.getSelectedObject() != null)
589
                s.setSelected(s.getSelectedObject(), false);
590
    }
591

    
592
    public void showFiles(final Folder f) {
593
        Set<File> files = f.getFiles();
594
        showFiles(files);
595
    }
596

    
597
    public void showFiles(Set<File> files) {
598
        fileList.setFiles(new ArrayList<File>(files));
599
    }
600

    
601
    /**
602
         * Parse and store the user credentials to the appropriate fields.
603
         */
604
        private boolean parseUserCredentials() {
605
        Configuration conf = (Configuration) GWT.create(Configuration.class);
606
                Dictionary otherProperties = Dictionary.getDictionary("otherProperties");
607
        String cookie = otherProperties.get("authCookie");
608
        String auth = Cookies.getCookie(cookie);
609
        if (auth == null) {
610
            authenticateUser();
611
            return false;
612
        }
613
        if (auth.startsWith("\""))
614
                auth = auth.substring(1);
615
        if (auth.endsWith("\""))
616
                auth = auth.substring(0, auth.length() - 1);
617
                String[] authSplit = auth.split("\\" + conf.cookieSeparator(), 2);
618
                if (authSplit.length != 2) {
619
                    authenticateUser();
620
                    return false;
621
                }
622
                username = authSplit[0];
623
                token = authSplit[1];
624

    
625
        String gotoUrl = Window.Location.getParameter("goto");
626
                if (gotoUrl != null && gotoUrl.length() > 0) {
627
                        Window.Location.assign(gotoUrl);
628
                        return false;
629
                }
630
                return true;
631
    }
632

    
633
    /**
634
         * Redirect the user to the login page for authentication.
635
         */
636
        protected void authenticateUser() {
637
                Dictionary otherProperties = Dictionary.getDictionary("otherProperties");
638
        Window.Location.assign(otherProperties.get("loginUrl") + Window.Location.getHref());
639
        }
640

    
641
        public void fetchAccount(final Command callback) {
642
        String path = "?format=json";
643

    
644
        GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, getApiPath(), username, path) {
645
            @Override
646
            public void onSuccess(AccountResource _result) {
647
                account = _result;
648
                if (callback != null)
649
                        callback.execute();
650
            }
651

    
652
            @Override
653
            public void onError(Throwable t) {
654
                GWT.log("Error getting account", t);
655
                                setError(t);
656
                if (t instanceof RestException)
657
                    displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
658
                else
659
                    displayError("System error fetching user data: " + t.getMessage());
660
            }
661

    
662
                        @Override
663
                        protected void onUnauthorized(Response response) {
664
                                sessionExpired();
665
                        }
666
        };
667
        getAccount.setHeader("X-Auth-Token", token);
668
        Scheduler.get().scheduleDeferred(getAccount);
669
    }
670

    
671
    public void updateStatistics() {
672
            HeadRequest<AccountResource> headAccount = new HeadRequest<AccountResource>(AccountResource.class, getApiPath(), username, "", account) {
673

    
674
                        @Override
675
                        public void onSuccess(AccountResource _result) {
676
                                folderTreeView.showStatistics(account);
677
                        }
678

    
679
                        @Override
680
                        public void onError(Throwable t) {
681
                GWT.log("Error getting account", t);
682
                                setError(t);
683
                if (t instanceof RestException)
684
                    displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
685
                else
686
                    displayError("System error fetching user data: " + t.getMessage());
687
                        }
688

    
689
                        @Override
690
                        protected void onUnauthorized(Response response) {
691
                                sessionExpired();
692
                        }
693
                };
694
                headAccount.setHeader("X-Auth-Token", token);
695
                Scheduler.get().scheduleDeferred(headAccount);
696
        }
697

    
698
        protected void createHomeContainer(final AccountResource _account, final Command callback) {
699
        String path = "/" + Pithos.HOME_CONTAINER;
700
        PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) {
701
            @Override
702
            public void onSuccess(Resource result) {
703
                    if (!_account.hasTrashContainer())
704
                            createTrashContainer(callback);
705
                    else
706
                            fetchAccount(callback);
707
            }
708

    
709
            @Override
710
            public void onError(Throwable t) {
711
                GWT.log("Error creating pithos", t);
712
                                setError(t);
713
                if (t instanceof RestException)
714
                    displayError("Error creating pithos: " + ((RestException) t).getHttpStatusText());
715
                else
716
                    displayError("System error Error creating pithos: " + t.getMessage());
717
            }
718

    
719
                        @Override
720
                        protected void onUnauthorized(Response response) {
721
                                sessionExpired();
722
                        }
723
        };
724
        createPithos.setHeader("X-Auth-Token", getToken());
725
        Scheduler.get().scheduleDeferred(createPithos);
726
    }
727

    
728
    protected void createTrashContainer(final Command callback) {
729
        String path = "/" + Pithos.TRASH_CONTAINER;
730
        PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) {
731
            @Override
732
            public void onSuccess(Resource result) {
733
                           fetchAccount(callback);
734
            }
735

    
736
            @Override
737
            public void onError(Throwable t) {
738
                GWT.log("Error creating pithos", t);
739
                                setError(t);
740
                if (t instanceof RestException)
741
                    displayError("Error creating pithos: " + ((RestException) t).getHttpStatusText());
742
                else
743
                    displayError("System error Error creating pithos: " + t.getMessage());
744
            }
745

    
746
                        @Override
747
                        protected void onUnauthorized(Response response) {
748
                                sessionExpired();
749
                        }
750
        };
751
        createPithos.setHeader("X-Auth-Token", getToken());
752
        Scheduler.get().scheduleDeferred(createPithos);
753
    }
754

    
755
    /**
756
         * Creates an HTML fragment that places an image & caption together, for use
757
         * in a group header.
758
         *
759
         * @param imageProto an image prototype for an image
760
         * @param caption the group caption
761
         * @return the header HTML fragment
762
         */
763
        private String createHeaderHTML(AbstractImagePrototype imageProto, String caption) {
764
                String captionHTML = "<table class='caption' cellpadding='0' " 
765
                + "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML() 
766
                + "</td><td id =" + caption +" class='rcaption'><b style='white-space:nowrap'>&nbsp;" 
767
                + caption + "</b></td></tr></table>";
768
                return captionHTML;
769
        }
770

    
771
        protected void onWindowResized(int height) {
772
                // Adjust the split panel to take up the available room in the window.
773
                int newHeight = height - splitPanel.getAbsoluteTop() - 153;
774
                if (newHeight < 1)
775
                        newHeight = 1;
776
                splitPanel.setHeight("" + newHeight);
777
                inner.setHeight("" + newHeight);
778
        }
779
        
780
        native boolean isCloudbarReady()/*-{
781
                if ($wnd.$("div.servicesbar") && $wnd.$("div.servicesbar").height() > 0)
782
                        return true;
783
                return false;
784
        }-*/;
785
        
786
        @Override
787
        public void onResize(ResizeEvent event) {
788
                int height = event.getHeight();
789
                onWindowResized(height);
790
        }
791

    
792
        /**
793
         * Display an error message.
794
         *
795
         * @param msg the message to display
796
         */
797
        public void displayError(String msg) {
798
                messagePanel.displayError(msg);
799
                onWindowResized(Window.getClientHeight());
800
        }
801

    
802
        /**
803
         * Display a warning message.
804
         *
805
         * @param msg the message to display
806
         */
807
        public void displayWarning(String msg) {
808
                messagePanel.displayWarning(msg);
809
                onWindowResized(Window.getClientHeight());
810
        }
811

    
812
        /**
813
         * Display an informational message.
814
         *
815
         * @param msg the message to display
816
         */
817
        public void displayInformation(String msg) {
818
                messagePanel.displayInformation(msg);
819
                onWindowResized(Window.getClientHeight());
820
        }
821

    
822
        /**
823
         * Retrieve the fileList.
824
         *
825
         * @return the fileList
826
         */
827
        public FileList getFileList() {
828
                return fileList;
829
        }
830

    
831
        /**
832
         * Retrieve the topPanel.
833
         *
834
         * @return the topPanel
835
         */
836
        TopPanel getTopPanel() {
837
                return topPanel;
838
        }
839

    
840
        /**
841
         * Retrieve the clipboard.
842
         *
843
         * @return the clipboard
844
         */
845
        public Clipboard getClipboard() {
846
                return clipboard;
847
        }
848

    
849
        public StatusPanel getStatusPanel() {
850
                return statusPanel;
851
        }
852

    
853
        public String getToken() {
854
                return token;
855
        }
856

    
857
        public static native void preventIESelection() /*-{
858
                $doc.body.onselectstart = function() {
859
                        return false;
860
                };
861
        }-*/;
862

    
863
        public static native void enableIESelection() /*-{
864
                if ($doc.body.onselectstart != null)
865
                        $doc.body.onselectstart = null;
866
        }-*/;
867

    
868
        /**
869
         * @return the absolute path of the API root URL
870
         */
871
        public String getApiPath() {
872
                Configuration conf = (Configuration) GWT.create(Configuration.class);
873
                return conf.apiPath();
874
        }
875

    
876
        /**
877
         * History support for folder navigation
878
         * adds a new browser history entry
879
         *
880
         * @param key
881
         */
882
        public void updateHistory(String key){
883
//                Replace any whitespace of the initial string to "+"
884
//                String result = key.replaceAll("\\s","+");
885
//                Add a new browser history entry.
886
//                History.newItem(result);
887
                History.newItem(key);
888
        }
889

    
890
    public void deleteFolder(final Folder folder, final Command callback) {
891
            final PleaseWaitPopup pwp = new PleaseWaitPopup();
892
            pwp.center();
893
        String path = "/" + folder.getContainer() + "/" + folder.getPrefix() + "?delimiter=/" + "&t=" + System.currentTimeMillis();
894
        DeleteRequest deleteFolder = new DeleteRequest(getApiPath(), folder.getOwner(), path) {
895
                        
896
                        @Override
897
                        protected void onUnauthorized(Response response) {
898
                                pwp.hide();
899
                                sessionExpired();
900
                        }
901
                        
902
                        @Override
903
                        public void onSuccess(Resource result) {
904
                updateFolder(folder.getParent(), true, new Command() {
905
                                        
906
                                        @Override
907
                                        public void execute() {
908
                                                folderTreeSelectionModel.setSelected(folder.getParent(), true);
909
                                                updateStatistics();
910
                                                if (callback != null)
911
                                                        callback.execute();
912
                                                pwp.hide();
913
                                        }
914
                                }, true);
915
                        }
916
                        
917
                        @Override
918
                        public void onError(Throwable t) {
919
                GWT.log("", t);
920
                                setError(t);
921
                if (t instanceof RestException) {
922
                        if (((RestException) t).getHttpStatusCode() != Response.SC_NOT_FOUND)
923
                                displayError("Unable to delete folder: "+((RestException) t).getHttpStatusText());
924
                        else
925
                                onSuccess(null);
926
                }
927
                else
928
                    displayError("System error unable to delete folder: " + t.getMessage());
929
                                pwp.hide();
930
                        }
931
                };
932
                deleteFolder.setHeader("X-Auth-Token", getToken());
933
                Scheduler.get().scheduleDeferred(deleteFolder);
934
    }
935

    
936
    public FolderTreeView getFolderTreeView() {
937
        return folderTreeView;
938
    }
939

    
940
    public void copyFiles(final Iterator<File> iter, final String targetUsername, final String targetUri, final Command callback) {
941
        if (iter.hasNext()) {
942
            File file = iter.next();
943
            String path = targetUri + "/" + file.getName();
944
            PutRequest copyFile = new PutRequest(getApiPath(), targetUsername, path) {
945
                @Override
946
                public void onSuccess(Resource result) {
947
                    copyFiles(iter, targetUsername, targetUri, callback);
948
                }
949

    
950
                @Override
951
                public void onError(Throwable t) {
952
                    GWT.log("", t);
953
                                        setError(t);
954
                    if (t instanceof RestException) {
955
                        displayError("Unable to copy file: " + ((RestException) t).getHttpStatusText());
956
                    }
957
                    else
958
                        displayError("System error unable to copy file: "+t.getMessage());
959
                }
960

    
961
                                @Override
962
                                protected void onUnauthorized(Response response) {
963
                                        sessionExpired();
964
                                }
965
            };
966
            copyFile.setHeader("X-Auth-Token", getToken());
967
            copyFile.setHeader("X-Copy-From", URL.encodePathSegment(file.getUri()));
968
            if (!file.getOwner().equals(targetUsername))
969
                    copyFile.setHeader("X-Source-Account", URL.encodePathSegment(file.getOwner()));
970
            copyFile.setHeader("Content-Type", file.getContentType());
971
            Scheduler.get().scheduleDeferred(copyFile);
972
        }
973
        else  if (callback != null) {
974
            callback.execute();
975
        }
976
    }
977

    
978
    public void copyFolder(final Folder f, final String targetUsername, final String targetUri, boolean move, final Command callback) {
979
        String path = targetUri + "?delimiter=/";
980
        PutRequest copyFolder = new PutRequest(getApiPath(), targetUsername, path) {
981
            @Override
982
            public void onSuccess(Resource result) {
983
                    if (callback != null)
984
                            callback.execute();
985
            }
986

    
987
            @Override
988
            public void onError(Throwable t) {
989
                GWT.log("", t);
990
                                setError(t);
991
               if (t instanceof RestException) {
992
                    displayError("Unable to copy folder: " + ((RestException) t).getHttpStatusText());
993
                }
994
                else
995
                    displayError("System error copying folder: " + t.getMessage());
996
            }
997

    
998
                        @Override
999
                        protected void onUnauthorized(Response response) {
1000
                                sessionExpired();
1001
                        }
1002
        };
1003
        copyFolder.setHeader("X-Auth-Token", getToken());
1004
        copyFolder.setHeader("Accept", "*/*");
1005
        copyFolder.setHeader("Content-Length", "0");
1006
        copyFolder.setHeader("Content-Type", "application/directory");
1007
        if (!f.getOwner().equals(targetUsername))
1008
                copyFolder.setHeader("X-Source-Account", f.getOwner());
1009
        if (move)
1010
            copyFolder.setHeader("X-Move-From", URL.encodePathSegment(f.getUri()));
1011
        else
1012
                copyFolder.setHeader("X-Copy-From", URL.encodePathSegment(f.getUri()));
1013
        Scheduler.get().scheduleDeferred(copyFolder);
1014
    }
1015
    
1016
    public void addSelectionModel(@SuppressWarnings("rawtypes") SingleSelectionModel model) {
1017
            selectionModels.add(model);
1018
    }
1019

    
1020
        public OtherSharedTreeView getOtherSharedTreeView() {
1021
                return otherSharedTreeView;
1022
        }
1023

    
1024
        public void updateTrash(boolean showFiles, Command callback) {
1025
                updateFolder(trash, showFiles, callback, true);
1026
        }
1027

    
1028
        public void updateGroupsNode() {
1029
                groupTreeView.updateGroupNode(null);
1030
        }
1031

    
1032
        public Group addGroup(String groupname) {
1033
                Group newGroup = new Group(groupname);
1034
                account.addGroup(newGroup);
1035
                groupTreeView.updateGroupNode(null);
1036
                return newGroup;
1037
        }
1038

    
1039
        public void removeGroup(Group group) {
1040
                account.removeGroup(group);
1041
                updateGroupsNode();
1042
        }
1043

    
1044
        public TreeView getSelectedTree() {
1045
                return selectedTree;
1046
        }
1047
        
1048
        public void setSelectedTree(TreeView selected) {
1049
                selectedTree = selected;
1050
        }
1051

    
1052
        public Folder getSelection() {
1053
                if (selectedTree != null)
1054
                        return selectedTree.getSelection();
1055
                return null;
1056
        }
1057

    
1058
        public void showFolderStatistics(int folderFileCount) {
1059
                numOfFiles.setHTML(String.valueOf(folderFileCount));
1060
        }
1061

    
1062
        public GroupTreeView getGroupTreeView() {
1063
                return groupTreeView;
1064
        }
1065

    
1066
        public void sessionExpired() {
1067
                new SessionExpiredDialog(this).center();
1068
        }
1069

    
1070
        public void updateRootFolder(Command callback) {
1071
                updateFolder(account.getPithos(), false, callback, true);
1072
        }
1073

    
1074
        void createMySharedTree() {
1075
                mysharedTreeSelectionModel = new SingleSelectionModel<Folder>();
1076
                mysharedTreeSelectionModel.addSelectionChangeHandler(new Handler() {
1077
                    @Override
1078
                    public void onSelectionChange(SelectionChangeEvent event) {
1079
                        if (mysharedTreeSelectionModel.getSelectedObject() != null) {
1080
                            deselectOthers(mysharedTreeView, mysharedTreeSelectionModel);
1081
                            upload.setEnabled(false);
1082
                            disableUploadArea();
1083
                            updateSharedFolder(mysharedTreeSelectionModel.getSelectedObject(), true);
1084
                                        showRelevantToolbarButtons();
1085
                        }
1086
                                else {
1087
                                        if (getSelectedTree().equals(mysharedTreeView))
1088
                                                setSelectedTree(null);
1089
                                        if (getSelectedTree() == null)
1090
                                                showRelevantToolbarButtons();
1091
                                }
1092
                     }
1093
                });
1094
                selectionModels.add(mysharedTreeSelectionModel);
1095
                mysharedTreeViewModel = new MysharedTreeViewModel(Pithos.this, mysharedTreeSelectionModel);
1096
                mysharedTreeViewModel.initialize(new Command() {
1097
                        
1098
                        @Override
1099
                        public void execute() {
1100
                            mysharedTreeView = new MysharedTreeView(mysharedTreeViewModel);
1101
                                trees.insert(mysharedTreeView, 2);
1102
                                treeViews.add(mysharedTreeView);
1103
                                createOtherSharedTree();
1104
                        }
1105
                });
1106
        }
1107

    
1108
        void createOtherSharedTree() {
1109
                otherSharedTreeSelectionModel = new SingleSelectionModel<Folder>();
1110
                otherSharedTreeSelectionModel.addSelectionChangeHandler(new Handler() {
1111
                    @Override
1112
                    public void onSelectionChange(SelectionChangeEvent event) {
1113
                        if (otherSharedTreeSelectionModel.getSelectedObject() != null) {
1114
                            deselectOthers(otherSharedTreeView, otherSharedTreeSelectionModel);
1115
                            applyPermissions(otherSharedTreeSelectionModel.getSelectedObject());
1116
                            updateOtherSharedFolder(otherSharedTreeSelectionModel.getSelectedObject(), true, null);
1117
                                        showRelevantToolbarButtons();
1118
                        }
1119
                                else {
1120
                                        if (getSelectedTree().equals(otherSharedTreeView))
1121
                                                setSelectedTree(null);
1122
                                        if (getSelectedTree() == null)
1123
                                                showRelevantToolbarButtons();
1124
                                }
1125
                     }
1126
                });
1127
                selectionModels.add(otherSharedTreeSelectionModel);
1128
                otherSharedTreeViewModel = new OtherSharedTreeViewModel(Pithos.this, otherSharedTreeSelectionModel);
1129
                otherSharedTreeViewModel.initialize(new Command() {
1130
                        
1131
                        @Override
1132
                        public void execute() {
1133
                            otherSharedTreeView = new OtherSharedTreeView(otherSharedTreeViewModel);
1134
                                trees.insert(otherSharedTreeView, 1);
1135
                                treeViews.add(otherSharedTreeView);
1136
                                scheduleResfresh();
1137
                        }
1138
                });
1139
        }
1140

    
1141
        public native void log1(String message)/*-{
1142
                $wnd.console.log(message);
1143
        }-*/;
1144

    
1145
        public String getErrorData() {
1146
                if (error != null)
1147
                        return error.toString();
1148
                return "";
1149
        }
1150
        
1151
        public void setError(Throwable t) {
1152
                error = t;
1153
        }
1154
        
1155
        public void showRelevantToolbarButtons() {
1156
                toolbar.showRelevantButtons();
1157
        }
1158

    
1159
        public FileUploadDialog getFileUploadDialog() {
1160
                if (fileUploadDialog == null)
1161
                        fileUploadDialog = new FileUploadDialog(this);
1162
                return fileUploadDialog;
1163
        }
1164

    
1165
        public void hideUploadIndicator() {
1166
                upload.removeStyleName("pithos-uploadButton-loading");
1167
                upload.setTitle("");
1168
        }
1169
        
1170
        public void showUploadIndicator() {
1171
                upload.addStyleName("pithos-uploadButton-loading");
1172
                upload.setTitle("Upload in progress. Click for details.");
1173
        }
1174

    
1175
        public void scheduleFolderHeadCommand(final Folder folder, final Command callback) {
1176
                if (folder == null) {
1177
                        if (callback != null)
1178
                                callback.execute();
1179
                }
1180
                else {
1181
                        HeadRequest<Folder> headFolder = new HeadRequest<Folder>(Folder.class, getApiPath(), folder.getOwner(), folder.getUri(), folder) {
1182
        
1183
                                @Override
1184
                                public void onSuccess(Folder _result) {
1185
                                        if (callback != null)
1186
                                                callback.execute();
1187
                                }
1188
        
1189
                                @Override
1190
                                public void onError(Throwable t) {
1191
                                if (t instanceof RestException) {
1192
                                        if (((RestException) t).getHttpStatusCode() == Response.SC_NOT_FOUND) {
1193
                                final String path = folder.getUri();
1194
                                PutRequest newFolder = new PutRequest(getApiPath(), folder.getOwner(), path) {
1195
                                    @Override
1196
                                    public void onSuccess(Resource _result) {
1197
                                            scheduleFolderHeadCommand(folder, callback);
1198
                                    }
1199
        
1200
                                    @Override
1201
                                    public void onError(Throwable _t) {
1202
                                        GWT.log("", _t);
1203
                                                                setError(_t);
1204
                                        if(_t instanceof RestException){
1205
                                            displayError("Unable to create folder: " + ((RestException) _t).getHttpStatusText());
1206
                                        }
1207
                                        else
1208
                                            displayError("System error creating folder: " + _t.getMessage());
1209
                                    }
1210
        
1211
                                                    @Override
1212
                                                    protected void onUnauthorized(Response response) {
1213
                                                            sessionExpired();
1214
                                                    }
1215
                                };
1216
                                newFolder.setHeader("X-Auth-Token", getToken());
1217
                                newFolder.setHeader("Content-Type", "application/folder");
1218
                                newFolder.setHeader("Accept", "*/*");
1219
                                newFolder.setHeader("Content-Length", "0");
1220
                                Scheduler.get().scheduleDeferred(newFolder);
1221
                                        }
1222
                                        else
1223
                                                displayError("Error heading folder: " + ((RestException) t).getHttpStatusText());
1224
                                }
1225
                                else
1226
                                    displayError("System error heading folder: " + t.getMessage());
1227
        
1228
                                GWT.log("Error heading folder", t);
1229
                                        setError(t);
1230
                                }
1231
        
1232
                                @Override
1233
                                protected void onUnauthorized(Response response) {
1234
                                        sessionExpired();
1235
                                }
1236
                        };
1237
                        headFolder.setHeader("X-Auth-Token", getToken());
1238
                        Scheduler.get().scheduleDeferred(headFolder);
1239
                }
1240
        }
1241

    
1242
        public void scheduleFileHeadCommand(File f, final Command callback) {
1243
                HeadRequest<File> headFile = new HeadRequest<File>(File.class, getApiPath(), f.getOwner(), f.getUri(), f) {
1244

    
1245
                        @Override
1246
                        public void onSuccess(File _result) {
1247
                                if (callback != null)
1248
                                        callback.execute();
1249
                        }
1250

    
1251
                        @Override
1252
                        public void onError(Throwable t) {
1253
                        GWT.log("Error heading file", t);
1254
                                setError(t);
1255
                        if (t instanceof RestException)
1256
                            displayError("Error heading file: " + ((RestException) t).getHttpStatusText());
1257
                        else
1258
                            displayError("System error heading file: " + t.getMessage());
1259
                        }
1260

    
1261
                        @Override
1262
                        protected void onUnauthorized(Response response) {
1263
                                sessionExpired();
1264
                        }
1265
                };
1266
                headFile.setHeader("X-Auth-Token", getToken());
1267
                Scheduler.get().scheduleDeferred(headFile);
1268
        }
1269

    
1270
        public boolean isMySharedSelected() {
1271
                return getSelectedTree().equals(getMySharedTreeView());
1272
        }
1273
        
1274
        private Folder getUploadFolder() {
1275
                if (folderTreeView.equals(getSelectedTree()) || otherSharedTreeView.equals(getSelectedTree())) {
1276
                        return getSelection();
1277
                }
1278
                return null;
1279
        }
1280
        
1281
        private void updateUploadFolder() {
1282
                updateUploadFolder(null);
1283
        }
1284
        
1285
        private void updateUploadFolder(final JsArrayString urls) {
1286
                if (folderTreeView.equals(getSelectedTree()) || otherSharedTreeView.equals(getSelectedTree())) {
1287
                        Folder f = getSelection();
1288
                        if (getSelectedTree().equals(getFolderTreeView()))
1289
                                updateFolder(f, true, new Command() {
1290
                                
1291
                                        @Override
1292
                                        public void execute() {
1293
                                                updateStatistics();
1294
                                                if (urls != null)
1295
                                                        selectUploadedFiles(urls);
1296
                                        }
1297
                                }, false);
1298
                        else
1299
                                updateOtherSharedFolder(f, true, null);
1300
                }
1301
        }
1302

    
1303
        public native void disableUploadArea() /*-{
1304
                var uploader = $wnd.$("#uploader").pluploadQueue();
1305
                var dropElm = $wnd.document.getElementById('rightPanel');
1306
                $wnd.plupload.removeAllEvents(dropElm, uploader.id);
1307
        }-*/;
1308

    
1309
        public native void enableUploadArea() /*-{
1310
                var uploader = $wnd.$("#uploader").pluploadQueue();
1311
                var dropElm = $wnd.document.getElementById('rightPanel');
1312
                $wnd.plupload.removeAllEvents(dropElm, uploader.id);
1313
                if (uploader.runtime == 'html5') {
1314
                        uploader.settings.drop_element = 'rightPanel';
1315
                        uploader.trigger('PostInit');
1316
                }
1317
        }-*/;
1318
        
1319
        public void showUploadAlert(int nOfFiles) {
1320
                if (uploadAlert == null)
1321
                        uploadAlert = new UploadAlert(this, nOfFiles);
1322
                if (!uploadAlert.isShowing())
1323
                        uploadAlert.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
1324
                                
1325
                                @Override
1326
                                public void setPosition(int offsetWidth, int offsetHeight) {
1327
                                        uploadAlert.setPopupPosition((Window.getClientWidth() - offsetWidth)/2, statusPanel.getAbsoluteTop() - offsetHeight);
1328
                                }
1329
                        });
1330
                uploadAlert.setNumOfFiles(nOfFiles);
1331
        }
1332
        
1333
        public void hideUploadAlert() {
1334
                if (uploadAlert != null && uploadAlert.isShowing())
1335
                        uploadAlert.hide();
1336
        }
1337
        
1338
        public void selectUploadedFiles(JsArrayString urls) {
1339
                List<String> selectedUrls = new ArrayList<String>();
1340
                for (int i=0; i<urls.length(); i++)
1341
                        selectedUrls.add(urls.get(i));
1342
                fileList.selectByUrl(selectedUrls);
1343
        }
1344
        
1345
        public void deleteAndCreateTrash() {
1346
                DeleteRequest delete = new DeleteRequest(getApiPath(), getUsername(), "/trash") {
1347
                        
1348
                        @Override
1349
                        protected void onUnauthorized(Response response) {
1350
                                sessionExpired();
1351
                        }
1352
                        
1353
                        @Override
1354
                        public void onSuccess(Resource result) {
1355
                                createTrashContainer(null);
1356
                        }
1357
                        
1358
                        @Override
1359
                        public void onError(Throwable t) {
1360
                GWT.log("Error deleting trash", t);
1361
                                setError(t);
1362
                if (t instanceof RestException)
1363
                    displayError("Error deleting trash: " + ((RestException) t).getHttpStatusText());
1364
                else
1365
                    displayError("System error deleting trash: " + t.getMessage());
1366
                        }
1367
                };
1368
                delete.setHeader("X-Auth-Token", getToken());
1369
                Scheduler.get().scheduleDeferred(delete);
1370
        }
1371
}