001: /*
002: * Created on Nov 24, 2004 TODO To change the template for this generated file go to Window -
003: * Preferences - Java - Code Style - Code Templates
004: */
005: package net.refractions.udig.project.ui.internal;
006:
007: import java.io.IOException;
008: import java.util.ArrayList;
009: import java.util.Collection;
010: import java.util.HashMap;
011: import java.util.List;
012:
013: import net.refractions.udig.project.ILayer;
014: import net.refractions.udig.project.internal.ContextModel;
015: import net.refractions.udig.project.internal.ContextModelListenerAdapter;
016: import net.refractions.udig.project.internal.Layer;
017: import net.refractions.udig.project.internal.Map;
018: import net.refractions.udig.project.internal.ProjectPackage;
019: import net.refractions.udig.project.internal.ProjectPlugin;
020: import net.refractions.udig.project.internal.render.CompositeRenderContext;
021: import net.refractions.udig.project.internal.render.MultiLayerRenderer;
022: import net.refractions.udig.project.internal.render.RenderContext;
023: import net.refractions.udig.project.internal.render.RenderListenerAdapter;
024: import net.refractions.udig.project.internal.render.RenderManager;
025: import net.refractions.udig.project.internal.render.RenderPackage;
026: import net.refractions.udig.project.internal.render.RendererCreator;
027: import net.refractions.udig.project.internal.render.SelectionLayer;
028: import net.refractions.udig.project.internal.render.ViewportModel;
029: import net.refractions.udig.project.internal.render.impl.RenderManagerImpl;
030: import net.refractions.udig.project.render.RenderException;
031: import net.refractions.udig.project.ui.render.displayAdapter.ViewportPane;
032:
033: import org.eclipse.emf.common.notify.Adapter;
034: import org.eclipse.emf.common.notify.Notification;
035: import org.eclipse.emf.common.notify.impl.AdapterImpl;
036: import org.geotools.data.FeatureEvent;
037: import org.geotools.filter.Filter;
038: import org.geotools.geometry.jts.JTS;
039: import org.opengis.referencing.operation.MathTransform;
040: import org.opengis.referencing.operation.TransformException;
041:
042: import com.vividsolutions.jts.geom.Envelope;
043:
044: /**
045: * Provides factory methods for various Listeners used by RenderManagerDynamic.
046: */
047: public class RenderManagerAdapters {
048:
049: static Adapter createViewportListener(
050: final RenderManagerImpl manager) {
051: return new AdapterImpl() {
052: /**
053: * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
054: */
055: public void notifyChanged(Notification msg) {
056: manager.checkState();
057: switch (msg.getFeatureID(ViewportModel.class)) {
058: case RenderPackage.VIEWPORT_MODEL__BOUNDS: {
059: if (ApplicationGISInternal.getActiveEditor()
060: .isVisible())
061: refreshDirtyArea(msg);
062: break;
063: }
064: case RenderPackage.VIEWPORT_MODEL__CRS: {
065: manager.refresh(null);
066: break;
067: }
068: }// switch
069: }
070:
071: private void refreshDirtyArea(Notification msg) {
072: manager.refresh(null);
073: }
074: };
075: }
076:
077: static ContextModelListenerAdapter createContextModelListener(
078: final RenderManagerDynamic manager) {
079: return new ContextModelListenerAdapter() {
080: /**
081: * @see net.refractions.udig.project.ContextModelListenerAdapter#commandExecuted(org.eclipse.emf.common.notify.Notification)
082: */
083: public void notifyChanged(Notification msg) {
084: super .notifyChanged(msg);
085: }
086:
087: /**
088: * @see net.refractions.udig.project.ContextModelListenerAdapter#zorderChanged(org.eclipse.emf.common.notify.Notification)
089: */
090: protected void zorderChanged(Notification msg) {
091: synchronizeAndRefresh(msg, manager);
092:
093: updateImage();
094: }
095:
096: /**
097: * @see net.refractions.udig.project.ContextModelListenerAdapter#layerAdded(org.eclipse.emf.common.notify.Notification)
098: */
099: protected void layerAdded(Notification msg) {
100: synchronizeAndRefresh(msg, manager);
101: updateImage();
102: }
103:
104: /**
105: * @see net.refractions.udig.project.ContextModelListenerAdapter#layerRemoved(org.eclipse.emf.common.notify.Notification)
106: */
107: protected void layerRemoved(Notification msg) {
108: synchronizeAndRefresh(msg, manager);
109: manager.validateRendererConfiguration();
110: updateImage();
111: }
112:
113: /**
114: * @see net.refractions.udig.project.ContextModelListenerAdapter#manyLayersAdded(org.eclipse.emf.common.notify.Notification)
115: */
116: protected void manyLayersAdded(Notification msg) {
117: synchronizeAndRefresh(msg, manager);
118: updateImage();
119: }
120:
121: /**
122: * @see net.refractions.udig.project.ContextModelListenerAdapter#manyLayersRemoved(org.eclipse.emf.common.notify.Notification)
123: */
124: protected void manyLayersRemoved(Notification msg) {
125: synchronizeAndRefresh(msg, manager);
126: manager.validateRendererConfiguration();
127: updateImage();
128: }
129:
130: public void updateImage() {
131: try {
132: ((MultiLayerRenderer) manager.getRenderExecutor()
133: .getRenderer()).refreshImage();
134: } catch (RenderException e) {
135: // won't happen.
136: e.printStackTrace();
137: }
138: ((ViewportPane) manager.getMapDisplay()).renderDone();
139: }
140:
141: };
142:
143: }
144:
145: private static void synchronizeAndRefresh(Notification msg,
146: RenderManagerDynamic manager) {
147: List<Layer> toRender = synchronizeRenderers(msg,
148: manager.configuration, manager.getRendererCreator());
149: for (Layer layer : toRender) {
150: layer.refresh(null);
151: }
152: }
153:
154: public static List<Layer> synchronizeRenderers(
155: final Notification msg,
156: final Collection<RenderContext> configuration,
157: final RendererCreator rendererCreator) {
158:
159: HashMap<RenderContext, RenderContext> oldToCopy = new HashMap<RenderContext, RenderContext>();
160: Collection<RenderContext> configuration2 = configuration;
161: if (configuration2 != null)
162: for (RenderContext context : configuration2) {
163: oldToCopy.put(context, context.copy());
164: }
165:
166: rendererCreator.changed(msg);
167:
168: configuration2 = rendererCreator.getConfiguration();
169: List<Layer> toRender = new ArrayList<Layer>();
170: for (RenderContext newcontext : configuration2) {
171: if (!oldToCopy.containsKey(newcontext)
172: && !(newcontext.getLayer() instanceof SelectionLayer)) {
173: toRender.add(newcontext.getLayerInternal());
174: } else {
175: if (newcontext instanceof CompositeRenderContext) {
176: List<Layer> oldLayers = new ArrayList<Layer>(
177: ((CompositeRenderContext) oldToCopy
178: .get(newcontext))
179: .getLayersInternal());
180: for (Layer layer : ((CompositeRenderContext) newcontext)
181: .getLayersInternal()) {
182: if (!oldLayers.contains(layer)) {
183: toRender.add(newcontext.getLayerInternal());
184: break;
185: }
186: oldLayers.remove(layer);
187: // XXX
188: }
189: if (!oldLayers.isEmpty())
190: toRender.add(newcontext.getLayerInternal());
191: }
192: oldToCopy.remove(newcontext);
193: }
194: }
195: return toRender;
196: }
197:
198: /**
199: * <!-- begin-user-doc --> <!-- end-user-doc -->
200: *
201: * @generated NOT
202: */
203: static Adapter createViewportModelChangeListener(
204: final RenderManagerImpl manager,
205: final Adapter viewportListener,
206: final ContextModelListenerAdapter contextModelListener) {
207: return new AdapterImpl() {
208: /**
209: * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
210: */
211: @SuppressWarnings("unchecked")
212: public void notifyChanged(Notification msg) {
213: manager.checkState();
214:
215: switch (msg.getFeatureID(RenderManager.class)) {
216: case RenderPackage.RENDER_MANAGER__VIEWPORT_MODEL_INTERNAL: {
217: if (msg.getOldValue() != null)
218: ((ViewportModel) msg.getOldValue()).eAdapters()
219: .remove(viewportListener);
220: if (msg.getNewValue() != null)
221: ((ViewportModel) msg.getNewValue()).eAdapters()
222: .add(viewportListener);
223: break;
224: }// case
225: case RenderPackage.RENDER_MANAGER__MAP_INTERNAL: {
226: if (msg.getOldValue() != null)
227: ((Map) msg.getOldValue()).getContextModel()
228: .eAdapters().remove(
229: contextModelListener);
230: if (msg.getNewValue() != null)
231: ((Map) msg.getNewValue()).getContextModel()
232: .eAdapters().add(contextModelListener);
233: break;
234: }// case
235:
236: }
237: }
238: };
239: }
240:
241: static Adapter createLayerListener(
242: final RenderManagerDynamic manager) {
243: return new AdapterImpl() {
244: /**
245: * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
246: */
247: public void notifyChanged(Notification event) {
248: manager.checkState();
249:
250: if (event.getNotifier() instanceof Map) {
251: if (ProjectPackage.MAP__CONTEXT_MODEL == event
252: .getFeatureID(Map.class)) {
253: if (event.getOldValue() != null) {
254: ((ContextModel) event.getOldValue())
255: .removeDeepAdapter(this );
256: }
257: if (event.getNewValue() != null) {
258: ((ContextModel) event.getNewValue())
259: .addDeepAdapter(this );
260: }
261: }
262: } else if (event.getNotifier() instanceof Layer) {
263: switch (event.getFeatureID(Layer.class)) {
264: case ProjectPackage.LAYER__FILTER:
265: filterChanged(manager, event);
266: break;
267: case ProjectPackage.LAYER__STYLE_BLACKBOARD:
268: synchronizeRenderers(event,
269: manager.configuration, manager
270: .getRendererCreator());
271: break;
272: case ProjectPackage.LAYER__CRS:
273: if (event.getOldValue() == null
274: || !event.getOldValue().equals(
275: event.getNewValue())) {
276: ((Layer) event.getNotifier()).refresh(null);
277: }
278: break;
279: case ProjectPackage.LAYER__FEATURE_CHANGES:
280: FeatureEvent featureEvent = (FeatureEvent) event
281: .getNewValue();
282: if (featureEvent == null) {
283: break;
284: }
285: featureEvent(manager, event, featureEvent);
286: break;
287:
288: default:
289: break;
290: }
291:
292: }
293: }
294:
295: private void featureEvent(
296: final RenderManagerDynamic manager,
297: Notification event, FeatureEvent featureEvent) {
298: Envelope bounds = featureEvent.getBounds();
299: if (bounds != null) {
300: ILayer notifier = (ILayer) event.getNotifier();
301: if (bounds.isNull()) {
302: // change to null because renderer treat null as the entire viewport but don't make
303: // the same assumption for NULL envelope.
304: manager.refresh(notifier, null);
305: } else {
306: try {
307: MathTransform layerToMapTransform = notifier
308: .layerToMapTransform();
309: if (!layerToMapTransform.isIdentity()) {
310: Envelope newBounds = new Envelope();
311: JTS.transform(bounds, newBounds,
312: layerToMapTransform, 10);
313: bounds = newBounds;
314: }
315: } catch (IOException e) {
316: ProjectPlugin.log("", e); //$NON-NLS-1$
317: } catch (TransformException e) {
318: ProjectPlugin.log("", e); //$NON-NLS-1$
319: }
320: bounds.expandBy(bounds.getWidth() * .2, bounds
321: .getHeight() * .2);
322: if (notifier.isVisible()) {
323: manager.refresh(notifier, bounds);
324: }
325: }
326: }
327: }
328:
329: private void filterChanged(
330: final RenderManagerDynamic manager,
331: Notification event) {
332: if (!event.getOldValue().equals(event.getNewValue())) {
333: Filter newFilter = (Filter) event.getNewValue();
334:
335: if (Filter.ALL.equals(newFilter))
336: manager.clearSelection((Layer) event
337: .getNotifier());
338: else
339: manager.refreshSelection((Layer) event
340: .getNotifier(), null);
341: }
342: }
343: };
344: }
345:
346: static class RenderExecutorListener extends RenderListenerAdapter {
347:
348: private RenderManager manager;
349:
350: /**
351: * Construct <code>RenderManagerAdapters.RenderExecutorListener</code>.
352: */
353: public RenderExecutorListener(RenderManager manager) {
354: this .manager = manager;
355: }
356:
357: /**
358: * @see net.refractions.udig.project.render.RenderListenerAdapter#renderStarting()
359: */
360: protected void renderStarting() {
361: ((ViewportPane) manager.getMapDisplay()).renderStarting();
362: }
363:
364: /**
365: * @see net.refractions.udig.project.render.RenderListenerAdapter#renderUpdate()
366: */
367: protected void renderUpdate() {
368: ((ViewportPane) manager.getMapDisplay()).renderUpdate();
369: }
370:
371: /**
372: * @see net.refractions.udig.project.render.RenderListenerAdapter#renderDone()
373: */
374: protected void renderDone() {
375: ((ViewportPane) manager.getMapDisplay()).renderDone();
376: }
377: }
378:
379: static RenderExecutorListener getRenderExecutorListener(
380: RenderManager manager) {
381: return new RenderExecutorListener(manager);
382: }
383:
384: }
|