ingo@523: package de.intevation.flys.client.client.ui.chart;
ingo@523:
ingo@523: import com.google.gwt.core.client.GWT;
ingo@523:
felix@1456: import com.google.gwt.user.client.rpc.AsyncCallback;
ingo@523:
felix@1456: import com.smartgwt.client.types.ListGridFieldType;
felix@1456:
felix@1456: import com.smartgwt.client.widgets.grid.ListGridField;
felix@1456: import com.smartgwt.client.widgets.grid.ListGridRecord;
felix@1456: import com.smartgwt.client.widgets.layout.VLayout;
felix@1456: import com.smartgwt.client.widgets.menu.events.ClickHandler;
felix@1456:
felix@1456: import com.smartgwt.client.widgets.menu.Menu;
felix@1456: import com.smartgwt.client.widgets.menu.MenuItem;
felix@1456: import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
felix@1456:
felix@1456: import com.smartgwt.client.util.SC;
felix@1456:
felix@1456: import de.intevation.flys.client.shared.model.Artifact;
felix@1456: import de.intevation.flys.client.shared.model.Data;
felix@1456: import de.intevation.flys.client.shared.model.DefaultData;
felix@1456: import de.intevation.flys.client.shared.model.DefaultArtifact;
felix@1456: import de.intevation.flys.client.shared.model.FacetRecord;
felix@1456: import de.intevation.flys.client.shared.model.OutputMode;
felix@1456: import de.intevation.flys.client.shared.model.Recommendation;
ingo@524: import de.intevation.flys.client.shared.model.Theme;
felix@1456: import de.intevation.flys.client.shared.model.ThemeList;
ingo@523:
felix@1456: import de.intevation.flys.client.client.Config;
ingo@523: import de.intevation.flys.client.client.FLYSConstants;
felix@1474: import de.intevation.flys.client.client.ui.CollectionView;
ingo@805: import de.intevation.flys.client.client.ui.ThemePanel;
ingo@523:
felix@854: import de.intevation.flys.client.client.services.FeedService;
felix@854: import de.intevation.flys.client.client.services.FeedServiceAsync;
ingo@523:
felix@1456: import de.intevation.flys.client.client.services.LoadArtifactService;
felix@1456: import de.intevation.flys.client.client.services.LoadArtifactServiceAsync;
felix@1456:
felix@1456:
ingo@523: /**
felix@1430: * ThemePanel on the left in CollectionView.
felix@1430: * Contains control widgets for "themes", which are plotted in a diagram (chart).
felix@1430: *
ingo@523: * @author Ingo Weinzierl
ingo@523: */
ingo@805: public class ChartThemePanel extends ThemePanel {
felix@1456: /** Artifact Clone/Creation service. */
felix@1456: protected LoadArtifactServiceAsync loadService =
felix@1456: GWT.create(LoadArtifactService.class);
ingo@805:
ingo@523: /** The interface that provides i18n messages. */
felix@858: protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
ingo@526:
felix@854: public static final String GRID_FIELD_ACTIVE = "active";
felix@854: public static final String GRID_FIELD_NAME = "name";
felix@854: public static final String GRID_FIELD_ACTIONS = "actions";
ingo@523:
felix@854: FeedServiceAsync feedService = GWT.create(
felix@854: de.intevation.flys.client.client.services.FeedService.class);
ingo@523:
felix@1456:
felix@1517: /** Constructor for a ChartThemePanel. */
felix@1474: public ChartThemePanel(
felix@1474: OutputMode mode,
felix@1474: CollectionView view
felix@1474: ) {
felix@1555: super(mode, view);
ingo@523:
ingo@523: initGrid();
ingo@523: initLayout();
ingo@523:
ingo@523: updateGrid();
ingo@523: }
ingo@523:
ingo@523:
felix@1514: /** Creates Layout with theme list and navigation bar inside. */
felix@1430: protected VLayout createLayout() {
felix@1430: VLayout layout = new VLayout();
felix@1430: layout.setWidth100();
felix@1430: layout.setHeight100();
felix@1430:
felix@1430: layout.addMember(list);
felix@1430: layout.addMember(navigation);
felix@1430:
felix@1430: return layout;
felix@1430: }
felix@1430:
felix@1456:
ingo@523: /**
ingo@523: * Initializes the layout of this panel.
ingo@523: */
ingo@523: protected void initLayout() {
ingo@523: setWidth100();
ingo@523: setHeight100();
ingo@523:
felix@1430: addChild(createLayout());
ingo@523: }
ingo@523:
ingo@523:
ingo@523: /**
ingo@523: * Initializes the components (columns) of the theme grid.
ingo@523: */
ingo@523: protected void initGrid() {
ingo@523: list.setCanEdit(true);
ingo@523: list.setCanSort(false);
felix@858: list.setShowRecordComponents(false);
ingo@523: list.setShowRecordComponentsByCell(true);
ingo@523: list.setShowHeader(true);
ingo@523: list.setShowHeaderContextMenu(false);
ingo@523: list.setWidth100();
ingo@523: list.setHeight100();
ingo@523:
ingo@523: list.addEditCompleteHandler(this);
ingo@523:
ingo@1288: ListGridField active = new ListGridField(GRID_FIELD_ACTIVE, " ", 20);
ingo@523: active.setType(ListGridFieldType.BOOLEAN);
ingo@523:
ingo@523: ListGridField name = new ListGridField(
ingo@523: GRID_FIELD_NAME, MSG.chart_themepanel_header_themes());
ingo@523: name.setType(ListGridFieldType.TEXT);
ingo@523:
felix@858: list.setFields(active, name);
ingo@523: }
ingo@523:
ingo@523:
felix@1460: /** Set theme active/inactive. */
ingo@805: @Override
ingo@805: public void activateTheme(Theme theme, boolean active) {
ingo@805: theme.setActive(active ? 1 : 0);
ingo@527: }
felix@1456:
felix@1456:
felix@1457: /** Returns name of longitudinal section area facets. */
felix@1457: protected String getAreaFacetName() {
felix@1457: return "longitudinal_section.area";
felix@1457: }
felix@1457:
felix@1517:
felix@1517: /** Create the DataProvider ('Blackboard') key for a theme. */
felix@1514: public static String areaKey(Theme theme) {
felix@1514: return theme.getArtifact() + ":" + theme.getFacet() + ":"
felix@1514: + theme.getIndex();
felix@1514: }
felix@1514:
felix@1457:
felix@1456: /**
felix@1456: * Tell an area artifact where to get the upper and lower curve from.
felix@1462: * @param artifact UUID of area-artifact.
felix@1456: */
felix@1462: public void feedTellArea(
felix@1462: final String artifact,
felix@1462: Theme under,
felix@1462: Theme over,
felix@1462: boolean between
felix@1462: ) {
felix@1456: Data[] feedData;
felix@1456:
felix@1456: if (over != null && under != null) {
felix@1456: feedData = new Data[] {
felix@1456: DefaultData.createSimpleStringData("area.curve_under",
felix@1514: areaKey(under)),
felix@1456: DefaultData.createSimpleStringData("area.curve_over",
felix@1514: areaKey(over)),
felix@1456: DefaultData.createSimpleStringData("area.name",
felix@1456: over.getDescription() + " / " + under.getDescription()),
felix@1456: DefaultData.createSimpleStringData("area.facet",
felix@1462: getAreaFacetName()),
felix@1462: DefaultData.createSimpleStringData("area.between",
felix@1462: (between)? "true" : "false")
felix@1456: };
felix@1517: GWT.log("Have 'over' and 'under' curve");
felix@1456: }
felix@1456: else if (over == null && under != null) {
felix@1456: feedData = new Data[] {
felix@1456: DefaultData.createSimpleStringData("area.curve_under",
felix@1514: areaKey(under)),
felix@1456: DefaultData.createSimpleStringData("area.name",
felix@1456: under.getDescription() + " / " + MSG.getString("x_axis")),
felix@1456: DefaultData.createSimpleStringData("area.facet",
felix@1462: getAreaFacetName()),
felix@1462: DefaultData.createSimpleStringData("area.between",
felix@1462: (between)? "true" : "false")
felix@1456: };
felix@1517: GWT.log("Have 'under' curve only");
felix@1456: }
felix@1456: else if (over != null && under == null) {
felix@1456: feedData = new Data[] {
felix@1456: DefaultData.createSimpleStringData("area.curve_over",
felix@1514: areaKey(over)),
felix@1456: DefaultData.createSimpleStringData("area.name",
felix@1456: MSG.getString("x_axis") + " / " + over.getDescription()),
felix@1456: DefaultData.createSimpleStringData("area.facet",
felix@1462: getAreaFacetName()),
felix@1462: DefaultData.createSimpleStringData("area.between",
felix@1462: (between)? "true" : "false")
felix@1456: };
felix@1517: GWT.log("Have 'over' curve only");
felix@1456: }
felix@1456: else {
felix@1456: GWT.log("Missing Data for area painting.");
felix@1456: return;
felix@1456: }
felix@1456:
felix@1456: feedService.feed(
felix@1456: Config.getInstance().getLocale(),
felix@1456: new DefaultArtifact(artifact, "TODO:hash"),
felix@1456: feedData,
felix@1456: new AsyncCallback() {
felix@1456: public void onFailure(Throwable caught) {
felix@1456: GWT.log("Could not feed artifact (" + artifact
felix@1456: + ") with area info: " + caught.getMessage());
felix@1456: SC.warn(MSG.getString(caught.getMessage()));
felix@1456: enable();
felix@1456: }
felix@1514: public void onSuccess(Artifact fartifact) {
felix@1456: GWT.log("Successfully set area params to " + artifact);
felix@1456: requestRedraw();
felix@1456: updateCollection();
felix@1456: updateGrid();
felix@1456: enable();
felix@1456: }
felix@1456: });
felix@1456: }
felix@1456:
felix@1456:
felix@1456: /**
felix@1456: * Create and parameterize a new area artifact.
felix@1456: * @param under
felix@1462: * @param over if null, against axis.
felix@1462: * @param between if true, ignore under/over order.
felix@1456: */
felix@1456: public void createAreaArtifact(
felix@1462: final Theme over,
felix@1462: final Theme under,
felix@1462: final boolean between
felix@1456: ) {
felix@1456: Config config = Config.getInstance();
felix@1456: String locale = config.getLocale();
felix@1456:
felix@1456: Recommendation area = new Recommendation(
felix@1456: "area",
felix@1456: "",
felix@1456: "",
felix@1456: null);
felix@1456: Recommendation[] recommendations = new Recommendation[] {area};
felix@1456:
felix@1456: loadService.loadMany(
felix@1555: this.getCollection(),
felix@1456: recommendations,
felix@1456: null, //use individual factories.
felix@1456: locale,
felix@1456: new AsyncCallback() {
felix@1456: public void onFailure(Throwable caught) {
felix@1456: GWT.log("Failed, no area artifact: " + caught.getMessage());
felix@1456: enable();
felix@1456: // TODO SC.warn
felix@1456: }
felix@1456: public void onSuccess(Artifact[] artifacts) {
felix@1456: GWT.log("Success, created area artifact: "
felix@1456: + artifacts[0].getUuid());
felix@1456: // Now, feed the artifact with the relevant data.
felix@1462: feedTellArea(artifacts[0].getUuid(), under, over, between);
felix@1456: }
felix@1456: }
felix@1517: );
felix@1456: }
felix@1456:
sascha@2905:
felix@1456: /**
felix@1456: * Return true if two themes are canditates for an area being
felix@1456: * rendered between them.
felix@1456: * TODO join with canArea, generalize to allow easier modification
felix@1456: * in subclasses.
felix@1456: */
felix@1456: protected boolean areAreaCompatible(Theme a, Theme b) {
felix@1456: if (a.equals(b)) {
felix@1456: return false;
felix@1456: }
felix@1460: if (a.getFacet().equals("longitudinal_section.w") ||
felix@1460: a.getFacet().equals("other.wkms")) {
felix@1460: return b.getFacet().equals("longitudinal_section.w")
felix@1460: || b.getFacet().equals("other.wkms");
felix@1456: }
felix@1456: else if (a.getFacet().equals("longitudinal_section.q")) {
felix@1456: return b.getFacet().equals("longitudinal_section.q");
felix@1456: }
felix@1456: return false;
felix@1456: }
felix@1456:
felix@1456:
felix@1456: /**
felix@1456: * True if context menu should contain 'create area' submenu on
felix@1456: * this theme.
felix@1456: */
felix@1456: protected boolean canArea(Theme a) {
felix@1456: return a.getFacet().equals("longitudinal_section.q")
felix@1460: || a.getFacet().equals("longitudinal_section.w")
felix@1460: || a.getFacet().equals("other.wkms");
felix@1456: }
felix@1456:
felix@1456:
felix@1559: /** Attach menu/item to open editor for Manual Points. */
felix@1559: protected void attachManualPointsMenu(Menu menu) {
felix@1559: menu.addItem(createSeparator());
felix@1559: MenuItem editManualPoints = new MenuItem(MSG.editpoints());
sascha@2905:
felix@1559: editManualPoints.addClickHandler(new ClickHandler() {
felix@1559: public void onClick(MenuItemClickEvent evt) {
raimund@2483: if(mode.getName().equals("historical_discharge")) {
raimund@2483: new ManualDatePointsEditor(view.getCollection(),
raimund@2483: redrawRequestHandlers.get(0),
raimund@2483: mode.getName()).show();
raimund@2483: }
raimund@2483: else {
raimund@2483: new ManualPointsEditor(view.getCollection(),
raimund@2483: redrawRequestHandlers.get(0),
raimund@2483: mode.getName()).show();
raimund@2483: }
felix@1559: }
felix@1559: });
felix@1559: menu.addItem(editManualPoints);
felix@1559: }
felix@1559:
felix@1559:
felix@1456: /**
felix@1559: * Include area specific menu items and manual point editor, depending
felix@1559: * on facet.
felix@1456: */
felix@1456: protected Menu getSingleContextMenu(final ListGridRecord[] records) {
felix@1456: Menu menu = super.getSingleContextMenu(records);
felix@1456:
felix@1456: final Theme facetTheme = ((FacetRecord)records[0]).getTheme();
felix@1456: String thisItem = facetTheme.getDescription();
felix@1456: if (!canArea(facetTheme)) {
felix@1607: if (facetTheme.getFacet().endsWith("manualpoints")) {
felix@1559: attachManualPointsMenu(menu);
felix@1559: return menu;
felix@1559: }
felix@1559: else {
felix@1559: return menu;
felix@1559: }
felix@1456: }
sascha@2905:
felix@1456: menu.addItem(createSeparator());
felix@1456:
felix@1456: MenuItem areaMenuItem = new MenuItem(MSG.chart_themepanel_new_area());
felix@1456: Menu areaMenu = new Menu();
felix@1456:
felix@1456: ThemeList themes = getThemeList();
felix@1456: int nThemes = themes.getThemeCount();
felix@1456:
felix@1517: // Create the "under..." submenu.
felix@1456: MenuItem underMenuItem = new MenuItem(MSG.chart_themepanel_area_under());
felix@1456: Menu underMenu = new Menu();
felix@1456: for (int i = 0; i < nThemes; i++) {
felix@1456: final Theme theme = themes.getThemeAt(i+1);
felix@2442:
felix@2442: if (theme.getVisible() == 0) {
felix@2442: continue;
felix@2442: }
felix@2442:
felix@1456: if (!areAreaCompatible(facetTheme, theme)) {
felix@1456: continue;
felix@1456: }
felix@2442:
felix@1456: MenuItem againster = new MenuItem(theme.getDescription());
felix@1456: underMenu.addItem(againster);
felix@1456:
felix@1456: againster.addClickHandler(new ClickHandler() {
felix@1456: public void onClick(MenuItemClickEvent evt) {
felix@1456: disable();
felix@1456: createAreaArtifact(theme, facetTheme, false);
felix@1456: }
felix@1456: });
felix@1456: }
felix@1456:
felix@1517: // Create the "over..." submenu.
felix@1456: MenuItem overMenuItem = new MenuItem(MSG.chart_themepanel_area_over());
felix@1456: Menu overMenu = new Menu();
felix@1456: for (int i = 0; i < nThemes; i++) {
felix@1456: final Theme theme = themes.getThemeAt(i+1);
felix@2442: if (theme.getVisible() == 0) {
felix@2442: continue;
felix@2442: }
felix@1456: if (!areAreaCompatible(facetTheme, theme)) {
felix@1456: continue;
felix@1456: }
felix@1456: MenuItem againster = new MenuItem(theme.getDescription());
felix@1456: overMenu.addItem(againster);
felix@1456:
felix@1456: againster.addClickHandler(new ClickHandler() {
felix@1456: public void onClick(MenuItemClickEvent evt) {
felix@1456: disable();
felix@1456: createAreaArtifact(facetTheme, theme, false);
felix@1456: }
felix@1456: });
felix@1456: }
felix@1456: overMenu.addItem(createSeparator());
felix@1456: MenuItem againstAxis = new MenuItem(MSG.getString("x_axis"));
felix@1456: againstAxis.addClickHandler(new ClickHandler() {
felix@1456: public void onClick(MenuItemClickEvent evt) {
felix@1456: disable();
felix@1469: createAreaArtifact(null, facetTheme, false);
felix@1456: }
felix@1456: });
felix@1456: overMenu.addItem(againstAxis);
felix@1456:
felix@1517: // Create the "between..." submenu.
felix@1456: MenuItem betweenMenuItem = new MenuItem(MSG.chart_themepanel_area_between());
felix@1456: Menu betweenMenu = new Menu();
felix@1456: for (int i = 0; i < nThemes; i++) {
felix@1456: final Theme theme = themes.getThemeAt(i+1);
felix@2442: if (theme.getVisible() == 0) {
felix@2442: continue;
felix@2442: }
felix@1456: if (!areAreaCompatible(facetTheme, theme)) {
felix@1456: continue;
felix@1456: }
felix@1456: MenuItem againster = new MenuItem(theme.getDescription());
felix@1456: betweenMenu.addItem(againster);
felix@1456:
felix@1456: againster.addClickHandler(new ClickHandler() {
felix@1456: public void onClick(MenuItemClickEvent evt) {
felix@1456: disable();
felix@1456: createAreaArtifact(facetTheme, theme, true);
felix@1456: }
felix@1456: });
felix@1456: }
felix@1456: betweenMenu.addItem(createSeparator());
felix@1456: betweenMenu.addItem(againstAxis);
felix@1456:
felix@1456: overMenuItem.setSubmenu(overMenu);
felix@1456: underMenuItem.setSubmenu(underMenu);
felix@1456: betweenMenuItem.setSubmenu(betweenMenu);
felix@1456:
felix@1469: areaMenu.addItem(betweenMenuItem);
felix@1456: areaMenu.addItem(overMenuItem);
felix@1456: areaMenu.addItem(underMenuItem);
felix@1469: areaMenu.addItem(createSeparator());
felix@1469: MenuItem standAloneAgainstAxis = new MenuItem(MSG.getString("against_x_axis"));
felix@1469: standAloneAgainstAxis.addClickHandler(new ClickHandler() {
felix@1469: public void onClick(MenuItemClickEvent evt) {
felix@1469: disable();
felix@1469: createAreaArtifact(null, facetTheme, false);
felix@1469: }
felix@1469: });
felix@1469: areaMenu.addItem(standAloneAgainstAxis);
felix@1456:
felix@1456: areaMenuItem.setSubmenu(areaMenu);
felix@1456: menu.addItem(areaMenuItem);
felix@1456:
felix@1456: return menu;
felix@1456: }
ingo@523: }
ingo@523: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :