ingo@805: package de.intevation.flys.client.client.ui; ingo@805: ingo@805: import java.util.ArrayList; ingo@805: import java.util.List; ingo@805: ingo@805: import com.google.gwt.core.client.GWT; ingo@805: import com.google.gwt.user.client.rpc.AsyncCallback; ingo@805: ingo@805: import com.smartgwt.client.util.SC; ingo@805: import com.smartgwt.client.widgets.Canvas; ingo@805: import com.smartgwt.client.widgets.grid.ListGrid; ingo@805: import com.smartgwt.client.widgets.grid.ListGridRecord; ingo@805: import com.smartgwt.client.widgets.grid.events.EditCompleteEvent; ingo@805: import com.smartgwt.client.widgets.grid.events.EditCompleteHandler; ingo@1309: import com.smartgwt.client.widgets.grid.events.RowContextClickEvent; ingo@1309: import com.smartgwt.client.widgets.grid.events.RowContextClickHandler; ingo@1309: import com.smartgwt.client.widgets.menu.Menu; ingo@1309: import com.smartgwt.client.widgets.menu.MenuItem; ingo@1309: import com.smartgwt.client.widgets.menu.events.ClickHandler; ingo@1309: import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent; ingo@805: ingo@805: import de.intevation.flys.client.shared.model.Collection; ingo@1309: import de.intevation.flys.client.shared.model.CollectionItemAttribute; ingo@805: import de.intevation.flys.client.shared.model.FacetRecord; ingo@805: import de.intevation.flys.client.shared.model.OutputMode; ingo@805: import de.intevation.flys.client.shared.model.Theme; ingo@805: import de.intevation.flys.client.shared.model.ThemeList; ingo@805: ingo@805: import de.intevation.flys.client.client.Config; ingo@805: import de.intevation.flys.client.client.FLYSConstants; ingo@805: import de.intevation.flys.client.client.event.HasOutputParameterChangeHandlers; felix@858: import de.intevation.flys.client.client.event.HasRedrawRequestHandlers; ingo@805: import de.intevation.flys.client.client.event.OnMoveEvent; ingo@805: import de.intevation.flys.client.client.event.OnMoveHandler; ingo@805: import de.intevation.flys.client.client.event.OutputParameterChangeEvent; ingo@805: import de.intevation.flys.client.client.event.OutputParameterChangeHandler; felix@858: import de.intevation.flys.client.client.event.RedrawRequestHandler; ingo@911: import de.intevation.flys.client.client.event.RedrawRequestEvent; ingo@911: import de.intevation.flys.client.client.event.RedrawRequestEvent.Type; ingo@805: import de.intevation.flys.client.client.services.CollectionAttributeService; ingo@805: import de.intevation.flys.client.client.services.CollectionAttributeServiceAsync; ingo@1309: import de.intevation.flys.client.client.services.CollectionItemAttributeService; ingo@1309: import de.intevation.flys.client.client.services.CollectionItemAttributeServiceAsync; ingo@805: ingo@805: ingo@805: public abstract class ThemePanel felix@854: extends Canvas felix@854: implements OnMoveHandler, felix@854: EditCompleteHandler, felix@858: HasOutputParameterChangeHandlers, felix@858: HasRedrawRequestHandlers ingo@805: { ingo@805: protected CollectionAttributeServiceAsync updater = ingo@805: GWT.create(CollectionAttributeService.class); ingo@805: ingo@1309: /** The service used to get collection item attributes. */ ingo@1309: protected CollectionItemAttributeServiceAsync itemAttributeService = ingo@1309: GWT.create(CollectionItemAttributeService.class); ingo@1309: ingo@805: private FLYSConstants MSG = GWT.create(FLYSConstants.class); ingo@805: felix@858: /** List of OutParameterChangedHandler. */ ingo@805: protected List outHandlers; felix@858: /** List of ChartShallRedrawHandler. */ felix@858: protected List redrawRequestHandlers; ingo@805: ingo@805: protected Collection collection; ingo@805: protected OutputMode mode; ingo@805: ingo@805: protected ThemeNavigationPanel navigation; ingo@805: protected ListGrid list; ingo@805: ingo@1309: /** The collection view*/ ingo@1309: protected CollectionView view; ingo@1309: ingo@805: felix@854: /** felix@854: * Setup Grid, navigation bar. felix@854: * @param collection Collection for which to show themes. felix@854: */ ingo@805: public ThemePanel(Collection collection, OutputMode mode) { ingo@805: this.collection = collection; ingo@805: this.mode = mode; felix@854: this.list = createGrid(); felix@854: felix@858: this.redrawRequestHandlers = new ArrayList(); ingo@805: this.outHandlers = new ArrayList(); ingo@805: this.navigation = new ThemeNavigationPanel(); ingo@805: this.navigation.addOnMoveHandler(this); ingo@805: } ingo@805: ingo@805: ingo@805: public abstract void activateTheme(Theme theme, boolean active); ingo@805: ingo@805: ingo@805: /** ingo@805: * Replace the current collection with a new one. NOTE: this operation ingo@805: * triggers updateGrid() which modifies the themes in the grid. ingo@805: * ingo@805: * @param collection The new collection object. ingo@805: */ ingo@805: protected void setCollection(Collection collection) { ingo@805: this.collection = collection; ingo@805: ingo@805: updateGrid(); ingo@805: } ingo@805: ingo@805: ingo@805: /** ingo@805: * Returns the ThemeList of the current collection and output mode. ingo@805: * ingo@805: * @return the current ThemeList. ingo@805: */ ingo@805: public ThemeList getThemeList() { ingo@805: return collection.getThemeList(mode.getName()); ingo@805: } ingo@805: ingo@805: ingo@805: /** ingo@805: * Registers a new OutputParameterChangeHandler. ingo@805: * ingo@805: * @param h The new handler. ingo@805: */ ingo@805: public void addOutputParameterChangeHandler(OutputParameterChangeHandler h){ ingo@805: if (h != null) { ingo@805: outHandlers.add(h); ingo@805: } ingo@805: } ingo@805: ingo@805: ingo@805: /** felix@858: * Registers a RedrawRequestHandler. felix@858: * felix@858: * @param h The new handler. felix@858: */ felix@858: public void addRedrawRequestHandler(RedrawRequestHandler h){ felix@858: if (h != null) { felix@858: redrawRequestHandlers.add(h); felix@858: } felix@858: } felix@858: felix@858: felix@858: /** felix@858: * Request a redraw of e.g. a Chart. felix@858: */ felix@858: protected void requestRedraw() { felix@858: for (RedrawRequestHandler handler: redrawRequestHandlers) { ingo@911: handler.onRedrawRequest(new RedrawRequestEvent(Type.RESET)); felix@858: } felix@858: } felix@858: felix@858: felix@858: /** ingo@805: * Called when the attribution of an output changed. It informs the ingo@805: * registered handlers about the changes. ingo@805: */ ingo@805: protected void fireOutputParameterChanged() { ingo@805: OutputParameterChangeEvent evt = new OutputParameterChangeEvent(); ingo@805: ingo@805: for (OutputParameterChangeHandler handler: outHandlers) { ingo@805: handler.onOutputParameterChanged(evt); ingo@805: } ingo@805: } ingo@805: ingo@805: ingo@1309: public void setCollectionView(CollectionView view) { ingo@1309: this.view = view; ingo@1309: } ingo@1309: ingo@1309: ingo@805: /** ingo@805: * This method is used to clear the current theme grid and add new updated ingo@805: * data. ingo@805: */ ingo@805: protected void updateGrid() { ingo@805: GWT.log("ThemePanel.updateGrid"); ingo@805: ingo@805: clearGrid(); ingo@805: ingo@805: ThemeList themeList = getThemeList(); ingo@805: ingo@805: if (themeList == null) { ingo@805: GWT.log("ERROR: No theme list."); ingo@805: return; ingo@805: } ingo@805: ingo@805: int count = themeList.getThemeCount(); ingo@805: ingo@805: for (int i = 1; i <= count; i++) { ingo@805: Theme theme = themeList.getThemeAt(i); ingo@805: ingo@805: if (theme == null) { ingo@805: continue; ingo@805: } ingo@805: ingo@805: list.addData(new FacetRecord(theme)); ingo@805: } ingo@805: ingo@805: fireOutputParameterChanged(); ingo@805: } ingo@805: ingo@805: ingo@805: /** ingo@805: * This method triggers the CollectionAttributeService. Based on the current ingo@805: * collectin settings, the attribute of the collection is modified or not. ingo@805: * But in every case, we will get a new collection object - which might be ingo@805: * the same as the current one. ingo@805: */ ingo@805: public void updateCollection() { ingo@805: final Config config = Config.getInstance(); ingo@805: final String url = config.getServerUrl(); ingo@805: final String loc = config.getLocale(); ingo@805: ingo@805: GWT.log("ThemePanel.updateCollection via RPC now"); ingo@805: ingo@805: // don't forget to enable the panel after the request has finished! ingo@805: disable(); ingo@805: ingo@805: updater.update(collection, url, loc, new AsyncCallback() { ingo@805: public void onFailure(Throwable caught) { ingo@805: GWT.log("Could not update collection attributes."); ingo@805: SC.warn(MSG.getString(caught.getMessage())); ingo@805: ingo@805: enable(); ingo@805: } ingo@805: ingo@805: ingo@805: public void onSuccess(Collection collection) { ingo@805: setCollection(collection); ingo@805: ingo@805: enable(); ingo@805: } ingo@805: }); ingo@805: } ingo@805: ingo@805: felix@854: /** felix@854: * Create and configure the Grid to display. felix@854: */ felix@854: protected ListGrid createGrid() { ingo@1309: ListGrid grid = new ListGrid(); ingo@1309: grid.addRowContextClickHandler(new RowContextClickHandler() { ingo@1309: public void onRowContextClick(RowContextClickEvent event) { ingo@1309: ListGridRecord[] records = list.getSelection(); ingo@1309: ingo@1309: Menu menu = null; ingo@1309: ingo@1309: if (records == null || records.length == 0) { ingo@1309: return; ingo@1309: } ingo@1309: else if (records.length == 1) { ingo@1309: menu = getSingleContextMenu(records); ingo@1309: } ingo@1309: else if (records.length > 1) { ingo@1309: menu = getMultiContextMenu(records); ingo@1309: } ingo@1309: ingo@1309: if (menu != null) { ingo@1309: list.setContextMenu(menu); ingo@1309: menu.showContextMenu(); ingo@1309: ingo@1309: event.cancel(); ingo@1309: } ingo@1309: } ingo@1309: }); ingo@1309: ingo@1309: return grid; felix@854: } ingo@805: ingo@805: ingo@805: /** ingo@805: * A method that removes all records from theme grid. ingo@805: */ ingo@805: protected void clearGrid() { ingo@805: ListGridRecord[] records = list.getRecords(); ingo@805: ingo@805: if (records == null || records.length == 0) { ingo@805: return; ingo@805: } ingo@805: ingo@805: for (ListGridRecord record: records) { ingo@805: list.removeData(record); ingo@805: } ingo@805: } ingo@805: ingo@805: ingo@1309: protected Menu getSingleContextMenu(final ListGridRecord[] records) { ingo@1309: Menu menu = new Menu(); ingo@1309: ingo@1309: menu.addItem(createActivateItem(records)); ingo@1309: menu.addItem(createDeactivateItem(records)); ingo@1309: menu.addItem(createRemoveItem(records)); ingo@1309: menu.addItem(createPropertiesItem(records)); ingo@1309: ingo@1309: return menu; ingo@1309: } ingo@1309: ingo@1309: ingo@1309: protected Menu getMultiContextMenu(final ListGridRecord[] records) { ingo@1309: Menu menu = new Menu(); ingo@1309: ingo@1309: menu.addItem(createActivateItem(records)); ingo@1309: menu.addItem(createDeactivateItem(records)); ingo@1309: menu.addItem(createRemoveItem(records)); ingo@1309: ingo@1309: return menu; ingo@1309: } ingo@1309: ingo@1309: ingo@1309: protected MenuItem createPropertiesItem(final ListGridRecord[] records) { ingo@1309: MenuItem properties = new MenuItem(MSG.properties()); ingo@1309: ingo@1309: properties.addClickHandler(new ClickHandler() { ingo@1309: public void onClick(MenuItemClickEvent evt) { ingo@1309: GWT.log("clicked properties"); ingo@1309: for (ListGridRecord record: records) { ingo@1309: openStyleEditor((FacetRecord) record); ingo@1309: } ingo@1309: } ingo@1309: }); ingo@1309: ingo@1309: return properties; ingo@1309: } ingo@1309: ingo@1309: ingo@1309: protected MenuItem createActivateItem(final ListGridRecord[] records) { ingo@1309: MenuItem activate = new MenuItem(MSG.activateTheme()); ingo@1309: ingo@1309: activate.addClickHandler(new ClickHandler() { ingo@1309: public void onClick(MenuItemClickEvent evt) { ingo@1309: for (ListGridRecord record: records) { ingo@1309: FacetRecord facet = (FacetRecord) record; ingo@1309: activateTheme(facet.getTheme(), true); ingo@1309: } ingo@1309: ingo@1309: updateCollection(); ingo@1309: } ingo@1309: }); ingo@1309: ingo@1309: return activate; ingo@1309: } ingo@1309: ingo@1309: ingo@1309: protected MenuItem createDeactivateItem(final ListGridRecord[] records) { ingo@1309: MenuItem deactivate = new MenuItem(MSG.deactivateTheme()); ingo@1309: ingo@1309: deactivate.addClickHandler(new ClickHandler() { ingo@1309: public void onClick(MenuItemClickEvent evt) { ingo@1309: for (ListGridRecord record: records) { ingo@1309: FacetRecord facet = (FacetRecord) record; ingo@1309: activateTheme(facet.getTheme(), false); ingo@1309: } ingo@1309: ingo@1309: updateCollection(); ingo@1309: } ingo@1309: }); ingo@1309: ingo@1309: return deactivate; ingo@1309: } ingo@1309: ingo@1309: ingo@1309: protected MenuItem createRemoveItem(final ListGridRecord[] records) { ingo@1309: MenuItem remove = new MenuItem(MSG.removeTheme()); ingo@1309: ingo@1309: remove.addClickHandler(new ClickHandler() { ingo@1309: public void onClick(MenuItemClickEvent evt) { ingo@1309: SC.warn("Currently not implemented"); ingo@1309: ingo@1309: for (ListGridRecord record: records) { ingo@1309: FacetRecord facet = (FacetRecord) record; ingo@1309: } ingo@1309: } ingo@1309: }); ingo@1309: ingo@1309: return remove; ingo@1309: } ingo@1309: ingo@1309: ingo@805: /** ingo@805: * This method is called after a cell in the theme grid has been modified. ingo@805: * ingo@805: * @param event The event that stores information about the modified record. ingo@805: */ ingo@805: @Override ingo@805: public void onEditComplete(EditCompleteEvent event) { ingo@805: GWT.log("Edited record."); ingo@805: ingo@805: int row = event.getRowNum(); ingo@805: FacetRecord rec = (FacetRecord) list.getRecord(row); ingo@805: ingo@805: activateTheme(rec.getTheme(), rec.getActive()); ingo@805: ingo@805: updateCollection(); ingo@805: } ingo@805: ingo@805: ingo@1303: /** ingo@1303: * This method should be defined in subclasses that wants to listen to this ingo@1303: * event. ingo@1303: * ingo@1303: * @param theme The theme that is moved. ingo@1303: * @param oldIdx The index of the theme before it was moved. ingo@1303: * @param newIdx The index of the theme after it was moved. ingo@1303: */ ingo@1303: protected void fireThemeMoved(Theme theme, int oldIdx, int newIdx) { ingo@1303: // TODO Implement in subclasses ingo@1303: } ingo@1303: ingo@1303: ingo@805: @Override ingo@805: public void onMove(OnMoveEvent event) { ingo@805: int type = event.getType(); ingo@805: ingo@805: GWT.log("ThemePanel.onMove: " + type); ingo@805: ingo@805: ListGridRecord[] records = list.getSelection(); ingo@805: ingo@805: if (records == null || records.length == 0) { ingo@805: GWT.log("ThemePanel.onMove: No records selected."); ingo@805: return; ingo@805: } ingo@805: ingo@805: switch (type) { ingo@805: case 0: moveRecordsTop(records); break; ingo@805: case 1: moveRecordsUp(records); break; ingo@805: case 2: moveRecordsDown(records); break; ingo@805: case 3: moveRecordsBottom(records); break; ingo@805: } ingo@805: ingo@805: updateCollection(); ingo@805: } ingo@805: ingo@805: ingo@805: /** ingo@805: * Moves the selected grid records (themes) to the top of the grid. ingo@805: * ingo@805: * @param records The selected themes in the list. Null not permitted. ingo@805: */ ingo@805: protected void moveRecordsTop(ListGridRecord[] records) { ingo@805: ThemeList themeList = getThemeList(); ingo@805: ingo@805: int idx = 1; ingo@805: ingo@805: for (ListGridRecord record: records) { ingo@805: Theme theme = ((FacetRecord) record).getTheme(); ingo@1303: fireThemeMoved(theme, theme.getPosition(), idx); ingo@805: themeList.setThemePosition(theme, idx++); ingo@805: } ingo@805: ingo@805: updateGrid(); ingo@805: } ingo@805: ingo@805: ingo@805: /** ingo@805: * Moves the selected grid records (themes) one step up. ingo@805: * ingo@805: * @param records The selected themes in the list. Null not permitted. ingo@805: */ ingo@805: protected void moveRecordsUp(ListGridRecord[] records) { ingo@805: ThemeList themeList = getThemeList(); ingo@805: ingo@805: int[] newPos = new int[records.length]; ingo@805: ingo@805: for (int i = 0; i < records.length ; i++) { ingo@805: Theme theme = ((FacetRecord) records[i]).getTheme(); ingo@805: newPos[i] = theme.getPosition() - 1; ingo@805: } ingo@805: ingo@805: for (int i = 0; i < records.length ; i++) { ingo@805: Theme theme = ((FacetRecord) records[i]).getTheme(); ingo@1303: fireThemeMoved(theme, theme.getPosition(), newPos[i]); ingo@805: themeList.setThemePosition(theme, newPos[i]); ingo@805: } ingo@805: ingo@805: updateGrid(); ingo@805: } ingo@805: ingo@805: ingo@805: /** ingo@805: * Moves the selected grid records (themes) one step down. ingo@805: * ingo@805: * @param records The selected themes in the list. Null not permitted. ingo@805: */ ingo@805: protected void moveRecordsDown(ListGridRecord[] records) { ingo@805: ThemeList themeList = getThemeList(); ingo@805: ingo@805: int[] newPos = new int[records.length]; ingo@805: ingo@805: for (int i = records.length-1; i >= 0; i--) { ingo@805: Theme theme = ((FacetRecord) records[i]).getTheme(); ingo@805: newPos[i] = theme.getPosition()+1; ingo@805: } ingo@805: ingo@805: for (int i = records.length-1; i >= 0; i--) { ingo@805: Theme theme = ((FacetRecord) records[i]).getTheme(); ingo@1303: fireThemeMoved(theme, theme.getPosition(), newPos[i]); ingo@805: themeList.setThemePosition(theme, newPos[i]); ingo@805: } ingo@805: ingo@805: updateGrid(); ingo@805: } ingo@805: ingo@805: ingo@805: /** ingo@805: * Moves the selected grid records (themes) to the bottom of the grid. ingo@805: * ingo@805: * @param records The selected themes in the list. Null not permitted. ingo@805: */ ingo@805: protected void moveRecordsBottom(ListGridRecord[] records) { ingo@805: ThemeList themeList = getThemeList(); ingo@805: ingo@805: int idx = themeList.getThemeCount(); ingo@805: ingo@805: for (int i = records.length-1; i >= 0; i--) { ingo@805: Theme theme = ((FacetRecord) records[i]).getTheme(); ingo@1303: fireThemeMoved(theme, theme.getPosition(), idx); ingo@805: themeList.setThemePosition(theme, idx--); ingo@805: } ingo@805: ingo@805: updateGrid(); ingo@805: } ingo@1309: ingo@1309: ingo@1309: protected void openStyleEditor(final FacetRecord record) { ingo@1309: Config config = Config.getInstance(); ingo@1309: String url = config.getServerUrl(); ingo@1309: String locale = config.getLocale(); ingo@1309: ingo@1309: String artifact = record.getTheme().getArtifact(); ingo@1309: ingo@1309: itemAttributeService.getCollectionItemAttribute( ingo@1309: this.collection, ingo@1309: artifact, ingo@1309: url, ingo@1309: locale, ingo@1309: new AsyncCallback() { ingo@1309: public void onFailure (Throwable caught) { ingo@1309: GWT.log("Could not get Collection item attributes."); ingo@1309: } ingo@1309: public void onSuccess(CollectionItemAttribute cia) { ingo@1309: GWT.log("Successfully loaded collectionitem attributes."); ingo@1309: StyleEditorWindow win = new StyleEditorWindow( ingo@1309: collection, ingo@1309: cia, ingo@1309: record); ingo@1309: win.setCollectionView(view); ingo@1309: win.show(); ingo@1309: } ingo@1309: }); ingo@1309: } ingo@805: } ingo@805: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :