Created
July 12, 2010 16:31
-
-
Save lenards/472682 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.iplantc.de.client.views; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.List; | |
import org.iplantc.de.client.ErrorHandler; | |
import org.iplantc.de.client.EventBus; | |
import org.iplantc.de.client.I18N; | |
import org.iplantc.de.client.events.disk.mgmt.DiskResourceDeletedEvent; | |
import org.iplantc.de.client.events.disk.mgmt.DiskResourceDeletedEventHandler; | |
import org.iplantc.de.client.events.disk.mgmt.DiskResourceRenamedEvent; | |
import org.iplantc.de.client.events.disk.mgmt.DiskResourceRenamedEventHandler; | |
import org.iplantc.de.client.events.disk.mgmt.FileMovedEvent; | |
import org.iplantc.de.client.events.disk.mgmt.FileMovedEventHandler; | |
import org.iplantc.de.client.events.disk.mgmt.FileSaveAsEvent; | |
import org.iplantc.de.client.events.disk.mgmt.FileSaveAsEventHandler; | |
import org.iplantc.de.client.events.disk.mgmt.FileUploadedEvent; | |
import org.iplantc.de.client.events.disk.mgmt.FileUploadedEventHandler; | |
import org.iplantc.de.client.events.disk.mgmt.FolderCreatedEvent; | |
import org.iplantc.de.client.events.disk.mgmt.FolderCreatedEventHandler; | |
import org.iplantc.de.client.images.Resources; | |
import org.iplantc.de.client.models.DiskResource; | |
import org.iplantc.de.client.models.File; | |
import org.iplantc.de.client.models.Folder; | |
import org.iplantc.de.client.models.UserInfo; | |
import org.iplantc.de.client.services.FolderServices; | |
import org.iplantc.de.client.utils.TreeStoreWrapper; | |
import org.iplantc.de.client.views.dialogs.IPlantDialog; | |
import org.iplantc.de.client.views.panels.AddFolderDialogPanel; | |
import org.iplantc.de.client.views.panels.RenameFileDialogPanel; | |
import org.iplantc.de.client.views.panels.RenameFolderDialogPanel; | |
import com.extjs.gxt.ui.client.data.ModelData; | |
import com.extjs.gxt.ui.client.data.ModelIconProvider; | |
import com.extjs.gxt.ui.client.event.Events; | |
import com.extjs.gxt.ui.client.event.GridEvent; | |
import com.extjs.gxt.ui.client.event.Listener; | |
import com.extjs.gxt.ui.client.store.TreeStore; | |
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig; | |
import com.extjs.gxt.ui.client.widget.grid.ColumnModel; | |
import com.extjs.gxt.ui.client.widget.treegrid.TreeGrid; | |
import com.extjs.gxt.ui.client.widget.treegrid.TreeGridCellRenderer; | |
import com.google.gwt.event.shared.HandlerRegistration; | |
import com.google.gwt.user.client.rpc.AsyncCallback; | |
import com.google.gwt.user.client.ui.AbstractImagePrototype; | |
/** | |
* Provides a grid representation of disk resources for user interaction. | |
*/ | |
public class DataBrowserGrid extends TreeGrid<DiskResource> | |
{ | |
/** | |
* When displaying all columns, an arbitrary column padding was included in the | |
* original implementation and is expected by parent widgets. This constant helps | |
* preserve the expected look and feel of the widget by consuming widgets. | |
*/ | |
public static final int ARBITRARY_COLUMN_PADDING = 30; | |
private TreeStoreWrapper storeWrapper; | |
private ColumnDisplay columnDisplay; | |
private List<HandlerRegistration> handlers; | |
protected DataBrowserGrid(ColumnDisplay columnDisplay, TreeStoreWrapper storeWrapper, | |
TreeStore<DiskResource> store, ColumnModel colModel) | |
{ | |
super(store, colModel); | |
addListener(Events.ViewReady, new Listener<GridEvent<DiskResource>>() | |
{ | |
@Override | |
public void handleEvent(GridEvent<DiskResource> be) | |
{ | |
expandRootFolder(); | |
} | |
}); | |
this.storeWrapper = storeWrapper; | |
this.columnDisplay = columnDisplay; | |
initEventHandlers(); | |
disableBrowserContextMenu(); | |
assembleView(); | |
} | |
private static DataBrowserGrid createInstanceImpl(ColumnDisplay columnDisplay) | |
{ | |
TreeStoreWrapper storeWrapper = new TreeStoreWrapper(); | |
TreeStore<DiskResource> store = storeWrapper.getStore(); | |
final ColumnModel colModel = buildColumnModel(columnDisplay); | |
return new DataBrowserGrid(columnDisplay, storeWrapper, store, colModel); | |
} | |
public static DataBrowserGrid createInstance() | |
{ | |
return createInstanceImpl(ColumnDisplay.ALL); | |
} | |
public static DataBrowserGrid createInstance(ColumnDisplay columnDisplay) | |
{ | |
return createInstanceImpl(columnDisplay); | |
} | |
/** | |
* Reconstructs and reconfigures the underlying tree grid. | |
* | |
* @return a newly constructed and configure instance of tree grid. | |
*/ | |
public TreeGrid<DiskResource> assembleView() | |
{ | |
getFilesInfo(); | |
final ColumnModel columnModel = buildColumnModel(columnDisplay); | |
return buildTreeGrid(getTreeStore(), columnModel); | |
} | |
/** | |
* Constructs and configures the underlying tree grid implementation. | |
* | |
* @param store the tree store holding the disk resources to display | |
* @param columnModel the specification of the columns for the grid | |
* @return a properly configured instance of a tree grid | |
*/ | |
private TreeGrid<DiskResource> buildTreeGrid(TreeStore<DiskResource> store, | |
final ColumnModel columnModel) | |
{ | |
int totalColumnWidth = computeColumnWidth(columnModel); | |
setBorders(true); | |
setHeight(260); | |
setWidth(totalColumnWidth); | |
getView().setShowDirtyCells(false); | |
setTrackMouseOver(false); | |
getTreeView().setBufferEnabled(false); | |
getTreeView().setCacheSize(10000); | |
setIconProvider(new ModelIconProvider<DiskResource>() | |
{ | |
@Override | |
public AbstractImagePrototype getIcon(DiskResource model) | |
{ | |
if(model instanceof Folder) | |
{ | |
return getNodeIcon(isExpanded(model)); | |
} | |
else | |
{ | |
return AbstractImagePrototype.create(Resources.ICONS.green()); | |
} | |
} | |
}); | |
return this; | |
} | |
/** | |
* Computes the width of the grid based on the widths specified in the column | |
* configuration | |
* | |
* @param columnModel the list of column configuration objects | |
* @return an integer representing necessary width of this widget | |
*/ | |
private int computeColumnWidth(ColumnModel columnModel) | |
{ | |
int totalWidth = 0; | |
for(ColumnConfig cc : columnModel.getColumns()) | |
{ | |
totalWidth += cc.getWidth(); | |
} | |
// when displaying all columns, include padding | |
if(columnDisplay == ColumnDisplay.ALL) | |
{ | |
totalWidth += ARBITRARY_COLUMN_PADDING; | |
} | |
return totalWidth; | |
} | |
/** | |
* Determine the correct node icon to display. | |
* | |
* @param isExpanded true if the node is expanded; otherwise false. | |
* @return a boolean representing the state of the node in a tree grid | |
*/ | |
private AbstractImagePrototype getNodeIcon(boolean isExpanded) | |
{ | |
return isExpanded ? getStyle().getNodeOpenIcon() : getStyle().getNodeCloseIcon(); | |
} | |
/** | |
* Create the column model for the tree grid. | |
* | |
* @return an instance of ColumnModel representing the columns visible in a grid | |
*/ | |
private static ColumnModel buildColumnModel(ColumnDisplay colDisplay) | |
{ | |
ColumnConfig name = new ColumnConfig("name", I18N.DISPLAY.name(), 330); | |
ColumnConfig date = new ColumnConfig("type", I18N.DISPLAY.description(), 190); | |
name.setRenderer(new TreeGridCellRenderer<ModelData>()); | |
List<ColumnConfig> columns = new ArrayList<ColumnConfig>(); | |
// add columns that are members of ColumnDisplay.CONCISE, a logical grouping of | |
// columns | |
columns.addAll(Arrays.asList(name, date)); | |
// if we want ALL, include the remaining columns | |
if(colDisplay == ColumnDisplay.ALL) | |
{ | |
ColumnConfig size = new ColumnConfig("uploaded", I18N.DISPLAY.uploaded(), 150); | |
columns.add(size); | |
} | |
return new ColumnModel(columns); | |
} | |
/** | |
* Disable the context menu of the browser using native JavaScript. | |
* | |
* This disables the user's ability to right-click on this widget and get the | |
* browser's context menu | |
*/ | |
private static native void disableBrowserContextMenu() | |
/*-{ | |
$doc.oncontextmenu = function() { return false; }; | |
}-*/; | |
/** | |
* Retrieve list of all uploaded files contains in the user's workspace | |
*/ | |
private void getFilesInfo() | |
{ | |
UserInfo uinfo = UserInfo.getInstance(); | |
String idWorkspace = uinfo.getWorkspaceId(); | |
FolderServices.getFiletree(idWorkspace, new AsyncCallback<String>() | |
{ | |
@Override | |
public void onFailure(Throwable arg0) | |
{ | |
ErrorHandler.post(I18N.ERROR.retrieveFiletreeFailed()); | |
} | |
@Override | |
public void onSuccess(String result) | |
{ | |
updateStore(result); | |
} | |
}); | |
} | |
private void expandRootFolder() | |
{ | |
Folder root = storeWrapper.getRootFolder(); | |
if(root != null) | |
{ | |
setExpanded(root, true); | |
} | |
} | |
private void updateStore(String jsonResult) | |
{ | |
storeWrapper.updateWrapper(jsonResult, true); | |
expandRootFolder(); | |
} | |
private void initEventHandlers() | |
{ | |
handlers = new ArrayList<HandlerRegistration>(); | |
EventBus eventbus = EventBus.getInstance(); | |
// folder added | |
handlers.add(eventbus.addHandler(FolderCreatedEvent.TYPE, new FolderCreatedEventHandler() | |
{ | |
@Override | |
public void onCreated(FolderCreatedEvent event) | |
{ | |
storeWrapper.createFolder(event.getParentId(), event.getFolderId(), event.getName()); | |
} | |
})); | |
// file uploaded | |
handlers.add(eventbus.addHandler(FileUploadedEvent.TYPE, new FileUploadedEventHandler() | |
{ | |
@Override | |
public void onUploaded(FileUploadedEvent event) | |
{ | |
storeWrapper.addFile(event.getParentId(), event.getFileInfo(), event.getDeleteIds()); | |
} | |
})); | |
// file save as completed | |
handlers.add(eventbus.addHandler(FileSaveAsEvent.TYPE, new FileSaveAsEventHandler() | |
{ | |
@Override | |
public void onSaved(FileSaveAsEvent event) | |
{ | |
storeWrapper.addFile(event.getParentId(), event.getFileInfo(), null); | |
} | |
})); | |
// folder/file renamed | |
handlers.add(eventbus.addHandler(DiskResourceRenamedEvent.TYPE, | |
new DiskResourceRenamedEventHandler() | |
{ | |
@Override | |
public void onFolderRenamed(DiskResourceRenamedEvent event) | |
{ | |
storeWrapper.renameFolder(event.getId(), event.getName()); | |
} | |
@Override | |
public void onFileRenamed(DiskResourceRenamedEvent event) | |
{ | |
storeWrapper.renameFile(event.getId(), event.getName()); | |
} | |
})); | |
// deletions | |
handlers.add(eventbus.addHandler(DiskResourceDeletedEvent.TYPE, | |
new DiskResourceDeletedEventHandler() | |
{ | |
@Override | |
public void onDeleted(DiskResourceDeletedEvent event) | |
{ | |
storeWrapper.delete(event.getFolders(), event.getFiles()); | |
} | |
})); | |
// file moved | |
handlers.add(eventbus.addHandler(FileMovedEvent.TYPE, new FileMovedEventHandler() | |
{ | |
@Override | |
public void onMoved(FileMovedEvent event) | |
{ | |
storeWrapper.moveFile(event.getFolderId(), event.getFileId()); | |
} | |
})); | |
} | |
/** | |
* Get a list of disk resources the user has selected | |
* | |
* @return a list of disk resources | |
*/ | |
public List<DiskResource> getSelectedDiskResources() | |
{ | |
return getSelectionModel().getSelectedItems(); | |
} | |
/** | |
* Prompt the user for necessary input to create a folder. | |
*/ | |
public void promptForFolderCreate() | |
{ | |
IPlantDialog dlg = new IPlantDialog(I18N.DISPLAY.newFolder(), 320, new AddFolderDialogPanel( | |
getRootParentId())); | |
dlg.show(); | |
} | |
/** | |
* Prompt the user for either file or folder renaming. | |
*/ | |
public void promptForRename() | |
{ | |
DiskResource selected = getSelectionModel().getSelectedItem(); | |
if(selected != null) | |
{ | |
IPlantDialog dlg = null; | |
if(selected instanceof Folder) | |
{ | |
dlg = new IPlantDialog(I18N.DISPLAY.rename(), 320, new RenameFolderDialogPanel(selected | |
.getId(), selected.getName())); | |
} | |
else if(selected instanceof File) | |
{ | |
dlg = new IPlantDialog(I18N.DISPLAY.rename(), 320, new RenameFileDialogPanel(selected | |
.getId(), selected.getName())); | |
} | |
// do we have a dialog to display | |
if(dlg != null) | |
{ | |
dlg.show(); | |
} | |
} | |
} | |
/** | |
* Get the upload parent based on the user's selection(s) | |
* | |
* @return a string representing the root parent ID | |
*/ | |
public String getRootParentId() | |
{ | |
String ret = storeWrapper.getRootFolderId(); // by default - let's return the | |
// upload folder's id | |
List<DiskResource> items = getSelectedDiskResources(); | |
// do we only have one item selected | |
if(items.size() == 1) | |
{ | |
DiskResource selected = items.get(0); | |
// if we have a file... let's return the parent's id | |
if(selected instanceof File) | |
{ | |
File file = (File)selected; | |
Folder parent = (Folder)file.getParent(); | |
ret = parent.getId(); | |
} | |
else | |
{ | |
ret = selected.getId(); | |
} | |
} | |
return ret; | |
} | |
private void removeEventHandlers() | |
{ | |
EventBus eventbus = EventBus.getInstance(); | |
// unregister | |
for(HandlerRegistration reg : handlers) | |
{ | |
eventbus.removeHandler(reg); | |
} | |
// clear our list | |
handlers.clear(); | |
} | |
public void cleanup() | |
{ | |
removeEventHandlers(); | |
} | |
/** | |
* Describes the column data that will be displayed in the will | |
* | |
* How the widget treats the enum values: | |
* <dl> | |
* <dt>ALL</dt> | |
* <dd>Informs this widget to display all columns: name, type, & uploaded date.</dd> | |
* <dt>CONCISE</dt> | |
* <dd>Informs this widget to display only columns: name & type.</dd> | |
* </dl> | |
* | |
* @author lenards | |
* | |
*/ | |
public enum ColumnDisplay | |
{ | |
/** | |
* All columns will be displayed in the grid. | |
*/ | |
ALL, | |
/** | |
* A small subset of columns will be displayed in the grid. | |
*/ | |
CONCISE | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment