Mercurial > dive4elements > river
view flys-client/src/main/java/de/intevation/flys/client/client/ui/ProjectList.java @ 4604:488db475613d
Add methods to hide and show the manage projects button of the header
It should be possible to show the manage projects button only if the ProjectList
is hidden. Therefore add methods to allow to show and hide the button.
author | Björn Ricks <bjoern.ricks@intevation.de> |
---|---|
date | Fri, 30 Nov 2012 10:00:39 +0100 |
parents | 7f86ab48284c |
children | c1c4c95ae9e4 |
line wrap: on
line source
package de.intevation.flys.client.client.ui; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.smartgwt.client.types.Alignment; import com.smartgwt.client.types.Autofit; import com.smartgwt.client.types.ListGridEditEvent; import com.smartgwt.client.types.ListGridFieldType; import com.smartgwt.client.types.Overflow; import com.smartgwt.client.types.SelectionStyle; import com.smartgwt.client.types.SortArrow; import com.smartgwt.client.types.SortDirection; import com.smartgwt.client.types.VerticalAlignment; import com.smartgwt.client.util.BooleanCallback; import com.smartgwt.client.util.SC; import com.smartgwt.client.widgets.Canvas; import com.smartgwt.client.widgets.Label; import com.smartgwt.client.widgets.grid.CellFormatter; import com.smartgwt.client.widgets.grid.HoverCustomizer; import com.smartgwt.client.widgets.grid.ListGrid; import com.smartgwt.client.widgets.grid.ListGridField; import com.smartgwt.client.widgets.grid.ListGridRecord; import com.smartgwt.client.widgets.grid.events.CellClickEvent; import com.smartgwt.client.widgets.grid.events.CellClickHandler; import com.smartgwt.client.widgets.grid.events.CellDoubleClickEvent; import com.smartgwt.client.widgets.grid.events.CellDoubleClickHandler; import com.smartgwt.client.widgets.grid.events.EditCompleteEvent; import com.smartgwt.client.widgets.grid.events.EditCompleteHandler; import com.smartgwt.client.widgets.grid.events.HeaderDoubleClickEvent; import com.smartgwt.client.widgets.grid.events.HeaderDoubleClickHandler; import com.smartgwt.client.widgets.grid.events.RowContextClickEvent; import com.smartgwt.client.widgets.grid.events.RowContextClickHandler; import com.smartgwt.client.widgets.layout.HLayout; import com.smartgwt.client.widgets.layout.VLayout; import com.smartgwt.client.widgets.menu.Menu; import com.smartgwt.client.widgets.menu.MenuItem; import com.smartgwt.client.widgets.menu.MenuItemSeparator; import com.smartgwt.client.widgets.menu.events.ClickHandler; import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent; import de.intevation.flys.client.client.Config; import de.intevation.flys.client.client.FLYS; import de.intevation.flys.client.client.FLYSConstants; import de.intevation.flys.client.client.event.CollectionChangeEvent; import de.intevation.flys.client.client.event.CollectionChangeHandler; import de.intevation.flys.client.client.event.FilterHandler; import de.intevation.flys.client.client.event.RangeFilterEvent; import de.intevation.flys.client.client.event.StringFilterEvent; import de.intevation.flys.client.client.services.AddArtifactService; import de.intevation.flys.client.client.services.AddArtifactServiceAsync; import de.intevation.flys.client.client.services.ArtifactService; import de.intevation.flys.client.client.services.ArtifactServiceAsync; import de.intevation.flys.client.client.services.CreateCollectionService; import de.intevation.flys.client.client.services.CreateCollectionServiceAsync; import de.intevation.flys.client.client.services.DeleteCollectionService; import de.intevation.flys.client.client.services.DeleteCollectionServiceAsync; import de.intevation.flys.client.client.services.DescribeCollectionService; import de.intevation.flys.client.client.services.DescribeCollectionServiceAsync; import de.intevation.flys.client.client.services.GetArtifactService; import de.intevation.flys.client.client.services.GetArtifactServiceAsync; import de.intevation.flys.client.client.services.SetCollectionNameService; import de.intevation.flys.client.client.services.SetCollectionNameServiceAsync; import de.intevation.flys.client.client.services.SetCollectionTTLService; import de.intevation.flys.client.client.services.SetCollectionTTLServiceAsync; import de.intevation.flys.client.client.services.UserCollectionsService; import de.intevation.flys.client.client.services.UserCollectionsServiceAsync; import de.intevation.flys.client.shared.model.Artifact; import de.intevation.flys.client.shared.model.Collection; import de.intevation.flys.client.shared.model.CollectionItem; import de.intevation.flys.client.shared.model.CollectionRecord; import de.intevation.flys.client.shared.model.Recommendation; import de.intevation.flys.client.shared.model.User; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.MissingResourceException; /** * The project list shows a list of projects of a specific user. * * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ public class ProjectList extends VLayout implements CollectionChangeHandler, EditCompleteHandler, FilterHandler { /** Interval to refresh the user's projects.*/ public static final int UPDATE_INTERVAL = 30000; /** Min Interval to refresh the user's projects.*/ public static final int MIN_UPDATE_INTERVAL = 5000; /** The initial width of this panel.*/ public static final int MIN_WIDTH = 300; /** The max length for new project names.*/ public static final int MAX_NAME_LENGTH = 50; public static final String COLUMN_DATE_WIDTH = "100px"; public static final String COLUMN_TITLE_WIDTH = "*"; public static final String COLUMN_FAVORITE_WIDTH = "75px"; /** The interface that provides i18n messages. */ private final FLYSConstants messages = GWT.create(FLYSConstants.class); /** The UserService used to retrieve information about the current user. */ protected UserCollectionsServiceAsync userCollectionsService = GWT.create(UserCollectionsService.class); /** The service used to set the name of a project.*/ protected SetCollectionNameServiceAsync nameService = GWT.create(SetCollectionNameService.class); /** The service used to set the name of a project.*/ protected SetCollectionTTLServiceAsync ttlService = GWT.create(SetCollectionTTLService.class); /** The service used to set the name of a project.*/ protected DeleteCollectionServiceAsync deleteService = GWT.create(DeleteCollectionService.class); /** The DescribeCollectionService used to update the existing collection. */ protected DescribeCollectionServiceAsync describeCollectionService = GWT.create(DescribeCollectionService.class); /** The ArtifactService used to communicate with the Artifact server. */ protected ArtifactServiceAsync createArtifactService = GWT.create(ArtifactService.class); /** The ArtifactService used to communicate with the Artifact server. */ protected CreateCollectionServiceAsync createCollectionService = GWT.create(CreateCollectionService.class); /** The AddArtifactService used to add an artifact to a collection. */ protected AddArtifactServiceAsync addArtifactService = GWT.create(AddArtifactService.class); /** The GetArtifactService used to open an existing collection. */ protected GetArtifactServiceAsync getArtifactService = GWT.create(GetArtifactService.class); /** A pointer to the FLYS instance.*/ protected FLYS flys; /** The user whose projects should be displayed.*/ protected User user; /** The grid that contains the project rows.*/ protected ListGrid grid; /** All user collections.*/ protected List<Collection> collections; /** The collections visible in the grid.*/ protected List<Collection> filteredCollections; /** The collection to clone*/ protected Collection cloneCollection; /** The message class that provides i18n strings.*/ protected FLYSConstants MSG = GWT.create(FLYSConstants.class); /** * The default constructor that creates a new ProjectList for a specific * user. * * @param user The user. */ public ProjectList(FLYS flys, User user) { super(); this.flys = flys; this.user = user; filteredCollections = new ArrayList<Collection>(); collections = new ArrayList<Collection>(); grid = new ListGrid(); initGrid(); init(); initTimer(); grid.addEditCompleteHandler(this); updateUserCollections(); } protected void initGrid() { grid.setWidth100(); grid.setAutoFitData(Autofit.VERTICAL); grid.setAutoFitMaxWidth(500); grid.setEmptyMessage(messages.no_projects()); grid.setLoadingDataMessage(messages.load_projects()); grid.setCanEdit(false); grid.setEditEvent(ListGridEditEvent.NONE); grid.setShowHeaderContextMenu(false); grid.setShowSortArrow(SortArrow.NONE); grid.setSortDirection(SortDirection.DESCENDING); grid.setSortField(0); grid.setSelectionType(SelectionStyle.SINGLE); grid.setCanReorderFields(false); grid.setLeaveScrollbarGap(false); grid.setBorder("0px"); ListGridField date = buildDateField(); ListGridField name = buildNameField(); ListGridField fav = buildFavoriteField(); grid.setFields(date, name, fav); grid.addHeaderDoubleClickHandler(new HeaderDoubleClickHandler() { @Override public void onHeaderDoubleClick(HeaderDoubleClickEvent event) { // Cancel the event. return; } }); // Add a handler to set / unset the favorite state of a project. grid.addCellClickHandler(new CellClickHandler() { @Override public void onCellClick(CellClickEvent event) { if (event.getColNum() != 2) { return; } CollectionRecord r = (CollectionRecord) event.getRecord(); Collection c = r.getCollection(); c.setTTL(c.getTTL() == 0 ? -1 : 0); updateCollectionTTL(c); } }); // Add a handler to open a project. grid.addCellDoubleClickHandler(new CellDoubleClickHandler() { @Override public void onCellDoubleClick(CellDoubleClickEvent e) { CollectionRecord record = (CollectionRecord) e.getRecord(); String uuid = record != null ? record.getCollection().identifier() : ""; getFlys().openProject(uuid); } }); // Add a handler to open a context menu. grid.addRowContextClickHandler(new RowContextClickHandler() { @Override public void onRowContextClick(RowContextClickEvent event) { CollectionRecord record = (CollectionRecord) event.getRecord(); Menu menu = createContextMenu(record); grid.setContextMenu(menu); menu.showContextMenu(); event.cancel(); } }); } /** * Initializes a repeating timer that updates the user's collections. The * interval is specified by the constant <i>UPDATE_INTERVAL</i>. */ protected void initTimer() { Config config = Config.getInstance(); int interval = config.getProjectListUpdateInterval(); interval = interval > MIN_UPDATE_INTERVAL ? interval : UPDATE_INTERVAL; GWT.log("Update project list every " + interval + " milliseconds."); Timer t = new Timer() { @Override public void run() { updateUserCollections(); } }; t.scheduleRepeating(interval); } public FLYS getFlys() { return flys; } /** * Creates a new context menu that interacts with a CollectionRecord. * * @param record The selected record. * * @return the context menu with operations that interact with * <i>record</i>. */ protected Menu createContextMenu(final CollectionRecord record) { Menu menu = new Menu(); MenuItem open = new MenuItem(messages.open_project()); open.addClickHandler(new ClickHandler() { @Override public void onClick(MenuItemClickEvent evt) { getFlys().openProject(record.getCollection().identifier()); } }); MenuItem del = new MenuItem(messages.delete_project()); del.addClickHandler(new ClickHandler() { @Override public void onClick(MenuItemClickEvent evt) { SC.ask(messages.really_delete(), new BooleanCallback() { @Override public void execute(Boolean value) { if (value) { deleteCollection(record.getCollection()); } } }); } }); MenuItem rename = new MenuItem(messages.rename_project()); rename.addClickHandler(new ClickHandler() { @Override public void onClick(MenuItemClickEvent evt) { int row = grid.getRecordIndex(record); grid.startEditing(row, 1, false); } }); MenuItem clone = new MenuItem(messages.clone_project()); clone.addClickHandler(new ClickHandler() { @Override public void onClick(MenuItemClickEvent evt) { cloneProject(record.getCollection()); } }); menu.addItem(open); menu.addItem(rename); menu.addItem(clone); menu.addItem(new MenuItemSeparator()); menu.addItem(del); return menu; } /** * The init() method handles the layout stuff for this widget. */ protected void init() { setWidth(MIN_WIDTH); setMinWidth(MIN_WIDTH); setHeight100(); setShowResizeBar(true); setShowEdges(false); setLayoutMargin(0); setLayoutAlign(VerticalAlignment.TOP); setOverflow(Overflow.AUTO); Label title = new Label(messages.projects()); title.setHeight("20"); title.setMargin(5); title.setWidth100(); title.setStyleName("projectHeader"); HLayout buttonWrapper = new HLayout(); Button addButton = new Button("+"); addButton.setStyleName("projectsAddButton"); addButton.setTitle(messages.new_project()); addButton.setWidth("30px"); Button closeButton = new Button("X"); closeButton.setStyleName("projectsCloseButton"); closeButton.setTitle(messages.projectlist_close()); closeButton.setWidth("30px"); buttonWrapper.addMember(addButton); buttonWrapper.addMember(closeButton); buttonWrapper.setAlign(Alignment.RIGHT); buttonWrapper.setAutoWidth(); HLayout titleWrapper = new HLayout(); titleWrapper.setStyleName("bgBlueMid"); titleWrapper.setWidth100(); titleWrapper.setHeight("20px"); titleWrapper.addMember(title); titleWrapper.addMember(buttonWrapper); Canvas gridWrapper = new Canvas(); gridWrapper.setPadding(0); titleWrapper.setWidth100(); gridWrapper.addChild(grid); TableFilter filter = new TableFilter(); filter.setHeight("30px"); filter.addFilterHandler(this); filter.setBorder("1px solid gray"); addMember(titleWrapper); addMember(gridWrapper); addMember(filter); addButton.addClickHandler( new com.google.gwt.event.dom.client.ClickHandler() { @Override public void onClick(ClickEvent ev) { flys.newProject(); } }); closeButton.addClickHandler( new com.google.gwt.event.dom.client.ClickHandler() { @Override public void onClick(ClickEvent ev) { hide(); } }); } @Override public void onFilterCriteriaChanged(StringFilterEvent event) { String search = event.getFilter(); if (search != null && search.length() > 0) { // Filter the records. filterCollections(search); } else { filteredCollections.clear(); for(int i = 0; i < collections.size(); i++) { filteredCollections.add(collections.get(i)); } updateGrid(); } } @Override public void onFilterCriteriaChanged(RangeFilterEvent event) { //Empty. No Ranges to filter. } /** On collection change, update list (probably name change or similar). */ @Override public void onCollectionChange(CollectionChangeEvent event) { if (event.getOldValue() == null) { updateUserCollections(); } } @Override public void onEditComplete(EditCompleteEvent event) { if (event.getColNum() != 1) { return; } int row = event.getRowNum(); CollectionRecord r = (CollectionRecord) grid.getRecord(row); Collection c = r.getCollection(); Map<?, ?> newValues = event.getNewValues(); String name = (String) newValues.get("name"); int maxLength = getMaxNameLength(); int length = name != null ? name.length() : 0; if (length <= 0 || length > maxLength) { String msg = messages.project_name_too_long(); msg = msg.replace("$LEN", String.valueOf(maxLength)); SC.warn(msg); ListGridRecord[] rs = grid.getRecords(); rs[row] = (ListGridRecord) event.getOldRecord(); grid.setRecords(rs); return; } c.setName(name); updateCollectionName(c); } /** * Set the name of the collection <i>c</i> to a new value. If the update * process succeeded, the project list is refreshed. * * @param c The Collection with a new name. */ protected void updateCollectionName(final Collection c) { if (c == null) { return; } GWT.log("Update Collection name: " + c.identifier()); GWT.log("=> New name = " + c.getName()); nameService.setName(c, new AsyncCallback<Void>(){ @Override public void onFailure(Throwable caught) { String msg = caught.getMessage(); try { SC.warn(messages.getString(msg)); } catch (MissingResourceException mre) { SC.warn(msg); } } @Override public void onSuccess(Void v) { updateUserCollections(); if(flys.getWorkspace().hasView(c.identifier())) { flys.getWorkspace().updateTitle(c.identifier(), c.getName()); } } }); } /** * Set the ttl of the collection <i>c</i> to a new value. If the update * process succeeded, the project list is refreshed. * * @param c The Collection with a new ttl. */ protected void updateCollectionTTL(Collection c) { if (c == null) { return; } GWT.log("Update Collection TTL: " + c.identifier()); GWT.log("=> New ttl = " + c.getTTL()); ttlService.setTTL(c, new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { String msg = caught.getMessage(); try { SC.warn(messages.getString(msg)); } catch (MissingResourceException mre) { SC.warn(msg); } } @Override public void onSuccess(Void v) { updateUserCollections(); } }); } /** * Delete the collection <i>c</i>. * * @param c The Collection that should be deleted. */ public void deleteCollection(final Collection c) { if (c == null) { return; } GWT.log("Delete Collection: " + c.identifier()); deleteService.delete(c, new AsyncCallback<Void>(){ @Override public void onFailure(Throwable caught) { String msg = caught.getMessage(); try { SC.warn(messages.getString(msg)); } catch (MissingResourceException mre) { SC.warn(msg); } } @Override public void onSuccess(Void v) { flys.getWorkspace().destroyProject(c.identifier()); updateUserCollections(); } }); } public void updateUserCollections() { GWT.log("==> ProjectList updates user collections!"); Config config = Config.getInstance(); String locale = config.getLocale(); userCollectionsService.getUserCollections(locale, user.identifier(), new AsyncCallback<Collection[]>() { @Override public void onFailure(Throwable caught) { String msg = caught.getMessage(); try { SC.warn(messages.getString(msg)); } catch (MissingResourceException mre) { SC.warn(msg); } } @Override public void onSuccess(Collection[] collections) { int num = collections != null ? collections.length : 0; GWT.log("Received " + num + " user collections."); updateGridDataSource(collections); } } ); } /** * Delete all entries in the ListGrid. */ protected void clearGrid() { ListGridRecord[] records = grid.getRecords(); for (ListGridRecord record: records) { grid.removeData(record); } } /** * Update the collections data source. * * First removes all collections to avoid duplicates, then add new entries. * * @param c Collections to set to the data source. */ protected void updateGridDataSource (Collection[] c) { collections.clear(); if(c == null) { clearGrid(); return; } for (Collection coll : c) { this.collections.add(coll); } filterCollections(""); } /** * Updates the ListGrid. */ protected void updateGrid() { clearGrid(); if (filteredCollections == null || filteredCollections.size() == 0) { return; } for (Collection c: filteredCollections) { grid.addData(new CollectionRecord(c)); } } /** * Filter for the user collections. * * @param search String to search for in collection names. */ protected void filterCollections(String search) { // Clear the collection list. filteredCollections.clear(); // Filter the list. for (int i = 0; i < collections.size(); i++) { String name; // Get the collection name. if (collections.get(i).getName().equals("") || collections.get(i).getName() == null) { name = collections.get(i).identifier(); } else { name = collections.get(i).getName(); } name = name.toLowerCase(); // Add a collection to the filtered list if the search string // matches. if (name.contains(search.toLowerCase())) { filteredCollections.add(collections.get(i)); } } updateGrid(); } public int getMaxNameLength() { return MAX_NAME_LENGTH; } /** * Builds the field in the grid that displays the creation time of a * project. * * @return the grid field. */ protected ListGridField buildDateField() { ListGridField date = new ListGridField( "creationTime", messages.projectlist_creationTime()); date.setType(ListGridFieldType.DATE); date.setCanEdit(false); date.setCellFormatter(new CellFormatter() { @Override public String format(Object value, ListGridRecord rec, int r, int c) { if (value == null) { return null; } DateTimeFormat dtf = DateTimeFormat.getFormat( messages.datetime_format()); return dtf.format((Date)value); } }); date.setWidth(COLUMN_DATE_WIDTH); date.setAlign(Alignment.CENTER); return date; } /** * Builds the field in the grid that displays the name of a project. * * @return the grid field. */ protected ListGridField buildNameField() { ListGridField name = new ListGridField( "name", messages.projectlist_title()); name.setType(ListGridFieldType.TEXT); name.setShowHover(true); name.setHoverCustomizer(new HoverCustomizer() { @Override public String hoverHTML( Object value, ListGridRecord record, int row, int col) { CollectionRecord r = (CollectionRecord) record; Collection c = r.getCollection(); String name = r.getName(); return name != null && name.length() > 0 ? name : c.identifier(); } }); name.setWidth(COLUMN_TITLE_WIDTH); name.setAlign(Alignment.LEFT); return name; } protected ListGridField buildFavoriteField() { ListGridField fav = new ListGridField( "ttl", messages.projectlist_favorite()); fav.setType(ListGridFieldType.IMAGE); String base = GWT.getHostPageBaseURL(); fav.setImageURLPrefix(base + "images/"); fav.setImageURLSuffix(".png"); fav.setWidth(COLUMN_FAVORITE_WIDTH); fav.setAlign(Alignment.CENTER); fav.setCanEdit(false); return fav; } protected void cloneProject(Collection c) { Config config = Config.getInstance(); String locale = config.getLocale(); cloneCollection = c; describeCollectionService.describe(c.identifier(), locale, new AsyncCallback<Collection>() { @Override public void onFailure(Throwable caught) { GWT.log("Could not DESCRIBE collection."); SC.warn(messages.getString(caught.getMessage())); } @Override public void onSuccess(Collection newCollection) { GWT.log("Successfully DESCRIBED collection."); String uuid = getMasterArtifact(newCollection); cloneArtifact(uuid, newCollection); } } ); } /** Get master artifacts UUID of a collection. */ protected String getMasterArtifact(Collection newCollection) { String uuid = newCollection.getItem(0).identifier(); // The master artifact uuid. return uuid; } /** Clone artifact/create collection, using the refArtifacts factory. */ protected void cloneArtifact(String uuid, Artifact refArtifact, final String locale) { Recommendation recommendation = new Recommendation( refArtifact.getName(), null, uuid, null); String factory = recommendation.getFactory(); createArtifactService.create( locale, factory, recommendation, new AsyncCallback<Artifact>() { @Override public void onFailure(Throwable caught) { GWT.log("Error loading recommendations: " + caught.getMessage()); } @Override public void onSuccess(Artifact artifact) { GWT.log("Created new artifact: " + artifact.getUuid()); createCollection(artifact); } } ); } /** * Clone a project (collection). */ protected void cloneArtifact(final String uuid, Collection newCollection) { Config config = Config.getInstance(); final String locale = config.getLocale(); // Find out which factory to use for cloning. CollectionItem master = newCollection.getItem(0); getArtifactService.getArtifact( locale, master.identifier(), master.hash(), new AsyncCallback<Artifact>() { @Override public void onFailure(Throwable caught) { SC.warn(MSG.getString(caught.getMessage())); } @Override public void onSuccess(Artifact artifact) { cloneArtifact(uuid, artifact, locale); } }); } protected void createCollection(final Artifact artifact) { Config config = Config.getInstance(); final String locale = config.getLocale(); final String ownerid = user.identifier(); createCollectionService.create( locale, ownerid, new AsyncCallback<Collection>() { @Override public void onFailure(Throwable caught) { GWT.log("Could not create the new collection."); SC.warn(messages.getString(caught.getMessage())); } @Override public void onSuccess(Collection collection) { GWT.log("Successfully created a new collection."); addArtifactToCollection(artifact, collection); } } ); } protected void addArtifactToCollection(Artifact a, Collection c) { Config config = Config.getInstance(); final String locale = config.getLocale(); addArtifactService.add( c, a, locale, new AsyncCallback<Collection>() { @Override public void onFailure(Throwable caught) { GWT.log("An error occured while adding artifact."); SC.warn(messages.getString(caught.getMessage())); } @Override public void onSuccess(Collection newColl) { String name = cloneCollection.getName(); if(name == null || name.equals("")) { name = cloneCollection.identifier(); } newColl.setName(messages.copy_of() + ": " + name); updateCollectionName(newColl); if(cloneCollection.getTTL() == 0) { newColl.setTTL(0); updateCollectionTTL(newColl); } updateUserCollections(); } } ); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :