initial support for celltable( added in tabs panel)
[pithos] / src / gr / ebs / gss / client / GSS.java
1 /*
2  * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.
3  *
4  * This file is part of GSS.
5  *
6  * GSS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 package gr.ebs.gss.client;
20
21 import gr.ebs.gss.client.clipboard.Clipboard;
22 import gr.ebs.gss.client.commands.GetUserCommand;
23 import gr.ebs.gss.client.dnd.DnDFocusPanel;
24 import gr.ebs.gss.client.dnd.DnDSimpleFocusPanel;
25 import gr.ebs.gss.client.rest.GetCommand;
26 import gr.ebs.gss.client.rest.RestException;
27 import gr.ebs.gss.client.rest.resource.FileResource;
28 import gr.ebs.gss.client.rest.resource.FolderResource;
29 import gr.ebs.gss.client.rest.resource.TrashResource;
30 import gr.ebs.gss.client.rest.resource.UserResource;
31
32 import java.util.Arrays;
33 import java.util.Date;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37
38 import com.allen_sauer.gwt.dnd.client.DragContext;
39 import com.allen_sauer.gwt.dnd.client.PickupDragController;
40 import com.allen_sauer.gwt.dnd.client.VetoDragException;
41 import com.google.gwt.core.client.EntryPoint;
42 import com.google.gwt.core.client.GWT;
43 import com.google.gwt.event.logical.shared.ResizeEvent;
44 import com.google.gwt.event.logical.shared.ResizeHandler;
45 import com.google.gwt.event.logical.shared.SelectionEvent;
46 import com.google.gwt.event.logical.shared.SelectionHandler;
47 import com.google.gwt.event.logical.shared.ValueChangeEvent;
48 import com.google.gwt.event.logical.shared.ValueChangeHandler;
49 import com.google.gwt.i18n.client.DateTimeFormat;
50 import com.google.gwt.resources.client.ClientBundle;
51 import com.google.gwt.resources.client.ImageResource;
52 import com.google.gwt.user.client.Command;
53 import com.google.gwt.user.client.Cookies;
54 import com.google.gwt.user.client.DOM;
55 import com.google.gwt.user.client.DeferredCommand;
56 import com.google.gwt.user.client.History;
57 import com.google.gwt.user.client.Window;
58 import com.google.gwt.user.client.ui.AbsolutePanel;
59 import com.google.gwt.user.client.ui.AbstractImagePrototype;
60 import com.google.gwt.user.client.ui.DecoratedTabPanel;
61 import com.google.gwt.user.client.ui.DockPanel;
62 import com.google.gwt.user.client.ui.HTML;
63 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
64 import com.google.gwt.user.client.ui.HasVerticalAlignment;
65 import com.google.gwt.user.client.ui.HorizontalSplitPanel;
66 import com.google.gwt.user.client.ui.Label;
67 import com.google.gwt.user.client.ui.RootPanel;
68 import com.google.gwt.user.client.ui.TabPanel;
69 import com.google.gwt.user.client.ui.TreeItem;
70 import com.google.gwt.user.client.ui.VerticalPanel;
71 import com.google.gwt.user.client.ui.Widget;
72
73 /**
74  * Entry point classes define <code>onModuleLoad()</code>.
75  */
76 public class GSS implements EntryPoint, ResizeHandler {
77
78         /**
79          * A constant that denotes the completion of an IncrementalCommand.
80          */
81         public static final boolean DONE = false;
82
83         public static final int VISIBLE_FILE_COUNT = 100;
84
85         /**
86          * Instantiate an application-level image bundle. This object will provide
87          * programmatic access to all the images needed by widgets.
88          */
89         private static Images images = (Images) GWT.create(Images.class);
90
91         private GlassPanel glassPanel = new GlassPanel();
92
93         /**
94          * An aggregate image bundle that pulls together all the images for this
95          * application into a single bundle.
96          */
97         public interface Images extends ClientBundle, TopPanel.Images, StatusPanel.Images, FileMenu.Images, EditMenu.Images, SettingsMenu.Images, GroupMenu.Images, FilePropertiesDialog.Images, MessagePanel.Images, FileList.Images, SearchResults.Images, Search.Images, Groups.Images, Folders.Images, CellTreeView.Images {
98
99                 @Source("gr/ebs/gss/resources/document.png")
100                 ImageResource folders();
101
102                 @Source("gr/ebs/gss/resources/edit_group_22.png")
103                 ImageResource groups();
104
105                 @Source("gr/ebs/gss/resources/search.png")
106                 ImageResource search();
107         }
108
109         /**
110          * The single GSS instance.
111          */
112         private static GSS singleton;
113
114         /**
115          * Gets the singleton GSS instance.
116          *
117          * @return the GSS object
118          */
119         public static GSS get() {
120                 if (GSS.singleton == null)
121                         GSS.singleton = new GSS();
122                 return GSS.singleton;
123         }
124
125         /**
126          * The Application Clipboard implementation;
127          */
128         private Clipboard clipboard = new Clipboard();
129
130         private UserResource currentUserResource;
131
132         /**
133          * The top panel that contains the menu bar.
134          */
135         private TopPanel topPanel;
136
137         /**
138          * The panel that contains the various system messages.
139          */
140         private MessagePanel messagePanel = new MessagePanel(GSS.images);
141
142         /**
143          * The bottom panel that contains the status bar.
144          */
145         private StatusPanel statusPanel = new StatusPanel(GSS.images);
146
147         /**
148          * The top right panel that displays the logged in user details
149          */
150         private UserDetailsPanel userDetailsPanel = new UserDetailsPanel();
151
152         /**
153          * The file list widget.
154          */
155         private FileList fileList;
156
157         /**
158          * The group list widget.
159          */
160         private Groups groups = new Groups(images);
161
162         /**
163          * The search result widget.
164          */
165         private SearchResults searchResults;
166
167         /**
168          * The tab panel that occupies the right side of the screen.
169          */
170         private TabPanel inner = new DecoratedTabPanel();
171
172         /**
173          * The split panel that will contain the left and right panels.
174          */
175         private HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
176
177         /**
178          * The horizontal panel that will contain the search and status panels.
179          */
180         private DockPanel searchStatus = new DockPanel();
181
182         /**
183          * The search widget.
184          */
185         private Search search;
186
187         /**
188          * The widget that displays the tree of folders.
189          */
190         private Folders folders = new Folders(images);
191
192         /**
193          * The currently selected item in the application, for use by the Edit menu
194          * commands. Potential types are Folder, File, User and Group.
195          */
196         private Object currentSelection;
197
198         /**
199          * The authentication token of the current user.
200          */
201         private String token;
202
203         /**
204          * The WebDAV password of the current user
205          */
206         private String webDAVPassword;
207
208         private PickupDragController dragController;
209
210         public HashMap<String, String> userFullNameMap = new HashMap<String, String>();
211
212         @Override
213         public void onModuleLoad() {
214                 // Initialize the singleton before calling the constructors of the
215                 // various widgets that might call GSS.get().
216                 singleton = this;
217                 RootPanel.get().add(glassPanel, 0, 0);
218                 parseUserCredentials();
219                 dragController = new PickupDragController(RootPanel.get(), false) {
220
221                         @Override
222                         public void previewDragStart() throws VetoDragException {
223                             super.previewDragStart();
224                             if (context.selectedWidgets.isEmpty())
225                                         throw new VetoDragException();
226
227                             if(context.draggable != null)
228                                         if(context.draggable instanceof DnDFocusPanel){
229                                                 DnDFocusPanel toDrop = (DnDFocusPanel) context.draggable;
230                                                 // prevent drag and drop for trashed files and for
231                                                 // unselected tree items
232                                                 if(toDrop.getFiles() != null && folders.isTrashItem(folders.getCurrent()))
233                                                         throw new VetoDragException();
234                                                 else if(toDrop.getItem() != null && !toDrop.getItem().equals(folders.getCurrent()))
235                                                         throw new VetoDragException();
236                                                 else if(toDrop.getItem() != null && !toDrop.getItem().isDraggable())
237                                                         throw new VetoDragException();
238
239                                         } else if (context.draggable instanceof DnDSimpleFocusPanel) {
240                                         DnDSimpleFocusPanel toDrop = (DnDSimpleFocusPanel) context.draggable;
241                                                 // prevent drag and drop for trashed files and for
242                                                 // unselected tree items
243                                                 if(toDrop.getFiles() != null && folders.isTrashItem(folders.getCurrent()))
244                                                         throw new VetoDragException();
245                                 }
246                           }
247
248                         @Override
249                         protected Widget newDragProxy(DragContext aContext) {
250                                 AbsolutePanel container = new AbsolutePanel();
251                                 HTML html = null;
252                                 DOM.setStyleAttribute(container.getElement(), "overflow", "visible");
253                                 if(aContext.draggable!=null && aContext.draggable.getParent()!= null && aContext.draggable.getParent() instanceof FileTable){
254                                         if(getFileList().getSelectedFiles().size()>1){
255                                                 html=new HTML(getFileList().getSelectedFiles().size()+ " files");
256                                                 container.add(html);
257                                                 return container;
258                                         }
259                                         FileTable proxy;
260                                     proxy = new FileTable(1,8);
261                                     proxy.addStyleName("gss-List");
262                                     FileTable draggableTable = (FileTable) context.draggable.getParent();
263                                     int dragRow = FileTable.getWidgetRow(context.draggable, draggableTable);
264                                     FileTable.copyRow(draggableTable, proxy, dragRow, 0);
265                                     return proxy;
266
267                                 }
268                                 for (Iterator iterator = aContext.selectedWidgets.iterator(); iterator.hasNext();) {
269                                         Widget widget = (Widget) iterator.next();
270                                         if (widget instanceof DnDFocusPanel) {
271                                                 DnDFocusPanel book = (DnDFocusPanel) widget;
272                                                 html = book.cloneHTML();
273                                         } else if (widget instanceof DnDSimpleFocusPanel) {
274                                                 DnDSimpleFocusPanel book = (DnDSimpleFocusPanel) widget;
275                                                 html = book.cloneHTML();
276                                         }
277                                         if(html == null)
278                                                 container.add(new Label("Drag ME"));
279                                         else
280                                                 container.add(html);
281                                         return container;
282                                 }
283                                 return container;
284                         }
285                 };
286                 dragController.setBehaviorDragProxy(true);
287                 dragController.setBehaviorMultipleSelection(false);
288                 topPanel = new TopPanel(GSS.images);
289                 topPanel.setWidth("100%");
290
291                 messagePanel.setWidth("100%");
292                 messagePanel.setVisible(false);
293
294                 search = new Search(images);
295                 searchStatus.add(search, DockPanel.WEST);
296                 searchStatus.add(userDetailsPanel, DockPanel.EAST);
297                 searchStatus.setCellHorizontalAlignment(userDetailsPanel, HasHorizontalAlignment.ALIGN_RIGHT);
298                 searchStatus.setCellVerticalAlignment(search, HasVerticalAlignment.ALIGN_MIDDLE);
299                 searchStatus.setCellVerticalAlignment(userDetailsPanel, HasVerticalAlignment.ALIGN_MIDDLE);
300                 searchStatus.setWidth("100%");
301
302                 fileList = new FileList(images);
303
304                 searchResults = new SearchResults(images);
305
306                 // Inner contains the various lists.
307                 inner.setAnimationEnabled(true);
308                 inner.getTabBar().addStyleName("gss-MainTabBar");
309                 inner.getDeckPanel().addStyleName("gss-MainTabPanelBottom");
310                 inner.add(fileList, createHeaderHTML(AbstractImagePrototype.create(images.folders()), "Files"), true);
311
312                 inner.add(groups, createHeaderHTML(AbstractImagePrototype.create(images.groups()), "Groups"), true);
313                 inner.add(searchResults, createHeaderHTML(AbstractImagePrototype.create(images.search()), "Search Results"), true);
314                 inner.add(new CellTreeView(images), createHeaderHTML(AbstractImagePrototype.create(images.search()), "Cell tree sample"), true);
315                 inner.setWidth("100%");
316                 inner.selectTab(0);
317
318                 inner.addSelectionHandler(new SelectionHandler<Integer>() {
319
320                         @Override
321                         public void onSelection(SelectionEvent<Integer> event) {
322                                 int tabIndex = event.getSelectedItem();
323 //                              TreeItem treeItem = GSS.get().getFolders().getCurrent();
324                                 switch (tabIndex) {
325                                         case 0:
326 //                                              Files tab selected
327                                                 fileList.clearSelectedRows();
328                                                 fileList.updateCurrentlyShowingStats();
329                                                 break;
330                                         case 1:
331 //                                              Groups tab selected
332                                                 groups.updateCurrentlyShowingStats();
333                                         updateHistory("Groups");
334                                                 break;
335                                         case 2:
336 //                                              Search tab selected
337                                                 searchResults.clearSelectedRows();
338                                                 searchResults.updateCurrentlyShowingStats();
339                                         updateHistory("Search");
340                                                 break;
341                                 }
342                         }
343                 });
344 //              If the application starts with no history token, redirect to a new "Files" state
345                 String initToken = History.getToken();
346                 if(initToken.length() == 0)
347                         History.newItem("Files");
348 //                 Add history listener to handle any history events
349                 History.addValueChangeHandler(new ValueChangeHandler<String>() {
350                         @Override
351                         public void onValueChange(ValueChangeEvent<String> event) {
352                                 String tokenInput = event.getValue();
353                                 String historyToken = handleSpecialFolderNames(tokenInput);
354                                 try {
355                                         if(historyToken.equals("Search"))
356                                                 inner.selectTab(2);
357                                         else if(historyToken.equals("Groups"))
358                                                 inner.selectTab(1);
359                                         else if(historyToken.equals("Files")|| historyToken.length()==0)
360                                                 inner.selectTab(0);
361                                         else {
362                                                 PopupTree popupTree = GSS.get().getFolders().getPopupTree();
363                                                 TreeItem treeObj = GSS.get().getFolders().getPopupTree().getTreeItem(historyToken);
364                                                 SelectionEvent.fire(popupTree, treeObj);
365                                         }
366                                 } catch (IndexOutOfBoundsException e) {
367                                         inner.selectTab(0);
368                                 }
369                         }
370                 });
371
372                 // Add the left and right panels to the split panel.
373                 splitPanel.setLeftWidget(folders);
374                 splitPanel.setRightWidget(inner);
375                 splitPanel.setSplitPosition("25%");
376                 splitPanel.setSize("100%", "100%");
377                 splitPanel.addStyleName("gss-splitPanel");
378
379                 // Create a dock panel that will contain the menu bar at the top,
380                 // the shortcuts to the left, the status bar at the bottom and the
381                 // right panel taking the rest.
382                 VerticalPanel outer = new VerticalPanel();
383                 outer.add(topPanel);
384                 outer.add(searchStatus);
385                 outer.add(messagePanel);
386                 outer.add(splitPanel);
387                 outer.add(statusPanel);
388                 outer.setWidth("100%");
389                 outer.setCellHorizontalAlignment(messagePanel, HasHorizontalAlignment.ALIGN_CENTER);
390
391                 outer.setSpacing(4);
392
393                 // Hook the window resize event, so that we can adjust the UI.
394                 Window.addResizeHandler(this);
395                 // Clear out the window's built-in margin, because we want to take
396                 // advantage of the entire client area.
397                 Window.setMargin("0px");
398                 // Finally, add the outer panel to the RootPanel, so that it will be
399                 // displayed.
400                 RootPanel.get().add(outer);
401                 // Call the window resized handler to get the initial sizes setup. Doing
402                 // this in a deferred command causes it to occur after all widgets'
403                 // sizes have been computed by the browser.
404                 DeferredCommand.addCommand(new Command() {
405
406                         @Override
407                         public void execute() {
408                                 onWindowResized(Window.getClientHeight());
409                         }
410                 });
411         }
412
413         /**
414          * Fetches the User object for the specified username.
415          *
416          * @param username the username of the user
417          */
418         private void fetchUser(final String username) {
419                 String path = getApiPath() + username + "/";
420                 GetCommand<UserResource> getUserCommand = new GetCommand<UserResource>(UserResource.class, username, path, null) {
421
422                         @Override
423                         public void onComplete() {
424                                 currentUserResource = getResult();
425                                 final String announcement = currentUserResource.getAnnouncement();
426                                 if (announcement != null)
427                                         DeferredCommand.addCommand(new Command() {
428
429                                                 @Override
430                                                 public void execute() {
431                                                         displayInformation(announcement);
432                                                 }
433                                         });
434                         }
435
436                         @Override
437                         public void onError(Throwable t) {
438                                 GWT.log("Fetching user error", t);
439                                 if (t instanceof RestException)
440                                         GSS.get().displayError("No user found:" + ((RestException) t).getHttpStatusText());
441                                 else
442                                         GSS.get().displayError("System error fetching user data:" + t.getMessage());
443                                 authenticateUser();
444                         }
445                 };
446                 DeferredCommand.addCommand(getUserCommand);
447         }
448
449         /**
450          * Parse and store the user credentials to the appropriate fields.
451          */
452         private void parseUserCredentials() {
453                 Configuration conf = (Configuration) GWT.create(Configuration.class);
454                 String cookie = conf.authCookie();
455                 String auth = Cookies.getCookie(cookie);
456                 if (auth == null) {
457                         authenticateUser();
458                         // Redundant, but silences warnings about possible auth NPE, below.
459                         return;
460                 }
461                 int sepIndex = auth.indexOf(conf.cookieSeparator());
462                 if (sepIndex == -1)
463                         authenticateUser();
464                 token = auth.substring(sepIndex + 1);
465                 final String username = auth.substring(0, sepIndex);
466                 if (username == null)
467                         authenticateUser();
468
469                 refreshWebDAVPassword();
470
471                 DeferredCommand.addCommand(new Command() {
472
473                         @Override
474                         public void execute() {
475                                 fetchUser(username);
476                         }
477                 });
478         }
479
480         /**
481          * Redirect the user to the login page for authentication.
482          */
483         protected void authenticateUser() {
484                 Configuration conf = (Configuration) GWT.create(Configuration.class);
485                 Window.Location.assign(conf.loginUrl() + "?next=" + GWT.getModuleBaseURL());
486         }
487
488         /**
489          * Clear the cookie and redirect the user to the logout page.
490          */
491         void logout() {
492                 Configuration conf = (Configuration) GWT.create(Configuration.class);
493                 String cookie = conf.authCookie();
494                 String domain = Window.Location.getHostName();
495                 String path = Window.Location.getPath();
496                 Cookies.setCookie(cookie, "", null, domain, path, false);
497                 Window.Location.assign(conf.logoutUrl());
498         }
499
500         /**
501          * Creates an HTML fragment that places an image & caption together, for use
502          * in a group header.
503          *
504          * @param imageProto an image prototype for an image
505          * @param caption the group caption
506          * @return the header HTML fragment
507          */
508         private String createHeaderHTML(AbstractImagePrototype imageProto, String caption) {
509                 String captionHTML = "<table class='caption' cellpadding='0' " + "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML() + "</td><td class='rcaption'><b style='white-space:nowrap'>&nbsp;" + caption + "</b></td></tr></table>";
510                 return captionHTML;
511         }
512
513         private void onWindowResized(int height) {
514                 // Adjust the split panel to take up the available room in the window.
515                 int newHeight = height - splitPanel.getAbsoluteTop() - 44;
516                 if (newHeight < 1)
517                         newHeight = 1;
518                 splitPanel.setHeight("" + newHeight);
519         }
520
521         @Override
522         public void onResize(ResizeEvent event) {
523                 int height = event.getHeight();
524                 onWindowResized(height);
525         }
526
527         public boolean isFileListShowing() {
528                 int tab = inner.getTabBar().getSelectedTab();
529                 if (tab == 0)
530                         return true;
531                 return false;
532         }
533
534         public boolean isSearchResultsShowing() {
535                 int tab = inner.getTabBar().getSelectedTab();
536                 if (tab == 2)
537                         return true;
538                 return false;
539         }
540
541         /**
542          * Make the user list visible.
543          */
544         public void showUserList() {
545                 inner.selectTab(1);
546         }
547
548         /**
549          * Make the file list visible.
550          */
551         public void showFileList() {
552                 fileList.updateFileCache(false, true /*clear selection*/);
553                 inner.selectTab(0);
554         }
555
556         /**
557          * Make the file list visible.
558          *
559          * @param update
560          */
561         public void showFileList(boolean update) {
562                 TreeItem currentFolder = getFolders().getCurrent();
563                 if (currentFolder != null) {
564                         List<FileResource> files = null;
565                         Object cachedObject = currentFolder.getUserObject();
566                         if (cachedObject instanceof FolderResource) {
567                                 FolderResource folder = (FolderResource) cachedObject;
568                                 files = folder.getFiles();
569                         } else if (cachedObject instanceof TrashResource) {
570                                 TrashResource folder = (TrashResource) cachedObject;
571                                 files = folder.getFiles();
572                         }
573                         if (files != null)
574                                 getFileList().setFiles(files);
575                 }
576                 fileList.updateFileCache(update, true /*clear selection*/);
577                 inner.selectTab(0);
578         }
579
580         /**
581          * Make the search results visible.
582          *
583          * @param query the search query string
584          */
585         public void showSearchResults(String query) {
586                 searchResults.updateFileCache(query);
587                 searchResults.updateCurrentlyShowingStats();
588                 inner.selectTab(2);
589         }
590
591         /**
592          * Display the 'loading' indicator.
593          */
594         public void showLoadingIndicator() {
595                 topPanel.getLoading().setVisible(true);
596         }
597
598         /**
599          * Hide the 'loading' indicator.
600          */
601         public void hideLoadingIndicator() {
602                 topPanel.getLoading().setVisible(false);
603         }
604
605         /**
606          * A native JavaScript method to reach out to the browser's window and
607          * invoke its resizeTo() method.
608          *
609          * @param x the new width
610          * @param y the new height
611          */
612         public static native void resizeTo(int x, int y) /*-{
613                 $wnd.resizeTo(x,y);
614         }-*/;
615
616         /**
617          * A helper method that returns true if the user's list is currently visible
618          * and false if it is hidden.
619          *
620          * @return true if the user list is visible
621          */
622         public boolean isUserListVisible() {
623                 return inner.getTabBar().getSelectedTab() == 1;
624         }
625
626         /**
627          * Display an error message.
628          *
629          * @param msg the message to display
630          */
631         public void displayError(String msg) {
632                 messagePanel.displayError(msg);
633         }
634
635         /**
636          * Display a warning message.
637          *
638          * @param msg the message to display
639          */
640         public void displayWarning(String msg) {
641                 messagePanel.displayWarning(msg);
642         }
643
644         /**
645          * Display an informational message.
646          *
647          * @param msg the message to display
648          */
649         public void displayInformation(String msg) {
650                 messagePanel.displayInformation(msg);
651         }
652
653         /**
654          * Retrieve the folders.
655          *
656          * @return the folders
657          */
658         public Folders getFolders() {
659                 return folders;
660         }
661
662         /**
663          * Retrieve the search.
664          *
665          * @return the search
666          */
667         Search getSearch() {
668                 return search;
669         }
670
671         /**
672          * Retrieve the currentSelection.
673          *
674          * @return the currentSelection
675          */
676         public Object getCurrentSelection() {
677                 return currentSelection;
678         }
679
680         /**
681          * Modify the currentSelection.
682          *
683          * @param newCurrentSelection the currentSelection to set
684          */
685         public void setCurrentSelection(Object newCurrentSelection) {
686                 currentSelection = newCurrentSelection;
687         }
688
689         /**
690          * Retrieve the groups.
691          *
692          * @return the groups
693          */
694         public Groups getGroups() {
695                 return groups;
696         }
697
698         /**
699          * Retrieve the fileList.
700          *
701          * @return the fileList
702          */
703         public FileList getFileList() {
704                 return fileList;
705         }
706
707         public SearchResults getSearchResults() {
708                 return searchResults;
709         }
710
711         /**
712          * Retrieve the topPanel.
713          *
714          * @return the topPanel
715          */
716         TopPanel getTopPanel() {
717                 return topPanel;
718         }
719
720         /**
721          * Retrieve the clipboard.
722          *
723          * @return the clipboard
724          */
725         public Clipboard getClipboard() {
726                 return clipboard;
727         }
728
729         public StatusPanel getStatusPanel() {
730                 return statusPanel;
731         }
732
733         /**
734          * Retrieve the userDetailsPanel.
735          *
736          * @return the userDetailsPanel
737          */
738         public UserDetailsPanel getUserDetailsPanel() {
739                 return userDetailsPanel;
740         }
741
742         /**
743          * Retrieve the dragController.
744          *
745          * @return the dragController
746          */
747         public PickupDragController getDragController() {
748                 return dragController;
749         }
750
751         public String getToken() {
752                 return token;
753         }
754
755         public String getWebDAVPassword() {
756                 return webDAVPassword;
757         }
758
759         public void removeGlassPanel() {
760                 glassPanel.removeFromParent();
761         }
762
763         /**
764          * Retrieve the currentUserResource.
765          *
766          * @return the currentUserResource
767          */
768         public UserResource getCurrentUserResource() {
769                 return currentUserResource;
770         }
771
772         /**
773          * Modify the currentUserResource.
774          *
775          * @param newUser the new currentUserResource
776          */
777         public void setCurrentUserResource(UserResource newUser) {
778                 currentUserResource = newUser;
779         }
780
781         public static native void preventIESelection() /*-{
782                 $doc.body.onselectstart = function () { return false; };
783         }-*/;
784
785         public static native void enableIESelection() /*-{
786                 if ($doc.body.onselectstart != null)
787                 $doc.body.onselectstart = null;
788         }-*/;
789
790         /**
791          * @return the absolute path of the API root URL
792          */
793         public String getApiPath() {
794                 Configuration conf = (Configuration) GWT.create(Configuration.class);
795                 return GWT.getModuleBaseURL() + conf.apiPath();
796         }
797
798         public void refreshWebDAVPassword() {
799                 Configuration conf = (Configuration) GWT.create(Configuration.class);
800                 String domain = Window.Location.getHostName();
801                 String path = Window.Location.getPath();
802                 String cookie = conf.webdavCookie();
803                 webDAVPassword = Cookies.getCookie(cookie);
804                 Cookies.setCookie(cookie, "", null, domain, path, false);
805         }
806
807         /**
808          * Convert server date to local time according to browser timezone
809          * and format it according to localized pattern.
810          * Time is always formatted to 24hr format.
811          * NB: This assumes that server runs in UTC timezone. Otherwise
812          * we would need to adjust for server time offset as well.
813          *
814          * @param date
815          * @return String
816          */
817         public static String formatLocalDateTime(Date date) {
818                 Date convertedDate = new Date(date.getTime() - date.getTimezoneOffset());
819                 final DateTimeFormat dateFormatter = DateTimeFormat.getShortDateFormat();
820                 final DateTimeFormat timeFormatter = DateTimeFormat.getFormat("HH:mm");
821                 String datePart = dateFormatter.format(convertedDate);
822                 String timePart = timeFormatter.format(convertedDate);
823                 return datePart + " " + timePart;
824         }
825         
826         /**
827          * History support for folder navigation
828          * adds a new browser history entry
829          *
830          * @param key
831          */
832         public void updateHistory(String key){
833 //              Replace any whitespace of the initial string to "+"
834 //              String result = key.replaceAll("\\s","+");
835 //              Add a new browser history entry.
836 //              History.newItem(result);
837                 History.newItem(key);
838         }
839
840         /**
841          * This method examines the token input and add a "/" at the end in case it's omitted.
842          * This happens only in Files/trash/, Files/shared/, Files/others.
843          *
844          * @param tokenInput
845          * @return the formated token with a "/" at the end or the same tokenInput parameter
846          */
847
848         private String handleSpecialFolderNames(String tokenInput){
849                 List<String> pathsToCheck = Arrays.asList("Files/trash", "Files/shared", "Files/others");
850                 if(pathsToCheck.contains(tokenInput))
851                         return tokenInput + "/";
852                 return tokenInput;
853
854         }
855
856         /**
857          * Reject illegal resource names, like '.' or '..' or slashes '/'.
858          */
859         static boolean isValidResourceName(String name) {
860                 if (".".equals(name) || "..".equals(name) || name.contains("/"))
861                         return false;
862                 return true;
863         }
864
865         public void putUserToMap(String _userName, String _userFullName){
866                 userFullNameMap.put(_userName, _userFullName);
867         }
868
869         public String findUserFullName(String _userName){
870                 return userFullNameMap.get(_userName);
871         }
872
873         public String getUserFullName(String _userName) {
874                 if (GSS.get().findUserFullName(_userName) == null)
875                         //if there is no userFullName found then the map fills with the given _userName,
876                         //so userFullName = _userName
877                         GSS.get().putUserToMap(_userName, _userName);
878                 else if(GSS.get().findUserFullName(_userName).indexOf('@') != -1){
879                         //if the userFullName = _userName the GetUserCommand updates the userFullName in the map
880                         GetUserCommand guc = new GetUserCommand(_userName);
881                         guc.execute();
882                 }
883                 return GSS.get().findUserFullName(_userName);
884         }
885 }