001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.project.ui.internal.properties;
018:
019: import java.util.ArrayList;
020: import java.util.Collection;
021: import java.util.HashMap;
022: import java.util.List;
023: import java.util.Map;
024:
025: import net.refractions.udig.project.ILayer;
026: import net.refractions.udig.project.IMap;
027: import net.refractions.udig.project.command.EditCommand;
028: import net.refractions.udig.project.command.factory.EditCommandFactory;
029: import net.refractions.udig.project.ui.ApplicationGIS;
030: import net.refractions.udig.project.ui.internal.Messages;
031:
032: import org.eclipse.core.runtime.IAdaptable;
033: import org.eclipse.jface.viewers.LabelProvider;
034: import org.eclipse.ui.views.properties.IPropertyDescriptor;
035: import org.eclipse.ui.views.properties.IPropertySource2;
036: import org.eclipse.ui.views.properties.PropertyDescriptor;
037: import org.geotools.feature.AttributeType;
038: import org.geotools.feature.Feature;
039: import org.geotools.feature.FeatureType;
040: import org.geotools.feature.GeometryAttributeType;
041: import org.opengis.util.CodeList;
042:
043: import com.vividsolutions.jts.geom.Envelope;
044: import com.vividsolutions.jts.geom.Geometry;
045:
046: /**
047: * An adapter that allows features to act as a property source for a property sheet. The sheet
048: * allows the victim's attributes to be editted and viewed.
049: *
050: * @author jeichar
051: * @since 0.3
052: */
053: public class FeaturePropertySource implements IPropertySource2 {
054: private static final String ID = "ID"; //$NON-NLS-1$
055: private static final String DEFAULT_GEOM = "DEFAULT_GEOM"; //$NON-NLS-1$
056: private static final String BOUNDING_BOX = "BOUNDING_BOX"; //$NON-NLS-1$
057: private static final String FEATURE = "FEATURE"; //$NON-NLS-1$
058: private Feature feature = null;
059: private Feature old = null;
060: private Map<Geometry, Object> geomProperties = new HashMap<Geometry, Object>();
061: private Map<AttributeType, Object> attrProperties = new HashMap<AttributeType, Object>();
062: private AttributeType[] attrs;
063: private IPropertyDescriptor[] descriptors;
064: private boolean attribute;
065:
066: /** Are the attributes editable in cell editors. */
067: private boolean editable = true;
068: private IMap map;
069:
070: /**
071: * Creates a new instance of FeaturePropertySource
072: *
073: * @param feature The feature that this property source refers to.
074: */
075: public FeaturePropertySource(Feature feature) {
076: this (feature, false);
077: }
078:
079: /**
080: * Creates a new instance of FeaturePropertySource
081: *
082: * @param feature2
083: * @param attribute
084: */
085: public FeaturePropertySource(Feature feature2, boolean attribute) {
086: boolean editable = false;
087: if (feature2 instanceof IAdaptable) {
088: IAdaptable adaptable = (IAdaptable) feature2;
089: if (adaptable.getAdapter(ILayer.class) != null
090: || adaptable.getAdapter(IMap.class) != null) {
091: editable = true;
092: }
093: }
094: init(feature2, attribute, editable);
095:
096: }
097:
098: public FeaturePropertySource(Feature feature2, boolean attribute,
099: boolean editable) {
100: init(feature2, attribute, editable);
101: }
102:
103: private void init(Feature feature2, boolean attribute,
104: boolean editable) {
105: this .feature = feature2;
106: try {
107: if (feature2 != null)
108: old = feature.getFeatureType().duplicate(feature);
109: } catch (Exception e) {
110: e.printStackTrace();
111: }
112: this .attribute = attribute;
113: this .editable = editable;
114: if (editable) {
115: IAdaptable adaptable = (IAdaptable) feature2;
116: if (adaptable.getAdapter(ILayer.class) != null) {
117: ILayer layer = (ILayer) adaptable
118: .getAdapter(ILayer.class);
119: map = layer.getMap();
120: } else if (adaptable.getAdapter(IMap.class) != null) {
121: map = (IMap) adaptable.getAdapter(IMap.class);
122: } else {
123: map = ApplicationGIS.getActiveMap();
124: }
125:
126: }
127: }
128:
129: /**
130: * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
131: */
132: public Object getEditableValue() {
133: return ""; //$NON-NLS-1$
134: }
135:
136: /**
137: * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
138: */
139: public IPropertyDescriptor[] getPropertyDescriptors() {
140: if (descriptors == null) {
141: boolean hasAttrs = false;
142: List<IPropertyDescriptor> descrps = new ArrayList<IPropertyDescriptor>();
143: PropertyDescriptor d = new PropertyDescriptor(ID, "ID"); //$NON-NLS-1$
144: d.setCategory(Messages.FeaturePropertySource_feature);
145: descrps.add(d);
146: d = new GeometryPropertyDescriptor(DEFAULT_GEOM,
147: Messages.FeaturePropertySource_defaultGeometry);
148: d.setCategory(Messages.FeaturePropertySource_geometries);
149: descrps.add(d);
150: d = new PropertyDescriptor(BOUNDING_BOX,
151: Messages.FeaturePropertySource_bounds);
152: d.setCategory(Messages.FeaturePropertySource_feature);
153: d.setLabelProvider(new LabelProvider() {
154: /**
155: * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
156: */
157: public String getText(Object element) {
158: Envelope bbox = (Envelope) element;
159: String minx = String.valueOf(bbox.getMinX());
160: minx = minx.substring(0, Math
161: .min(10, minx.length()));
162: String maxx = String.valueOf(bbox.getMaxX());
163: maxx = maxx.substring(0, Math
164: .min(10, maxx.length()));
165: String miny = String.valueOf(bbox.getMinY());
166: miny = miny.substring(0, Math
167: .min(10, miny.length()));
168: String maxy = String.valueOf(bbox.getMaxY());
169: maxy = maxy.substring(0, Math
170: .min(10, maxy.length()));
171: return "(" + minx + "," + miny + "), (" + maxx + "," + maxy + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
172: }
173: });
174: descrps.add(d);
175: if (!attribute) {
176: FeatureType ft = feature.getFeatureType();
177: attrs = ft.getAttributeTypes();
178: for (int i = 0; i < attrs.length; i++) {
179: AttributeType at = attrs[i];
180: String name = at.getName().toLowerCase();
181: name = name.substring(0, 1).toUpperCase()
182: + name.substring(1);
183: if (at instanceof GeometryAttributeType) {
184: if (feature.getAttribute(i) != feature
185: .getDefaultGeometry()) {
186: d = new GeometryPropertyDescriptor(
187: Integer.valueOf(i),
188: name
189: + Messages.FeaturePropertySource_geometry);
190: d
191: .setCategory(Messages.FeaturePropertySource_geometries);
192: descrps.add(d);
193: }
194: } else {
195: if (Feature.class
196: .isAssignableFrom(at.getType())) {
197: d = new PropertyDescriptor(FEATURE
198: + Integer.valueOf(i), name);
199: } else if (Collection.class.isAssignableFrom(at
200: .getType()))
201: d = new PropertyDescriptor(Integer
202: .valueOf(i), name);
203: else {
204: d = new AttributePropertyDescriptor(Integer
205: .valueOf(i), name, at, ft, editable);
206: // if (String.class.isAssignableFrom(at.getType()))
207: // d = new TextPropertyDescriptor(Integer.valueOf(i), name);
208: // if (Integer.class.isAssignableFrom(at.getType()))
209: // d = new TextPropertyDescriptor(Integer.valueOf(i), name);
210: // if (Double.class.isAssignableFrom(at.getType()))
211: // d = new TextPropertyDescriptor(Integer.valueOf(i), name);
212: // if (Boolean.class.isAssignableFrom(at.getType()))
213: // d = new ComboBoxPropertyDescriptor(Integer.valueOf(i), name,
214: // new String[]{"true","false"});
215: // if (Float.class.isAssignableFrom(at.getType()))
216: // d = new TextPropertyDescriptor(Integer.valueOf(i), name);
217: }
218: // d.setValidator(new AttributeValidator(at));
219:
220: if (name.equalsIgnoreCase("name")) { //$NON-NLS-1$
221: d
222: .setCategory(Messages.FeaturePropertySource_feature);
223: descrps.add(0, d);
224: } else {
225: hasAttrs = true;
226: d
227: .setCategory(Messages.FeaturePropertySource_featureAttributes);
228: descrps.add(d);
229: }
230: }
231: }
232: }
233: if (!hasAttrs) {
234: d = new PropertyDescriptor(
235: "", Messages.FeaturePropertySource_noOtherAttributes); //$NON-NLS-1$
236: d
237: .setCategory(Messages.FeaturePropertySource_featureAttributes);
238: descrps.add(d);
239: }
240: descriptors = new IPropertyDescriptor[descrps.size()];
241: descrps.toArray(descriptors);
242: }
243:
244: IPropertyDescriptor[] c = new IPropertyDescriptor[descriptors.length];
245: System.arraycopy(descriptors, 0, c, 0, c.length);
246: return c;
247: }
248:
249: /**
250: * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
251: */
252: public Object getPropertyValue(Object id) {
253: if (id instanceof String) {
254: String sid = (String) id;
255: if (sid.equals(ID))
256: return feature.getID();
257: if (sid.equals(DEFAULT_GEOM))
258: return getGeomProperty(feature.getDefaultGeometry());
259: if (sid.equals(BOUNDING_BOX))
260: return feature.getBounds();
261: if (sid.startsWith(FEATURE)) {
262: int i = Integer.parseInt(sid
263: .substring(FEATURE.length()));
264: return new FeaturePropertySource((Feature) feature
265: .getAttribute(i), true);
266: }
267: }
268: if (id instanceof Integer) {
269: Integer i = (Integer) id;
270: AttributeType attrType = attrs[i.intValue()];
271: if (attrType instanceof GeometryAttributeType)
272: return getGeomProperty((Geometry) feature
273: .getAttribute(i.intValue()));
274: if (Collection.class.isAssignableFrom(attrType.getType()))
275: return getAttrProperty(attrType, feature.getAttribute(i
276: .intValue()));
277: // return feature.getAttribute(i.intValue()).toString();
278: Object attr = feature.getAttribute(i.intValue());
279:
280: if (!(attr instanceof Boolean)
281: && !(attr instanceof CodeList)) {
282: if (attr != null)
283: return attr.toString();
284: return ""; //$NON-NLS-1$
285: }
286:
287: if (attr instanceof Boolean) {
288: if (((Boolean) attr).booleanValue())
289: return Integer.valueOf(1);
290: return Integer.valueOf(0);
291: }
292: if (attr instanceof CodeList) {
293: CodeList list = (CodeList) attr;
294: return Integer.valueOf(list.ordinal()).toString();
295: }
296: }
297: return null;
298: }
299:
300: /**
301: * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object)
302: */
303: public boolean isPropertySet(Object id) {
304: if (id.equals(ID))
305: return feature.getID() == old.getID();
306: if (id.equals(DEFAULT_GEOM))
307: return feature.getDefaultGeometry() == old
308: .getDefaultGeometry();
309: if (id.equals(BOUNDING_BOX))
310: return feature.getBounds() == old.getBounds();
311: if (id instanceof Integer) {
312: int i = ((Integer) id).intValue();
313: Object attr = feature.getAttribute(i);
314: if (attr instanceof String || attr instanceof Integer
315: || attr instanceof Double || attr instanceof Float
316: || attr instanceof Boolean)
317: return attr.equals(old.getAttribute(i));
318: }
319: return false;
320: }
321:
322: /**
323: * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
324: */
325: public void resetPropertyValue(Object id) {
326: try {
327: if (id instanceof Integer) {
328: int i = ((Integer) id).intValue();
329: Object attr = feature.getAttribute(i);
330: if (attr instanceof String || attr instanceof Integer
331: || attr instanceof Double
332: || attr instanceof Float
333: || attr instanceof Boolean)
334: feature.setAttribute(i, old.getAttribute(i));
335: }
336: } catch (Exception e) {
337: e.printStackTrace();
338: }
339: }
340:
341: public void setPropertyValue(Object id, Object value) {
342: try {
343: if (id instanceof Integer) {
344: int i = ((Integer) id).intValue();
345: Object attr = feature.getAttribute(i);
346: EditCommand command = (EditCommand) EditCommandFactory
347: .getInstance().createSetAttributeCommand(
348: attrs[i].getName(), value);
349: map.sendCommandASync(command);
350: if (attr instanceof String) {
351: feature.setAttribute(i, value);
352: } else if (attr instanceof Integer) {
353: feature.setAttribute(i, Integer
354: .valueOf((String) value));
355: } else if (attr instanceof Double) {
356: feature.setAttribute(i, Double
357: .valueOf((String) value));
358: } else if (attr instanceof Float) {
359: feature.setAttribute(i, Float
360: .valueOf((String) value));
361: } else if (attr instanceof Boolean) {
362: feature.setAttribute(i,
363: Boolean.valueOf(((Integer) value)
364: .intValue() == 0 ? true : false));
365: }
366: }
367: if (value instanceof Geometry) {
368: if (id.equals(DEFAULT_GEOM)) {
369: feature.setDefaultGeometry((Geometry) value);
370:
371: EditCommand command = (EditCommand) EditCommandFactory
372: .getInstance().createSetGeometryCommand(
373: (Geometry) value);
374: map.sendCommandASync(command);
375: }
376: }
377: } catch (Exception e) {
378: e.printStackTrace();
379: }
380: }
381:
382: private Object getGeomProperty(Geometry id) {
383: Object geom = geomProperties.get(id);
384: if (geom == null) {
385: geom = new GeomPropertySource(id);
386: geomProperties.put(id, geom);
387: }
388: return geom;
389: }
390:
391: private Object getAttrProperty(AttributeType id, Object value) {
392: Object attr = geomProperties.get(id);
393: if (attr == null) {
394: attr = new AttributePropertySource(id, value);
395: attrProperties.put(id, attr);
396: }
397: return attr;
398:
399: }
400:
401: /**
402: * @see org.eclipse.ui.views.properties.IPropertySource2#isPropertyResettable(java.lang.Object)
403: */
404: public boolean isPropertyResettable(Object id) {
405: return true;
406: }
407: }
|