/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.widget.featureinfo.client.widget.factory; import org.geomajas.configuration.client.ClientWidgetInfo; import org.geomajas.gwt.client.i18n.I18nProvider; import org.geomajas.gwt.client.map.MapView.ZoomOption; import org.geomajas.gwt.client.map.feature.Feature; import org.geomajas.gwt.client.map.layer.Layer; import org.geomajas.gwt.client.map.layer.RasterLayer; import org.geomajas.gwt.client.map.layer.VectorLayer; import org.geomajas.gwt.client.spatial.Bbox; import org.geomajas.gwt.client.util.Log; import org.geomajas.gwt.client.util.WidgetLayout; import org.geomajas.gwt.client.widget.FeatureAttributeWindow; import org.geomajas.widget.featureinfo.client.widget.DockableWindow; import org.geomajas.widget.featureinfo.configuration.client.WidgetBuilderInfo; import com.google.gwt.core.client.GWT; import com.smartgwt.client.widgets.Canvas; import com.smartgwt.client.widgets.IButton; import com.smartgwt.client.widgets.Window; import com.smartgwt.client.widgets.events.ClickEvent; import com.smartgwt.client.widgets.events.ClickHandler; import com.smartgwt.client.widgets.toolbar.ToolStrip; /** * With FeatureDetailWidgetFactory you can get FeatureDetail widgets in a general manner. * The effective type used depends on configuration. * * @author Kristof Heirwegh * @author Oliver May */ public final class FeatureDetailWidgetFactory { private static boolean selectOnZoom = true; private static FeatureDetailWidgetBuilder defaultVectorFeatureDetailWidgetBuilder; private static FeatureDetailWidgetBuilder defaultRasterFeatureDetailWidgetBuilder; private FeatureDetailWidgetFactory() { // utility class, hide constructor } public static Window createFeatureDetailWindow(Feature feature, Layer<?> layer, boolean editingAllowed) { FeatureDetailWidgetBuilder customBuilder = getCustomBuilder(layer); if (customBuilder != null) { Window w = customBuilder.createFeatureDetailWindow(feature, editingAllowed); if (!(w instanceof DockableWindow)) { DockableWindow.mixin(w); } return w; } else { return createDefaultFeatureDetailWindow(feature, layer, editingAllowed); } } public static Window createFeatureDetailWindow(Feature feature, boolean editingAllowed) { return createFeatureDetailWindow(feature, feature.getLayer(), editingAllowed); } /** * Overrule configuration and create Geomajas default FeatureAttributeWindow. * * @param feature * @param editingAllowed * @return */ public static Window createDefaultFeatureDetailWindow(Feature feature, Layer<?> layer, boolean editingAllowed) { if (layer instanceof VectorLayer) { FeatureAttributeWindow w = new FeatureAttributeWindow(feature, editingAllowed); customize(w, feature); return w; } else { return new RasterLayerAttributeWindow(feature); } } public static boolean isSelectOnZoom() { return selectOnZoom; } /** * Should the feature be selected when zooming to it?. * * @param selectOnZoom include select on zoom? */ public static void setSelectOnZoom(boolean selectOnZoom) { FeatureDetailWidgetFactory.selectOnZoom = selectOnZoom; } /** * The default VectorFeatureDetailWidgetBuilder. * * @return the default FeatureDetailWidgetBuilder, can be <code>null</code>. */ public static FeatureDetailWidgetBuilder getDefaultVectorFeatureDetailWidgetBuilder() { return defaultVectorFeatureDetailWidgetBuilder; } /** * Set the (custom) default FeatureDetailWidgetBuilder to be used if there is no builder configured in the layer. * * @param defaultFeatureDetailWidgetBuilder can be <code>null</code>, in which case the Geomajas default will be * used. */ public static void setDefaultVectorFeatureDetailWidgetBuilder(FeatureDetailWidgetBuilder defaultFeatureDetailWidgetBuilder) { FeatureDetailWidgetFactory.defaultVectorFeatureDetailWidgetBuilder = defaultFeatureDetailWidgetBuilder; } /** * The default RasterFeatureDetailWidgetBuilder. * * @return the default FeatureDetailWidgetBuilder, can be <code>null</code>. */ public static FeatureDetailWidgetBuilder getDefaultRasterFeatureDetailWidgetBuilder() { return defaultRasterFeatureDetailWidgetBuilder; } /** * Set the (custom) default FeatureDetailWidgetBuilder to be used if there is no builder configured in the layer. * * @param defaultFeatureDetailWidgetBuilder can be <code>null</code>, in which case the Geomajas default will be * used. */ public static void setDefaultRasterFeatureDetailWidgetBuilder( FeatureDetailWidgetBuilder defaultRasterFeatureDetailWidgetBuilder) { FeatureDetailWidgetFactory.defaultRasterFeatureDetailWidgetBuilder = defaultRasterFeatureDetailWidgetBuilder; } // ---------------------------------------------------------- private static FeatureDetailWidgetBuilder getCustomBuilder(Layer<?> layer) { FeatureDetailWidgetBuilder b = null; try { if (layer != null) { ClientWidgetInfo cwi = layer.getLayerInfo().getWidgetInfo(WidgetBuilderInfo.IDENTIFIER); if (cwi != null) { if (cwi instanceof WidgetBuilderInfo) { WidgetBuilderInfo lcfdii = (WidgetBuilderInfo) cwi; WidgetBuilder wb = WidgetFactory.get(lcfdii); if (wb instanceof FeatureDetailWidgetBuilder) { return (FeatureDetailWidgetBuilder) wb; } else { GWT.log("Builder is not of type FeatureDetailWidgetBuilder: " + lcfdii.getBuilderName()); } } else { GWT.log("ClientWidgetInfo is not of class type LayerCustomFeatureDetailInfoInfo!! (layer type: " + layer.getServerLayerId() + ")"); } } } } catch (Exception e) { // NOSONAR Log.logError("Error getting custom detail widget: " + e.getMessage()); } if (b == null) { if (layer instanceof VectorLayer && defaultVectorFeatureDetailWidgetBuilder != null) { b = defaultVectorFeatureDetailWidgetBuilder; } else if (layer instanceof RasterLayer && defaultRasterFeatureDetailWidgetBuilder != null) { b = defaultRasterFeatureDetailWidgetBuilder; } } return b; } // ---------------------------------------------------------- private static void customize(FeatureAttributeWindow window, Feature feature) { DockableWindow.mixin(window); if (isSelectOnZoom()) { ToolStrip ts = window.getToolStrip(); Canvas editBtn = null; // hackety hack for (Canvas c : ts.getMembers()) { if (c instanceof IButton && WidgetLayout.iconEdit.equals(((IButton) c).getIcon())) { editBtn = c; } } ts.removeMembers(ts.getMembers()); // clear ts.addMember(new SelectingZoomButton(feature)); if (editBtn != null) { ts.addSpacer(2); ts.addMember(editBtn); } } } /** Definition of the zoom button that zooms to the feature on the map. */ private static class SelectingZoomButton extends IButton implements ClickHandler { private Feature feature; public SelectingZoomButton(Feature feature) { super(); setIcon(WidgetLayout.iconZoomSelection); setShowDisabledIcon(false); setTitle(I18nProvider.getAttribute().btnZoomFeature()); setTooltip(I18nProvider.getAttribute().btnZoomTooltip()); addClickHandler(this); setWidth(150); this.feature = feature; } public void onClick(ClickEvent event) { Bbox bounds = feature.getGeometry().getBounds(); feature.getLayer().getMapModel().getMapView().applyBounds(bounds, ZoomOption.LEVEL_FIT); feature.getLayer().getFeatureStore().addFeature(feature); feature.getLayer().selectFeature(feature); } } }