package org.activityinfo.ui.client.component.report.editor.chart; /* * #%L * ActivityInfo Server * %% * Copyright (C) 2009 - 2013 UNICEF * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.extjs.gxt.ui.client.data.BaseListLoader; import com.extjs.gxt.ui.client.data.ListLoadResult; import com.extjs.gxt.ui.client.data.ListLoader; import com.extjs.gxt.ui.client.event.SelectionChangedEvent; import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.store.StoreEvent; import com.extjs.gxt.ui.client.store.StoreListener; import com.extjs.gxt.ui.client.widget.form.ComboBox; import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem; import org.activityinfo.i18n.shared.I18N; import org.activityinfo.legacy.client.Dispatcher; import org.activityinfo.legacy.shared.reports.model.Dimension; import org.activityinfo.legacy.shared.reports.model.PivotChartReportElement; import org.activityinfo.legacy.shared.reports.model.PivotChartReportElement.Type; import org.activityinfo.ui.client.EventBus; import org.activityinfo.ui.client.component.report.editor.pivotTable.DimensionModel; import org.activityinfo.ui.client.page.report.HasReportElement; import org.activityinfo.ui.client.page.report.ReportChangeHandler; import org.activityinfo.ui.client.page.report.ReportEventBus; import java.util.List; public class DimensionComboBoxSet implements HasReportElement<PivotChartReportElement> { private final ReportEventBus reportEventBus; private final DimensionProxy proxy; private final ListStore<DimensionModel> store; private final ListLoader<ListLoadResult<DimensionModel>> loader; private final LabelToolItemWithText categoryLabel; private final LabelToolItemWithText seriesLabel; private final DimensionCombo categoryCombo; private final DimensionCombo seriesCombo; private PivotChartReportElement model; private boolean fireEvents = true; public DimensionComboBoxSet(EventBus eventBus, Dispatcher dispatcher) { this.proxy = new DimensionProxy(dispatcher); this.loader = new BaseListLoader<ListLoadResult<DimensionModel>>(proxy); this.store = new ListStore<DimensionModel>(loader); this.categoryCombo = new DimensionCombo(store, new SelectionChangedListener<DimensionModel>() { @Override public void selectionChanged(SelectionChangedEvent<DimensionModel> se) { model.setCategoryDimension(se.getSelectedItem().getDimension()); if (fireEvents) { DimensionComboBoxSet.this.reportEventBus.fireChange(); DimensionComboBoxSet.this.categoryCombo.setValue(se.getSelectedItem().getDimension()); } } }); this.seriesCombo = new DimensionCombo(store, new SelectionChangedListener<DimensionModel>() { @Override public void selectionChanged(SelectionChangedEvent<DimensionModel> se) { model.setSeriesDimension(se.getSelectedItem().getDimension()); if (fireEvents) { DimensionComboBoxSet.this.reportEventBus.fireChange(); DimensionComboBoxSet.this.seriesCombo.setValue(se.getSelectedItem().getDimension()); } } }); this.categoryLabel = new LabelToolItemWithText(); this.seriesLabel = new LabelToolItemWithText(); this.reportEventBus = new ReportEventBus(eventBus, this); this.reportEventBus.listen(new ReportChangeHandler() { @Override public void onChanged() { updateSelectionWithoutEvents(); } }); } @Override public void bind(PivotChartReportElement model) { this.model = model; this.proxy.setModel(model); updateSelectionWithoutEvents(); } @Override public PivotChartReportElement getModel() { return this.model; } @Override public void disconnect() { reportEventBus.disconnect(); } private void updateSelectionWithoutEvents() { fireEvents = false; updateSelection(); fireEvents = true; } private void updateSelection() { loader.load(); seriesCombo.setValue(firstOrNull(model.getSeriesDimensions())); categoryCombo.setValue(firstOrNull(model.getCategoryDimensions())); updateLabels(); } private void updateLabels() { Type type = model.getType(); if (type == Type.ClusteredBar || type == Type.Bar) { categoryLabel.setText(I18N.CONSTANTS.horizontalAxis()); seriesLabel.setText(I18N.CONSTANTS.bars()); } else if (type == Type.Line) { categoryLabel.setText(I18N.CONSTANTS.horizontalAxis()); seriesLabel.setText(I18N.CONSTANTS.lines()); } else if (type == Type.Pie) { categoryLabel.setText(I18N.CONSTANTS.slices()); } seriesCombo.setEnabled(type != Type.Pie); seriesCombo.setEnabled(type != Type.Pie); } private Dimension firstOrNull(List<Dimension> dimensions) { if (dimensions.isEmpty()) { return null; } else { return dimensions.get(0); } } public LabelToolItem getCategoryLabel() { return categoryLabel; } public LabelToolItem getSeriesLabel() { return seriesLabel; } public DimensionCombo getCategoryCombo() { return categoryCombo; } public DimensionCombo getSeriesCombo() { return seriesCombo; } private static class DimensionCombo extends ComboBox<DimensionModel> { private Dimension dimension; public DimensionCombo(ListStore<DimensionModel> store, SelectionChangedListener<DimensionModel> changeListener) { this.store = store; setDisplayField("name"); setEditable(false); setForceSelection(true); setTriggerAction(TriggerAction.ALL); addSelectionChangedListener(changeListener); store.addStoreListener(new StoreListener<DimensionModel>() { @Override public void storeDataChanged(StoreEvent<DimensionModel> se) { tryUpdateSelection(); } }); } public void setValue(Dimension dimension) { this.dimension = dimension; tryUpdateSelection(); } public void tryUpdateSelection() { // / try to update the combo box selection based on the current // value // / we may need to wait until we receive the list of dimensions // from the server // / because the model carries only the id, not the descriptive // label for (DimensionModel model : getStore().getModels()) { if (model.getDimension().equals(dimension)) { setValue(model); return; } } setValue((DimensionModel) null); } } }