package org.activityinfo.ui.client.page.entry.location; /* * #%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.Style.HorizontalAlignment; import com.extjs.gxt.ui.client.Style.LayoutRegion; import com.extjs.gxt.ui.client.Style.Scroll; import com.extjs.gxt.ui.client.event.BaseEvent; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.widget.Html; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.Window; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.layout.BorderLayout; import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData; import com.extjs.gxt.ui.client.widget.layout.FlowLayout; import org.activityinfo.core.shared.workflow.Workflow; import org.activityinfo.i18n.shared.I18N; import org.activityinfo.legacy.client.Dispatcher; import org.activityinfo.legacy.shared.model.LocationDTO; import org.activityinfo.legacy.shared.model.LocationTypeDTO; import org.activityinfo.ui.client.page.entry.form.resources.SiteFormResources; import org.activityinfo.ui.client.style.legacy.icon.IconImageBundle; /** * Dialog that presents a choice to the user to select an existing location or * add a new location. */ public class LocationDialog extends Window { private Dispatcher dispatcher; private final LocationSearchPresenter searchPresenter; private final NewLocationPresenter newLocationPresenter; private final LocationTypeDTO locationType; private Html formHeader; private Html addLocationHeader; private Html addLocationHelp; private Button addLocationButton; private Button useLocationButton; public interface Callback { void onSelected(LocationDTO location, boolean isNew); } private Callback callback; public LocationDialog(Dispatcher dispatcher, LocationTypeDTO locationType) { this.dispatcher = dispatcher; this.searchPresenter = new LocationSearchPresenter(dispatcher, locationType); this.newLocationPresenter = new NewLocationPresenter(locationType.getCountryBounds()); this.locationType = locationType; setHeadingText(I18N.CONSTANTS.chooseLocation()); setWidth((int) (com.google.gwt.user.client.Window.getClientWidth() * 0.95)); setHeight((int) (com.google.gwt.user.client.Window.getClientHeight() * 0.95)); setLayout(new BorderLayout()); addSearchPanel(locationType); addMap(); getButtonBar().setAlignment(HorizontalAlignment.LEFT); getButtonBar().add(useLocationButton = new Button(I18N.CONSTANTS.useLocation(), IconImageBundle.ICONS.useLocation(), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { searchPresenter.accept(); } })); useLocationButton.disable(); getButtonBar().add(new Button(I18N.CONSTANTS.cancel(), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { hide(); } })); newLocationPresenter.addListener(NewLocationPresenter.ACTIVE_STATE_CHANGED, new Listener<BaseEvent>() { @Override public void handleEvent(BaseEvent be) { if (newLocationPresenter.isActive()) { formHeader.setHtml(I18N.CONSTANTS.addLocation()); } else { formHeader.setHtml(I18N.CONSTANTS.searchLocations()); } addLocationHeader.setVisible(!newLocationPresenter.isActive()); addLocationHelp.setVisible(!newLocationPresenter.isActive()); addLocationButton.setVisible(!newLocationPresenter.isActive()); layout(); } }); newLocationPresenter.addAcceptedListener(new Listener<LocationEvent>() { @Override public void handleEvent(LocationEvent event) { hide(); callback.onSelected(event.getLocation(), true); } }); searchPresenter.addListener(Events.Select, new Listener<BaseEvent>() { @Override public void handleEvent(BaseEvent be) { if (searchPresenter.getSelection() == null) { useLocationButton.disable(); } else { useLocationButton.enable(); useLocationButton.setText(I18N.MESSAGES.useLocation(searchPresenter.getSelection().getName())); } } }); searchPresenter.addAcceptListener(new Listener<BaseEvent>() { @Override public void handleEvent(BaseEvent be) { hide(); callback.onSelected(searchPresenter.getSelection(), false); } }); } private void addSearchPanel(LocationTypeDTO locationType) { LayoutContainer container = new LayoutContainer(); container.setLayout(new FlowLayout()); container.setScrollMode(Scroll.AUTOY); container.addStyleName(SiteFormResources.INSTANCE.style().locationDialogPane()); container.add(newHeader(I18N.CONSTANTS.chooseLocation())); container.add(newExplanation(I18N.CONSTANTS.chooseLocationDescription())); container.add(formHeader = newHeader(I18N.CONSTANTS.searchLocations())); container.add(new LocationForm(dispatcher, locationType, searchPresenter, newLocationPresenter)); container.add(newHeader(I18N.CONSTANTS.searchResults())); container.add(new SearchListView(searchPresenter)); container.add(new SearchStatusView(searchPresenter)); addLocationHeader = newHeader(I18N.CONSTANTS.addLocation()); addLocationHelp = newExplanation(I18N.CONSTANTS.addLocationDescription()); addLocationButton = new Button(I18N.CONSTANTS.newLocation(), IconImageBundle.ICONS.add(), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { newLocationPresenter.setActive(true, true); } }); addLocationButton.addStyleName(SiteFormResources.INSTANCE.style().addLocationButton()); if (isAddAllowed()) { container.add(addLocationHeader); container.add(addLocationHelp); container.add(addLocationButton); } BorderLayoutData layout = new BorderLayoutData(LayoutRegion.WEST); layout.setSize(350); add(container, layout); } private Html newHeader(String string) { Html html = new Html(string); html.addStyleName(SiteFormResources.INSTANCE.style().locationDialogHeader()); return html; } private Html newExplanation(String string) { Html html = new Html(string); html.addStyleName(SiteFormResources.INSTANCE.style().locationDialogHelp()); return html; } private void addMap() { LocationMap mapView = new LocationMap(searchPresenter, newLocationPresenter); add(mapView, new BorderLayoutData(LayoutRegion.CENTER)); } public void show(Callback callback) { this.callback = callback; show(); } /** * @return true if this LocationType's workflow allows adding new locations */ private boolean isAddAllowed() { return !Workflow.CLOSED_WORKFLOW_ID.equals(locationType.getWorkflowId()); } }