0001: /*
0002: * uDig - User Friendly Desktop Internet GIS client http://udig.refractions.net (C) 2004, Refractions Research Inc. This
0003: * library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
0004: * License as published by the Free Software Foundation; version 2.1 of the License. This library is distributed in the
0005: * hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0006: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
0007: */
0008: package net.refractions.udig.project.ui.internal;
0009:
0010: import java.awt.Rectangle;
0011: import java.awt.geom.Rectangle2D;
0012: import java.io.IOException;
0013: import java.text.NumberFormat;
0014: import java.util.ArrayList;
0015: import java.util.Iterator;
0016: import java.util.List;
0017:
0018: import net.refractions.udig.catalog.IGeoResource;
0019: import net.refractions.udig.catalog.ITransientResolve;
0020: import net.refractions.udig.catalog.ui.export.CatalogExportDelegateWizard;
0021: import net.refractions.udig.catalog.ui.export.ExportResourceSelectionState;
0022: import net.refractions.udig.catalog.ui.workflow.Workflow;
0023: import net.refractions.udig.core.internal.ExtensionPointList;
0024: import net.refractions.udig.internal.ui.IDropTargetProvider;
0025: import net.refractions.udig.internal.ui.UDIGControlDropListener;
0026: import net.refractions.udig.internal.ui.UDIGDropHandler;
0027: import net.refractions.udig.project.EditManagerEvent;
0028: import net.refractions.udig.project.IEditManagerListener;
0029: import net.refractions.udig.project.ILayer;
0030: import net.refractions.udig.project.ILayerListener;
0031: import net.refractions.udig.project.IMapCompositionListener;
0032: import net.refractions.udig.project.IMapListener;
0033: import net.refractions.udig.project.LayerEvent;
0034: import net.refractions.udig.project.MapCompositionEvent;
0035: import net.refractions.udig.project.MapEvent;
0036: import net.refractions.udig.project.command.UndoRedoCommand;
0037: import net.refractions.udig.project.interceptor.MapInterceptor;
0038: import net.refractions.udig.project.internal.Layer;
0039: import net.refractions.udig.project.internal.Map;
0040: import net.refractions.udig.project.internal.Project;
0041: import net.refractions.udig.project.internal.ProjectPackage;
0042: import net.refractions.udig.project.internal.ProjectPlugin;
0043: import net.refractions.udig.project.internal.commands.SetScaleCommand;
0044: import net.refractions.udig.project.internal.commands.selection.SelectLayerCommand;
0045: import net.refractions.udig.project.internal.render.RenderManager;
0046: import net.refractions.udig.project.internal.render.impl.RenderExecutorImpl.LayerListener;
0047: import net.refractions.udig.project.preferences.PreferenceConstants;
0048: import net.refractions.udig.project.render.IRenderer;
0049: import net.refractions.udig.project.render.IViewportModel;
0050: import net.refractions.udig.project.render.IViewportModelListener;
0051: import net.refractions.udig.project.render.ViewportModelEvent;
0052: import net.refractions.udig.project.render.ViewportModelEvent.EventType;
0053: import net.refractions.udig.project.ui.AnimationUpdater;
0054: import net.refractions.udig.project.ui.ApplicationGIS;
0055: import net.refractions.udig.project.ui.IAnimation;
0056: import net.refractions.udig.project.ui.UDIGEditorInput;
0057: import net.refractions.udig.project.ui.commands.AbstractDrawCommand;
0058: import net.refractions.udig.project.ui.commands.IDrawCommand;
0059: import net.refractions.udig.project.ui.internal.commands.draw.DrawFeatureCommand;
0060: import net.refractions.udig.project.ui.internal.render.displayAdapter.impl.ViewportPaneSWT;
0061: import net.refractions.udig.project.ui.render.displayAdapter.ViewportPane;
0062: import net.refractions.udig.project.ui.tool.IMapEditorSelectionProvider;
0063: import net.refractions.udig.project.ui.tool.IToolManager;
0064: import net.refractions.udig.ui.IBlockingSelection;
0065: import net.refractions.udig.ui.PlatformGIS;
0066: import net.refractions.udig.ui.PreShutdownTask;
0067: import net.refractions.udig.ui.ProgressManager;
0068: import net.refractions.udig.ui.ShutdownTaskList;
0069: import net.refractions.udig.ui.UDIGDragDropUtilities;
0070: import net.refractions.udig.ui.ZoomingDialog;
0071: import net.refractions.udig.ui.UDIGDragDropUtilities.DragSourceDescriptor;
0072: import net.refractions.udig.ui.UDIGDragDropUtilities.DropTargetDescriptor;
0073:
0074: import org.eclipse.core.runtime.IAdaptable;
0075: import org.eclipse.core.runtime.IConfigurationElement;
0076: import org.eclipse.core.runtime.IProgressMonitor;
0077: import org.eclipse.core.runtime.ISafeRunnable;
0078: import org.eclipse.core.runtime.Platform;
0079: import org.eclipse.core.runtime.SubProgressMonitor;
0080: import org.eclipse.emf.common.notify.Notification;
0081: import org.eclipse.emf.ecore.InternalEObject;
0082: import org.eclipse.emf.ecore.impl.ENotificationImpl;
0083: import org.eclipse.emf.ecore.resource.Resource;
0084: import org.eclipse.jface.action.Action;
0085: import org.eclipse.jface.action.ContributionItem;
0086: import org.eclipse.jface.action.GroupMarker;
0087: import org.eclipse.jface.action.IAction;
0088: import org.eclipse.jface.action.IContributionManager;
0089: import org.eclipse.jface.action.IMenuListener;
0090: import org.eclipse.jface.action.IMenuManager;
0091: import org.eclipse.jface.action.MenuManager;
0092: import org.eclipse.jface.action.Separator;
0093: import org.eclipse.jface.action.StatusLineLayoutData;
0094: import org.eclipse.jface.action.StatusLineManager;
0095: import org.eclipse.jface.dialogs.IDialogConstants;
0096: import org.eclipse.jface.dialogs.IconAndMessageDialog;
0097: import org.eclipse.jface.preference.IPreferenceNode;
0098: import org.eclipse.jface.preference.IPreferenceStore;
0099: import org.eclipse.jface.preference.PreferenceDialog;
0100: import org.eclipse.jface.preference.PreferenceManager;
0101: import org.eclipse.jface.preference.PreferenceNode;
0102: import org.eclipse.jface.viewers.ISelection;
0103: import org.eclipse.jface.viewers.ISelectionChangedListener;
0104: import org.eclipse.jface.viewers.ISelectionProvider;
0105: import org.eclipse.jface.viewers.IStructuredSelection;
0106: import org.eclipse.jface.viewers.StructuredSelection;
0107: import org.eclipse.jface.window.SameShellProvider;
0108: import org.eclipse.jface.window.Window;
0109: import org.eclipse.jface.wizard.WizardDialog;
0110: import org.eclipse.swt.SWT;
0111: import org.eclipse.swt.dnd.DropTargetEvent;
0112: import org.eclipse.swt.events.FocusEvent;
0113: import org.eclipse.swt.events.FocusListener;
0114: import org.eclipse.swt.events.KeyEvent;
0115: import org.eclipse.swt.events.KeyListener;
0116: import org.eclipse.swt.graphics.Font;
0117: import org.eclipse.swt.graphics.FontData;
0118: import org.eclipse.swt.graphics.Point;
0119: import org.eclipse.swt.layout.FormAttachment;
0120: import org.eclipse.swt.layout.FormData;
0121: import org.eclipse.swt.layout.FormLayout;
0122: import org.eclipse.swt.layout.RowLayout;
0123: import org.eclipse.swt.widgets.Button;
0124: import org.eclipse.swt.widgets.Composite;
0125: import org.eclipse.swt.widgets.Control;
0126: import org.eclipse.swt.widgets.Display;
0127: import org.eclipse.swt.widgets.Event;
0128: import org.eclipse.swt.widgets.Label;
0129: import org.eclipse.swt.widgets.Listener;
0130: import org.eclipse.swt.widgets.Menu;
0131: import org.eclipse.swt.widgets.Shell;
0132: import org.eclipse.swt.widgets.Text;
0133: import org.eclipse.ui.IEditorInput;
0134: import org.eclipse.ui.IEditorSite;
0135: import org.eclipse.ui.IPartListener2;
0136: import org.eclipse.ui.ISelectionListener;
0137: import org.eclipse.ui.IWorkbench;
0138: import org.eclipse.ui.IWorkbenchActionConstants;
0139: import org.eclipse.ui.IWorkbenchPage;
0140: import org.eclipse.ui.IWorkbenchPart;
0141: import org.eclipse.ui.IWorkbenchPartReference;
0142: import org.eclipse.ui.IWorkbenchWindow;
0143: import org.eclipse.ui.PlatformUI;
0144: import org.eclipse.ui.SubActionBars2;
0145: import org.eclipse.ui.actions.ActionFactory;
0146: import org.eclipse.ui.dialogs.PropertyDialogAction;
0147: import org.eclipse.ui.part.EditorPart;
0148: import org.eclipse.ui.preferences.ScopedPreferenceStore;
0149: import org.geotools.feature.Feature;
0150: import org.opengis.referencing.crs.CoordinateReferenceSystem;
0151:
0152: /**
0153: * This class is the Eclipse editor Part in which a ViewportPane is embedded. The ViewportPane
0154: * displays and edits Maps. MapViewport is used to intialize ViewportPane and the RenderManager.
0155: *
0156: * @author Jesse Eichar
0157: * @version $Revision: 1.9 $
0158: */
0159: public class MapEditor extends EditorPart implements
0160: IDropTargetProvider, IAdaptable {
0161: /** The id of the MapViewport View */
0162: public final static String ID = "net.refractions.udig.project.ui.mapEditor"; //$NON-NLS-1$
0163: private final static int STATUS_LINE_HEIGHT;
0164: static {
0165: if (Platform.getWS().equals(Platform.WS_WIN32)) {
0166: STATUS_LINE_HEIGHT = 24;
0167: } else {
0168: STATUS_LINE_HEIGHT = 32;
0169: }
0170: }
0171: RenderManager renderManager = null;
0172:
0173: final MapEditor editor = this ;
0174: final StatusLineManager statusLineManager = new StatusLineManager();
0175: private MapEditorSite mapEditorSite;
0176: private boolean dirty = false;
0177:
0178: protected Map map;
0179:
0180: private Composite composite;
0181:
0182: Menu menu;
0183:
0184: private ViewportPane viewportPane;
0185:
0186: private DropTargetDescriptor dropTarget;
0187:
0188: /** This is for testing only DO NOT USE OTHERWISE */
0189: public boolean isTesting;
0190:
0191: private DragSourceDescriptor dragSource;
0192:
0193: /**
0194: * Creates a new MapViewport object.
0195: */
0196: public MapEditor() {
0197: super ();
0198: // Make sure the featureEditorProcessor has been started.
0199: ProjectUIPlugin.getDefault().getFeatureEditProcessor();
0200: }
0201:
0202: ILayerListener layerListener = new ILayerListener() {
0203:
0204: public void refresh(LayerEvent event) {
0205: if (event.getType() == LayerEvent.EventType.EDIT_EVENT) {
0206: setDirty(true);
0207: }
0208: }
0209:
0210: };
0211:
0212: IMapCompositionListener mapCompositionListener = new IMapCompositionListener() {
0213:
0214: public void changed(MapCompositionEvent event) {
0215: switch (event.getType()) {
0216: case ADDED:
0217:
0218: ((ILayer) event.getNewValue())
0219: .addListener(layerListener);
0220:
0221: // if a layer is only-in-memory, require a save
0222: if (event.getLayer().hasResource(
0223: ITransientResolve.class)) {
0224: setDirty(true);
0225: }
0226: break;
0227: case REMOVED:
0228:
0229: ((ILayer) event.getOldValue())
0230: .removeListener(layerListener);
0231:
0232: if (isDirty()) {
0233: // clear the dirty flag if no only-in-memory layers remain
0234: List<ILayer> layers = event.getSource()
0235: .getMapLayers();
0236: Iterator it = layers.iterator();
0237: boolean hasTransient = false;
0238: while (it.hasNext()) {
0239: ILayer layer = (ILayer) it.next();
0240: if (layer.hasResource(ITransientResolve.class)) {
0241: hasTransient = true;
0242: break;
0243: }
0244: }
0245: if (!hasTransient) {
0246: setDirty(false);
0247: }
0248: }
0249: default:
0250: break;
0251: }
0252: }
0253:
0254: };
0255:
0256: IMapListener mapListener = new IMapListener() {
0257:
0258: public void changed(final MapEvent event) {
0259: if (composite == null)
0260: return; // the composite hasn't been created so chill out
0261: if (map == null || composite.isDisposed()) {
0262: event.getSource().removeMapListener(this );
0263: return;
0264: }
0265:
0266: MapEditor.this .composite.getDisplay().asyncExec(
0267: new Runnable() {
0268: public void run() {
0269: switch (event.getType()) {
0270: case NAME:
0271: setPartName((String) event
0272: .getNewValue()); // rename the map
0273: break;
0274: case EDIT_MANAGER:
0275: for (ILayer layer : event.getSource()
0276: .getMapLayers()) {
0277: if (layer
0278: .hasResource(ITransientResolve.class)) {
0279: setDirty(true);
0280: break;
0281: }
0282: }
0283: break;
0284: default:
0285: break;
0286: }
0287: }
0288: });
0289: }
0290:
0291: };
0292:
0293: IEditManagerListener editListener = new IEditManagerListener() {
0294:
0295: public void changed(EditManagerEvent event) {
0296: switch (event.getType()) {
0297: case EditManagerEvent.EDIT_FEATURE:
0298: if (event.getSource().getEditLayer().hasResource(
0299: ITransientResolve.class)) {
0300: setDirty(true);
0301: }
0302: break;
0303: case EditManagerEvent.POST_COMMIT:
0304: setDirty(false);
0305: break;
0306: case EditManagerEvent.POST_ROLLBACK:
0307: setDirty(false);
0308: break;
0309: default:
0310: break;
0311: }
0312: }
0313: };
0314:
0315: private LayerSelectionListener layerSelectionListener;
0316:
0317: private ReplaceableSelectionProvider selectionProvider;
0318: private PreShutdownTask shutdownTask = new PreShutdownTask() {
0319:
0320: public int getProgressMonitorSteps() {
0321: return 3;
0322: }
0323:
0324: public boolean handlePreShutdownException(Throwable t,
0325: boolean forced) {
0326: ProjectUIPlugin.log(
0327: "error prepping map editors for shutdown", t); //$NON-NLS-1$
0328: return true;
0329: }
0330:
0331: public boolean preShutdown(IProgressMonitor monitor,
0332: IWorkbench workbench, boolean forced) throws Exception {
0333: monitor.beginTask("Saving Map Editor", 3); //$NON-NLS-1$
0334: save(new SubProgressMonitor(monitor, 1));
0335: if (dirty) {
0336: if (!forced) {
0337: return false;
0338: } else {
0339: setDirty(false);
0340: }
0341: }
0342: removeTemporaryLayers(ProjectPlugin.getPlugin()
0343: .getPreferenceStore());
0344: monitor.worked(1);
0345:
0346: // save the map's URI in the preferences so that it will be loaded the next time udig is
0347: // run.
0348: Resource resource = getMap().eResource();
0349: if (resource != null
0350: && renderManager.getRenderExecutor().getState() != IRenderer.RENDERING) {
0351: // save editor
0352: try {
0353: IPreferenceStore p = ProjectUIPlugin.getDefault()
0354: .getPreferenceStore();
0355: int numEditors = p.getInt(ID);
0356: String id = ID + ":" + numEditors; //$NON-NLS-1$
0357: numEditors++;
0358: p.setValue(ID, numEditors);
0359: String value = resource.getURI().toString();
0360: p.setValue(id, value);
0361: } catch (Exception e) {
0362: ProjectUIPlugin.log(
0363: "Failure saving which maps are open", e); //$NON-NLS-1$
0364: }
0365: }
0366:
0367: monitor.worked(1);
0368: monitor.done();
0369:
0370: return true;
0371: }
0372:
0373: private void save(final IProgressMonitor monitor) {
0374: if (dirty) {
0375: PlatformGIS.syncInDisplayThread(new Runnable() {
0376: public void run() {
0377: IconAndMessageDialog d = new SaveDialog(Display
0378: .getCurrent().getActiveShell(), map);
0379: int result = d.open();
0380:
0381: if (result == IDialogConstants.YES_ID)
0382: doSave(monitor);
0383: else if (result != Window.CANCEL) {
0384: setDirty(false);
0385: }
0386: }
0387: });
0388: }
0389: }
0390:
0391: };
0392:
0393: @SuppressWarnings("unchecked")
0394: public Object getAdapter(Class adaptee) {
0395: if (adaptee.isAssignableFrom(Map.class)) {
0396: return map;
0397: }
0398: if (adaptee.isAssignableFrom(ViewportPane.class)) {
0399: return viewportPane;
0400: }
0401: return super .getAdapter(adaptee);
0402: }
0403:
0404: /**
0405: * Displays the current scale ratio on the status bar
0406: *
0407: * @author Andrea Aime
0408: */
0409: class ScaleRatioLabel extends ContributionItem implements
0410: KeyListener, FocusListener {
0411: static final String SCALE_ITEM_ID = "Current scale"; //$NON-NLS-1$
0412: NumberFormat nf = NumberFormat.getIntegerInstance();
0413: Text label;
0414: IViewportModel viewportModel;
0415: /** Listens to viewport changes and updates the displayed scale accordingly */
0416: IViewportModelListener listener = new IViewportModelListener() {
0417:
0418: public void changed(ViewportModelEvent event) {
0419: if (event.getType() == EventType.CRS
0420: || event.getType() == EventType.BOUNDS) {
0421: Display display = PlatformUI.getWorkbench()
0422: .getDisplay();
0423: if (display == null)
0424: display = Display.getDefault();
0425:
0426: display.asyncExec(new Runnable() {
0427:
0428: public void run() {
0429: updateScale();
0430: }
0431: });
0432:
0433: }
0434:
0435: }
0436:
0437: };
0438:
0439: public ScaleRatioLabel() {
0440: super (SCALE_ITEM_ID);
0441: }
0442:
0443: /**
0444: * Sets the current viewport model. Should be called every time the map changes in order
0445: * update the shared ratio label
0446: */
0447: public void setViewportModel(IViewportModel newViewportModel) {
0448: // if(newViewportModel != null)
0449: // System.out.println(System.currentTimeMillis() + " - changing viewport model - map " +
0450: // newViewportModel.getMap().getName()); //$NON-NLS-1$
0451: if (newViewportModel != this .viewportModel) {
0452: if (viewportModel != null) {
0453: viewportModel.removeViewportModelListener(listener);
0454: }
0455: viewportModel = newViewportModel;
0456: viewportModel.addViewportModelListener(listener);
0457: updateScale();
0458: }
0459: }
0460:
0461: /**
0462: * @see org.eclipse.jface.action.IContributionItem#isDynamic()
0463: */
0464: public boolean isDynamic() {
0465: return true;
0466: }
0467:
0468: /**
0469: * @see org.eclipse.jface.action.ContributionItem#dispose()
0470: */
0471: public void dispose() {
0472: if (label != null)
0473: label.dispose();
0474: if (viewportModel != null) {
0475: viewportModel.removeViewportModelListener(listener);
0476: viewportModel = null;
0477: }
0478: }
0479:
0480: /**
0481: * @see org.eclipse.jface.action.ContributionItem#fill(org.eclipse.swt.widgets.Composite)
0482: */
0483: @Override
0484: public void fill(Composite c) {
0485: Label separator = new Label(c, SWT.SEPARATOR);
0486: StatusLineLayoutData data = new StatusLineLayoutData();
0487: separator.setLayoutData(data);
0488: data.widthHint = 1;
0489: data.heightHint = STATUS_LINE_HEIGHT;
0490: label = new Text(c, SWT.BORDER | SWT.CENTER);
0491: label.addKeyListener(this );
0492: label.addFocusListener(this );
0493: label.addListener(SWT.MouseDown, new Listener() {
0494: public void handleEvent(Event e) {
0495: if (label.getText().contains(":")) //$NON-NLS-1$
0496: formatForEditing();
0497: }
0498: });
0499: data = new StatusLineLayoutData();
0500: label.setLayoutData(data);
0501: updateScale();
0502: data.widthHint = 80;
0503: data.heightHint = STATUS_LINE_HEIGHT;
0504: setFont(label);
0505: }
0506:
0507: public void keyPressed(KeyEvent e) {
0508: if (label.getText().contains(":")) //$NON-NLS-1$
0509: formatForEditing();
0510: if (!isLegalKey(e)) {
0511: e.doit = false;
0512: }
0513: }
0514:
0515: public boolean isLegalKey(KeyEvent e) {
0516: char c = e.character;
0517:
0518: if (c == '0' || c == '1' || c == '2' || c == '3'
0519: || c == '4' || c == '5' || c == '6' || c == '7'
0520: || c == '8' || c == '9' || c == SWT.DEL
0521: || c == SWT.BS) {
0522: return true;
0523: }
0524:
0525: if (e.keyCode == SWT.ARROW_LEFT
0526: || e.keyCode == SWT.ARROW_RIGHT
0527: || e.keyCode == SWT.HOME || e.keyCode == SWT.END
0528: || e.keyCode == SWT.OK)
0529: return true;
0530:
0531: return false;
0532:
0533: }
0534:
0535: public void keyReleased(KeyEvent e) {
0536: if (e.character == SWT.Selection) {
0537: go();
0538: } else if (e.character == SWT.ESC) {
0539: updateScale();
0540: }
0541:
0542: }
0543:
0544: private void go() {
0545: String newScale = label.getText().trim();
0546: try {
0547: double d = Double.parseDouble(newScale);
0548: SetScaleCommand command = new SetScaleCommand(d);
0549: map.sendCommandASync(command);
0550: } catch (Exception e) {
0551: org.eclipse.swt.graphics.Rectangle start = ZoomingDialog
0552: .calculateBounds(label);
0553:
0554: ZoomingDialog.openErrorMessage(start, getSite()
0555: .getShell(),
0556: Messages.MapEditor_illegalScaleTitle,
0557: Messages.MapEditor_illegalScaleMessage);
0558: }
0559: }
0560:
0561: public void focusGained(FocusEvent e) {
0562: formatForEditing();
0563: }
0564:
0565: private void formatForEditing() {
0566: String text = label.getText();
0567: if (text.contains(":")) //$NON-NLS-1$
0568: text = text.substring(2);
0569: StringBuilder builder = new StringBuilder();
0570: for (int i = 0; i < text.length(); i++) {
0571: char c = text.charAt(i);
0572: if (c != ',')
0573: builder.append(c);
0574: }
0575: label.setText(builder.toString());
0576: int end = label.getText().length();
0577: label.setSelection(0, end);
0578: }
0579:
0580: public void focusLost(FocusEvent e) {
0581: updateScale();
0582: }
0583:
0584: private void updateScale() {
0585: if (label == null || label.isDisposed())
0586: return;
0587:
0588: if (viewportModel != null) {
0589: label
0590: .setText("1:" + nf.format(viewportModel.getScaleDenominator())); //$NON-NLS-1$
0591: label.setToolTipText(label.getText());
0592: } else {
0593: label.setText(""); //$NON-NLS-1$
0594: }
0595:
0596: }
0597:
0598: }
0599:
0600: void setFont(Control textArea2) {
0601: Display display = textArea2.getDisplay();
0602: FontData[] data = display.getFontList("courier", true); //$NON-NLS-1$
0603: if (data.length < 1) {
0604: data = textArea2.getFont().getFontData();
0605: }
0606: for (int i = 0; i < data.length; i++) {
0607: if (Platform.OS_MACOSX == Platform.getOS())
0608: data[i].setHeight(12);
0609: else
0610: data[i].setHeight(10);
0611: }
0612: textArea2.setFont(new Font(textArea2.getDisplay(), data));
0613: }
0614:
0615: /**
0616: * Displays a the current CRS and allows to change it
0617: */
0618: class StatusBarButton extends ContributionItem {
0619: static final String CRS_ITEM_ID = "CRS Display"; //$NON-NLS-1$
0620:
0621: static final String BOUNDS_ITEM_ID = "Bounds Display"; //$NON-NLS-1$
0622: static final int MAX_LENGTH = 12;
0623: private Button button;
0624: private String value;
0625:
0626: private String full;
0627:
0628: /**
0629: * Create new StatusBarLabel object
0630: */
0631: public StatusBarButton(String id, String initialValue) {
0632: super (id);
0633: setText(initialValue);
0634: }
0635:
0636: /**
0637: * sets the current text.
0638: */
0639: public void setText(String text) {
0640: value = text;
0641: full = value;
0642: if (value.length() > MAX_LENGTH) {
0643: int start2 = value.length() - 6;
0644: value = value.substring(0, 6)
0645: + "..." + value.substring(start2, value.length()); //$NON-NLS-1$
0646: System.out.println(value.length());
0647: }
0648: if (button != null && !button.isDisposed()) {
0649: button.setText(value);
0650: }
0651: }
0652:
0653: /**
0654: * @see org.eclipse.jface.action.IContributionItem#isDynamic()
0655: */
0656: public boolean isDynamic() {
0657: return true;
0658: }
0659:
0660: /**
0661: * @see org.eclipse.jface.action.ContributionItem#dispose()
0662: */
0663: public void dispose() {
0664: if (button != null)
0665: button.dispose();
0666: if (popup != null)
0667: popup.dispose();
0668: }
0669:
0670: /**
0671: * @see org.eclipse.jface.action.ContributionItem#fill(org.eclipse.swt.widgets.Composite)
0672: */
0673: @Override
0674: public void fill(Composite c) {
0675: Label separator = new Label(c, SWT.SEPARATOR);
0676: StatusLineLayoutData data = new StatusLineLayoutData();
0677: separator.setLayoutData(data);
0678: data.widthHint = 1;
0679: data.heightHint = STATUS_LINE_HEIGHT;
0680: button = new Button(c, SWT.PUSH);
0681: setFont(button);
0682: data = new StatusLineLayoutData();
0683: button.setLayoutData(data);
0684: button.setText(value);
0685: button.addListener(SWT.Selection, new Listener() {
0686:
0687: public void handleEvent(Event event) {
0688: promptForCRS();
0689: }
0690:
0691: });
0692: button.addListener(SWT.MouseEnter, new Listener() {
0693: public void handleEvent(final Event event) {
0694: showFullText();
0695: }
0696: });
0697: data.widthHint = 132;
0698: data.heightHint = STATUS_LINE_HEIGHT;
0699: }
0700:
0701: Label textLabel;
0702: Shell popup;
0703:
0704: private void promptForCRS() {
0705: CRSPropertyPage page = new CRSPropertyPage();
0706: page.setStrategy(new CRSPropertyPage.MapStrategy(getMap()));
0707: PreferenceManager mgr = new PreferenceManager();
0708: IPreferenceNode node = new PreferenceNode("1", page); //$NON-NLS-1$
0709: mgr.addToRoot(node);
0710:
0711: PreferenceDialog pdialog = new PreferenceDialog(getSite()
0712: .getShell(), mgr);
0713: ZoomingDialog dialog = new ZoomingDialog(getSite()
0714: .getShell(), pdialog, ZoomingDialog
0715: .calculateBounds(button));
0716: dialog.open();
0717: updateCRS();
0718: }
0719:
0720: void showFullText() {
0721: final Display display = button.getDisplay();
0722: if (popup == null) {
0723: popup = new Shell(display.getActiveShell(),
0724: SWT.NO_FOCUS | SWT.ON_TOP);
0725: popup.setForeground(display
0726: .getSystemColor(SWT.COLOR_INFO_FOREGROUND));
0727: popup.setBackground(display
0728: .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
0729: popup.setLayout(new RowLayout());
0730: Composite composite = new Composite(popup, SWT.NONE);
0731: composite.setForeground(display
0732: .getSystemColor(SWT.COLOR_INFO_FOREGROUND));
0733: composite.setBackground(display
0734: .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
0735: composite.setLayout(new RowLayout());
0736: textLabel = new Label(popup, SWT.NONE);
0737: textLabel.setForeground(display
0738: .getSystemColor(SWT.COLOR_INFO_FOREGROUND));
0739: textLabel.setBackground(display
0740: .getSystemColor(SWT.COLOR_INFO_BACKGROUND));
0741: textLabel.setFont(button.getFont());
0742:
0743: }
0744: Point location = statusLineManager.getControl().toDisplay(
0745: button.getLocation());
0746: location.y = location.y - STATUS_LINE_HEIGHT;
0747: popup.setLocation(location);
0748: textLabel.setText(full);
0749: popup.setVisible(true);
0750: popup.pack(true);
0751: display.timerExec(500, new Runnable() {
0752: public void run() {
0753: checkforMouseOver(display);
0754: }
0755: });
0756: }
0757:
0758: private void checkforMouseOver(final Display display) {
0759: if (display.getCursorControl() == button) {
0760: display.timerExec(500, new Runnable() {
0761: public void run() {
0762: if (display.getCursorControl() == button) {
0763: checkforMouseOver(display);
0764: } else {
0765: popup.setVisible(false);
0766: }
0767: }
0768: });
0769: } else {
0770: popup.setVisible(false);
0771: }
0772:
0773: }
0774:
0775: /**
0776: * Get current text.
0777: */
0778: public String getText() {
0779: return full;
0780: }
0781: }
0782:
0783: /**
0784: * Updates the crs label in the statusbar.
0785: */
0786: protected void updateCRS() {
0787: CoordinateReferenceSystem crs = getMap().getViewportModel()
0788: .getCRS();
0789: final String full = crs.getName().getCode();
0790: if (isSame(full))
0791: return;
0792:
0793: Display display = PlatformUI.getWorkbench().getDisplay();
0794: if (display == null)
0795: display = Display.getDefault();
0796:
0797: display.asyncExec(new Runnable() {
0798: public void run() {
0799:
0800: IContributionManager bar = mapEditorSite
0801: .getActionBars().getStatusLineManager();
0802: if (bar == null)
0803: return;
0804: StatusBarButton label = (StatusBarButton) bar
0805: .find(StatusBarButton.CRS_ITEM_ID);
0806: if (label == null) {
0807: label = new StatusBarButton(
0808: StatusBarButton.CRS_ITEM_ID, full);
0809: bar.appendToGroup(StatusLineManager.MIDDLE_GROUP,
0810: label);
0811: label.setVisible(true);
0812: bar.update(true);
0813: return;
0814: }
0815: label.setText(full);
0816: }
0817: });
0818:
0819: }
0820:
0821: /**
0822: * Makes sure the scale is displayed
0823: */
0824: protected void updateScaleLabel() {
0825: if (composite.isDisposed())
0826: return;
0827: if (Display.getCurrent() != null) {
0828: doUpdateScaleLabel();
0829: return;
0830: }
0831: Display display = PlatformUI.getWorkbench().getDisplay();
0832: if (display == null)
0833: display = Display.getDefault();
0834: display.asyncExec(new Runnable() {
0835: public void run() {
0836: doUpdateScaleLabel();
0837: }
0838:
0839: });
0840:
0841: }
0842:
0843: void doUpdateScaleLabel() {
0844: IContributionManager bar = mapEditorSite.getActionBars()
0845: .getStatusLineManager();
0846: if (bar == null)
0847: return;
0848: ScaleRatioLabel label = (ScaleRatioLabel) bar
0849: .find(ScaleRatioLabel.SCALE_ITEM_ID);
0850: if (label == null) {
0851: label = new ScaleRatioLabel();
0852: bar.appendToGroup(StatusLineManager.MIDDLE_GROUP, label);
0853: label.setVisible(true);
0854: bar.update(true);
0855: }
0856: label.setViewportModel(getMap().getViewportModel());
0857: }
0858:
0859: private boolean isSame(String crs) {
0860: IContributionManager bar = getActionbar()
0861: .getStatusLineManager();
0862:
0863: if (bar != null) {
0864: StatusBarButton label = (StatusBarButton) bar
0865: .find(StatusBarButton.CRS_ITEM_ID);
0866: if (label != null && crs.equals(label.getText()))
0867: return true;
0868: }
0869: return false;
0870: }
0871:
0872: /**
0873: * @see org.eclipse.ui.IWorkbenchPart#dispose()
0874: */
0875: public void dispose() {
0876:
0877: if (isTesting)
0878: return;
0879:
0880: deregisterFeatureFlasher();
0881: getSite().getPage().removePartListener(partlistener);
0882: viewportPane.removePaneListener(getMap()
0883: .getViewportModelInternal());
0884: getMap().getViewportModelInternal().setInitialized(false);
0885:
0886: selectFeatureListener = null;
0887: partlistener = null;
0888:
0889: if (statusLineManager != null)
0890: statusLineManager.dispose();
0891:
0892: final ScopedPreferenceStore store = ProjectPlugin.getPlugin()
0893: .getPreferenceStore();
0894: if (!PlatformUI.getWorkbench().isClosing()) {
0895: ShutdownTaskList.instance().removePreShutdownTask(
0896: shutdownTask);
0897: renderManager.dispose();
0898: map.getEditManagerInternal().setEditFeature(null, null);
0899: try {
0900: PlatformGIS.run(new ISafeRunnable() {
0901:
0902: public void handleException(Throwable exception) {
0903: ProjectUIPlugin
0904: .log(
0905: "error saving map: " + map.getName(), exception); //$NON-NLS-1$
0906: }
0907:
0908: public void run() throws Exception {
0909:
0910: removeTemporaryLayers(store);
0911: Project p = map.getProjectInternal();
0912: if (p != null) {
0913: if (p.eResource() != null
0914: && p.eResource().isModified()) {
0915: p
0916: .eResource()
0917: .save(
0918: ProjectPlugin
0919: .getPlugin().saveOptions);
0920: }
0921:
0922: final Resource resource = map.eResource();
0923: resource
0924: .save(ProjectPlugin.getPlugin().saveOptions);
0925:
0926: // need to kick the Project so viewers will update
0927: p
0928: .eNotify(new ENotificationImpl(
0929: (InternalEObject) p,
0930: Notification.SET,
0931: ProjectPackage.PROJECT__ELEMENTS_INTERNAL,
0932: null, null));
0933:
0934: } else {
0935: final Resource resource = map.eResource();
0936: if (resource != null)
0937: resource
0938: .save(ProjectPlugin.getPlugin().saveOptions);
0939: }
0940:
0941: map = null;
0942: }
0943:
0944: });
0945: } catch (Exception e) {
0946: ProjectPlugin.log("Exception while saving Map", e); //$NON-NLS-1$
0947: }
0948: }
0949:
0950: super .dispose();
0951:
0952: }
0953:
0954: private void removeTemporaryLayers(IPreferenceStore store) {
0955: if (store
0956: .getBoolean(net.refractions.udig.project.preferences.PreferenceConstants.P_REMOVE_LAYERS)) {
0957: List<Layer> layers = map.getLayersInternal();
0958: List<Layer> layersToRemove = new ArrayList<Layer>();
0959: for (Layer layer : layers) {
0960: if (layer.getGeoResources().get(0).canResolve(
0961: ITransientResolve.class)) {
0962: layersToRemove.add(layer);
0963: }
0964: }
0965:
0966: if (!layers.isEmpty()) {
0967: if (map.eResource() != null)
0968: map.eResource().setModified(true);
0969: layers.removeAll(layersToRemove);
0970: }
0971: }
0972: }
0973:
0974: /**
0975: * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
0976: */
0977: public void doSave(IProgressMonitor monitor) {
0978: final boolean[] success = new boolean[] { false };
0979: PlatformGIS.syncInDisplayThread(new Runnable() {
0980:
0981: public void run() {
0982: try {
0983: map.getEditManagerInternal().commitTransaction();
0984:
0985: boolean removeTempLayers = ProjectPlugin
0986: .getPlugin()
0987: .getPreferenceStore()
0988: .getBoolean(
0989: PreferenceConstants.P_REMOVE_LAYERS);
0990: if (!removeTempLayers) {
0991: success[0] = saveTemporaryLayers();
0992: } else {
0993: success[0] = true;
0994: }
0995: } catch (IOException e) {
0996: ProjectUIPlugin.log("Error saving", e); //$NON-NLS-1$
0997: success[0] = false;
0998: }
0999: }
1000:
1001: /**
1002: *
1003: * @param success
1004: */
1005: private boolean saveTemporaryLayers() {
1006: boolean success = false;
1007: List<IGeoResource> resources = new ArrayList<IGeoResource>();
1008: for (ILayer layer : map.getMapLayers()) {
1009: if (layer.hasResource(ITransientResolve.class))
1010: resources.addAll(layer.getGeoResources());
1011: }
1012: StructuredSelection selection = new StructuredSelection(
1013: resources);
1014: // create the workflow for the export wizard
1015: ExportResourceSelectionState layerState = new ExportResourceSelectionState(
1016: selection);
1017: Workflow workflow = new Workflow(
1018: new Workflow.State[] { layerState });
1019: CatalogExportDelegateWizard wiz = new CatalogExportDelegateWizard(
1020: workflow);
1021: wiz.init(null, null);
1022: // open the export dialog
1023: IWorkbench workbench = PlatformUI.getWorkbench();
1024: IWorkbenchWindow window = workbench
1025: .getActiveWorkbenchWindow();
1026: Shell shell = window.getShell();
1027: WizardDialog wizDialog = new WizardDialog(shell, wiz);
1028: wizDialog.create();
1029: if (wizDialog.open() == Window.OK) {
1030: success = true;
1031: }
1032: wizDialog.close();
1033:
1034: return success;
1035: }
1036: });
1037: if (success[0]) {
1038: setDirty(false);
1039: } else {
1040: //abort shutdown if in progress
1041: monitor.setCanceled(true);
1042: }
1043: }
1044:
1045: /**
1046: * @see org.eclipse.ui.ISaveablePart#doSaveAs()
1047: */
1048: public void doSaveAs() {
1049: }
1050:
1051: /**
1052: * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
1053: */
1054: public void init(IEditorSite site, IEditorInput input) {
1055: setSite(site);
1056: setInput(input);
1057: // initialize ToolManager
1058: ApplicationGIS.getToolManager();
1059: }
1060:
1061: /**
1062: * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
1063: */
1064: protected void setInput(IEditorInput input) {
1065: if (getEditorInput() != null) {
1066: Map map = (Map) ((UDIGEditorInput) getEditorInput())
1067: .getProjectElement();
1068: map.removeMapCompositionListener(mapCompositionListener);
1069: map.removeMapListener(mapListener);
1070: map.getEditManager().removeListener(editListener);
1071: }
1072: if (input != null) {
1073: map = (Map) ((UDIGEditorInput) input).getProjectElement();
1074: map.addMapCompositionListener(mapCompositionListener);
1075: map.addMapListener(mapListener);
1076: map.getEditManager().addListener(editListener);
1077: }
1078: super .setInput(input);
1079: }
1080:
1081: /**
1082: * @see org.eclipse.ui.ISaveablePart#isDirty()
1083: */
1084: public boolean isDirty() {
1085: return dirty;
1086: }
1087:
1088: /**
1089: * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
1090: */
1091: public boolean isSaveAsAllowed() {
1092: return true;
1093: }
1094:
1095: void setDirty(boolean dirty) {
1096: if (dirty == this .dirty)
1097: return;
1098:
1099: this .dirty = dirty;
1100:
1101: Display.getDefault().asyncExec(new Runnable() {
1102: /**
1103: * @see java.lang.Runnable#run()
1104: */
1105: @SuppressWarnings("synthetic-access")
1106: public void run() {
1107: firePropertyChange(PROP_DIRTY);
1108: }
1109: });
1110: }
1111:
1112: /**
1113: * @see org.eclipse.ui.part.EditorPart#isSaveOnCloseNeeded()
1114: */
1115: public boolean isSaveOnCloseNeeded() {
1116: return true;
1117: }
1118:
1119: /**
1120: * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
1121: */
1122: public void createPartControl(final Composite parent) {
1123:
1124: ShutdownTaskList.instance().addPreShutdownTask(shutdownTask);
1125:
1126: this .composite = new Composite(parent, SWT.NO_BACKGROUND);
1127: composite.setLayout(new FormLayout());
1128: composite.setFont(parent.getFont());
1129: // composite.setLayout(new GridLayout());
1130: setPartName(map.getName());
1131:
1132: setTitleToolTip(Messages.MapEditor_titleToolTip);
1133: setTitleImage(Images.get(ISharedImages.MAP_OBJ));
1134:
1135: viewportPane = new ViewportPaneSWT(composite, this );
1136:
1137: FormData formdata = new FormData();
1138: formdata.top = new FormAttachment(0);
1139: formdata.bottom = new FormAttachment(100, -STATUS_LINE_HEIGHT);
1140: formdata.left = new FormAttachment(0);
1141: formdata.right = new FormAttachment(100);
1142: viewportPane.getControl().setLayoutData(formdata);
1143:
1144: statusLineManager.add(new GroupMarker(
1145: StatusLineManager.BEGIN_GROUP));
1146: statusLineManager.add(new GroupMarker(
1147: StatusLineManager.MIDDLE_GROUP));
1148: statusLineManager.add(new GroupMarker(
1149: StatusLineManager.END_GROUP));
1150: statusLineManager.createControl(composite, SWT.BORDER);
1151: formdata = new FormData();
1152: formdata.left = new FormAttachment(0);
1153: formdata.right = new FormAttachment(100);
1154: formdata.top = new FormAttachment(viewportPane.getControl(), 0,
1155: SWT.BOTTOM);
1156: formdata.bottom = new FormAttachment(100);
1157: // formdata=new GridData(SWT.FILL, SWT.NONE, true, false);
1158: // formdata.heightHint=STATUS_LINE_HEIGHT;
1159: statusLineManager.getControl().setLayoutData(formdata);
1160:
1161: getSite().getPage().addPartListener(partlistener);
1162: registerFeatureFlasher();
1163: if (map.getRenderManager() == null)
1164: map.setRenderManagerInternal(new RenderManagerDynamic());
1165:
1166: renderManager = map.getRenderManagerInternal();
1167: viewportPane.setRenderManager(renderManager);
1168: renderManager.setMapDisplay(viewportPane);
1169:
1170: viewportPane.addPaneListener(getMap()
1171: .getViewportModelInternal());
1172:
1173: layerSelectionListener = new LayerSelectionListener(
1174: new LayerSelectionListener.Callback() {
1175:
1176: public void callback(List<Layer> layers) {
1177: if (composite.isDisposed()) {
1178: getSite().getPage()
1179: .removePostSelectionListener(
1180: layerSelectionListener);
1181: return; // component.isVisible cannot be called on a disposed component
1182: } else if (!composite.isVisible())
1183: return;
1184: Layer layer = layers.get(0);
1185: //Second condition excludes unnecessary UI call
1186: if (layer.getMap() == map
1187: && map.getEditManager()
1188: .getSelectedLayer() != layer) {
1189: SelectLayerCommand selectLayerCommand = new SelectLayerCommand(
1190: layer);
1191: selectLayerCommand.setMap(map);
1192: try {
1193: selectLayerCommand.run(ProgressManager
1194: .instance().get());
1195: } catch (Exception e) {
1196: throw (RuntimeException) new RuntimeException()
1197: .initCause(e);
1198: }
1199: map.sendCommandSync(new UndoRedoCommand(
1200: selectLayerCommand));
1201: }
1202: }
1203:
1204: });
1205: getSite().getPage().addPostSelectionListener(
1206: layerSelectionListener);
1207:
1208: for (Layer layer : getMap().getLayersInternal()) {
1209: layer.addListener(layerListener);
1210: }
1211:
1212: dropTarget = UDIGDragDropUtilities.addDropSupport(viewportPane
1213: .getControl(), this );
1214: this .selectionProvider = new ReplaceableSelectionProvider();
1215: getSite().setSelectionProvider(selectionProvider);
1216: runMapOpeningInterceptor(map);
1217: mapEditorSite = new MapEditorSite(super .getSite(), this );
1218: updateCRS();
1219: updateScaleLabel();
1220: }
1221:
1222: private void runMapOpeningInterceptor(Map map) {
1223: List<IConfigurationElement> interceptors = ExtensionPointList
1224: .getExtensionPointList(MapInterceptor.MAP_INTERCEPTOR_EXTENSIONPOINT);
1225: for (IConfigurationElement element : interceptors) {
1226: if (!"mapOpening".equals(element.getName())) //$NON-NLS-1$
1227: continue;
1228: try {
1229: MapInterceptor interceptor = (MapInterceptor) element
1230: .createExecutableExtension("class"); //$NON-NLS-1$
1231: interceptor.run(map);
1232: } catch (Exception e) {
1233: ProjectPlugin.log("", e); //$NON-NLS-1$
1234: }
1235: }
1236: }
1237:
1238: private FlashFeatureListener selectFeatureListener = new FlashFeatureListener();
1239: private boolean flashFeatureRegistered = false;
1240: private Action propertiesAction;
1241:
1242: /**
1243: * registers a listener with the current page that flashes a feature each time the current
1244: * selected feature changes.
1245: */
1246: protected synchronized void registerFeatureFlasher() {
1247: if (!flashFeatureRegistered) {
1248: flashFeatureRegistered = true;
1249: IWorkbenchPage page = getSite().getPage();
1250: page.addPostSelectionListener(selectFeatureListener);
1251: }
1252: }
1253:
1254: protected synchronized void deregisterFeatureFlasher() {
1255: flashFeatureRegistered = false;
1256: getSite().getPage().removePostSelectionListener(
1257: selectFeatureListener);
1258: }
1259:
1260: void createContextMenu() {
1261: if (menu == null) {
1262: final MenuManager contextMenu = new MenuManager();
1263: contextMenu.setRemoveAllWhenShown(true);
1264: contextMenu.addMenuListener(new IMenuListener() {
1265: public void menuAboutToShow(IMenuManager mgr) {
1266: IToolManager tm = ApplicationGIS.getToolManager();
1267: contextMenu.add(tm.getBACKWARD_HISTORYAction());
1268: contextMenu.add(tm.getFORWARD_HISTORYAction());
1269: contextMenu.add(new Separator());
1270: // contextMenu.add(tm.createCUTAction(MapEditor.this));
1271: contextMenu.add(tm.getCOPYAction(MapEditor.this ));
1272: contextMenu.add(tm.getPASTEAction(MapEditor.this ));
1273: contextMenu.add(tm.getDELETEAction());
1274:
1275: /*
1276: * Gets contributions from active modal tool if possible
1277: */
1278: tm.contributeActiveModalTool(contextMenu);
1279:
1280: contextMenu.add(new Separator());
1281: contextMenu.add(new GroupMarker(
1282: IWorkbenchActionConstants.MB_ADDITIONS));
1283: if (map.getEditManager().getEditFeature() != null) {
1284: contextMenu.add(ProjectUIPlugin.getDefault()
1285: .getFeatureEditProcessor()
1286: .getEditFeatureAction(
1287: getSite()
1288: .getSelectionProvider()
1289: .getSelection()));
1290:
1291: contextMenu.add(ProjectUIPlugin.getDefault()
1292: .getFeatureEditProcessor()
1293: .getEditWithFeatureMenu(
1294: getSite()
1295: .getSelectionProvider()
1296: .getSelection()));
1297: }
1298: contextMenu.add(ApplicationGIS.getToolManager()
1299: .createOperationsContextMenu(
1300: selectionProvider.getSelection()));
1301: contextMenu.add(new Separator());
1302: contextMenu.add(ActionFactory.EXPORT
1303: .create(getSite().getWorkbenchWindow()));
1304: contextMenu.add(new Separator());
1305: contextMenu.add(getPropertiesAction());
1306: }
1307: });
1308:
1309: // Create menu.
1310: menu = contextMenu.createContextMenu(composite);
1311: getSite().registerContextMenu(contextMenu,
1312: getSite().getSelectionProvider());
1313: }
1314: }
1315:
1316: protected IAction getPropertiesAction() {
1317: if (propertiesAction == null) {
1318: final Shell shell = PlatformUI.getWorkbench()
1319: .getActiveWorkbenchWindow().getShell();
1320: final PropertyDialogAction tmp = new PropertyDialogAction(
1321: new SameShellProvider(shell),
1322: new ISelectionProvider() {
1323:
1324: public void addSelectionChangedListener(
1325: ISelectionChangedListener listener) {
1326: }
1327:
1328: public ISelection getSelection() {
1329: return new StructuredSelection(map);
1330: }
1331:
1332: public void removeSelectionChangedListener(
1333: ISelectionChangedListener listener) {
1334: }
1335:
1336: public void setSelection(ISelection selection) {
1337: }
1338:
1339: });
1340:
1341: propertiesAction = new Action() {
1342: @Override
1343: public void runWithEvent(Event event) {
1344: tmp.createDialog().open();
1345: }
1346: };
1347:
1348: propertiesAction.setText(tmp.getText());
1349: propertiesAction.setActionDefinitionId(tmp
1350: .getActionDefinitionId());
1351: propertiesAction.setDescription(tmp.getDescription());
1352: propertiesAction.setHoverImageDescriptor(tmp
1353: .getHoverImageDescriptor());
1354: propertiesAction.setImageDescriptor(tmp
1355: .getImageDescriptor());
1356: propertiesAction.setToolTipText(tmp.getToolTipText());
1357:
1358: }
1359: getEditorSite().getActionBars().setGlobalActionHandler(
1360: ActionFactory.PROPERTIES.getId(), propertiesAction);
1361: return propertiesAction;
1362: }
1363:
1364: /**
1365: * @see org.eclipse.ui.IWorkbenchPart#setFocus()
1366: */
1367: public void setFocus() {
1368: composite.setFocus();
1369: updateCRS();
1370: updateScaleLabel();
1371: }
1372:
1373: /**
1374: * Returns the map that this editor edits
1375: *
1376: * @return Returns the map that this editor edits
1377: */
1378: public Map getMap() {
1379: return map;
1380: }
1381:
1382: /**
1383: * Returns the ActionbarContributor for the Editor.
1384: *
1385: * @return the ActionbarContributor for the Editor.
1386: */
1387: public SubActionBars2 getActionbar() {
1388: return (SubActionBars2) getEditorSite().getActionBars();
1389: }
1390:
1391: IPartListener2 partlistener = new IPartListener2() {
1392: public void partActivated(IWorkbenchPartReference partRef) {
1393: if (partRef.getPart(false) == MapEditor.this ) {
1394: registerFeatureFlasher();
1395: ApplicationGIS.getToolManager()
1396: .setCurrentEditor(editor);
1397: }
1398: }
1399:
1400: public void partBroughtToTop(IWorkbenchPartReference partRef) {
1401: }
1402:
1403: public void partClosed(IWorkbenchPartReference partRef) {
1404: if (partRef.getPart(false) == MapEditor.this ) {
1405: deregisterFeatureFlasher();
1406: visible = false;
1407: }
1408: }
1409:
1410: public void partDeactivated(IWorkbenchPartReference partRef) {
1411: // do nothing
1412: }
1413:
1414: public void partOpened(IWorkbenchPartReference partRef) {
1415: // do nothing
1416: }
1417:
1418: public void partHidden(IWorkbenchPartReference partRef) {
1419: if (partRef.getPart(false) == MapEditor.this ) {
1420: deregisterFeatureFlasher();
1421: visible = false;
1422: }
1423: }
1424:
1425: public void partVisible(IWorkbenchPartReference partRef) {
1426: if (partRef.getPart(false) == MapEditor.this ) {
1427: registerFeatureFlasher();
1428: visible = true;
1429: }
1430: }
1431:
1432: public void partInputChanged(IWorkbenchPartReference partRef) {
1433: }
1434:
1435: };
1436:
1437: private boolean draggingEnabled;
1438: private volatile boolean visible = false;
1439:
1440: /**
1441: * Opens the map's context menu.
1442: */
1443: public void openContextMenu() {
1444: getEditorSite().getShell().getDisplay().asyncExec(
1445: new Runnable() {
1446: public void run() {
1447: menu.setVisible(true);
1448: }
1449: });
1450: }
1451:
1452: public UDIGDropHandler getDropHandler() {
1453: return ((UDIGControlDropListener) dropTarget.listener)
1454: .getHandler();
1455: }
1456:
1457: public Object getTarget(DropTargetEvent event) {
1458: return this ;
1459: }
1460:
1461: /**
1462: * Enables or disables dragging (drag and drop) from the map editor.
1463: */
1464: public void setDragging(boolean enable) {
1465: if (draggingEnabled == enable)
1466: return;
1467: if (enable) {
1468: dragSource = UDIGDragDropUtilities.addDragSupport(
1469: viewportPane.getControl(), getSite()
1470: .getSelectionProvider());
1471: } else {
1472: dragSource.source.dispose();
1473: }
1474: draggingEnabled = enable;
1475: }
1476:
1477: public boolean isDragging() {
1478: return draggingEnabled;
1479: }
1480:
1481: @Override
1482: public String toString() {
1483: return getTitle();
1484: }
1485:
1486: /**
1487: * @return Returns the composite.
1488: */
1489: public Composite getComposite() {
1490: return composite;
1491: }
1492:
1493: public void setSelectionProvider(
1494: IMapEditorSelectionProvider selectionProvider) {
1495: if (selectionProvider == null) {
1496: throw new NullPointerException(
1497: "selection provider must not be null!"); //$NON-NLS-1$
1498: }
1499: selectionProvider.setActiveMap(getMap(), this );
1500: if (selectionProvider != this .selectionProvider
1501: .getSelectionProvider()) {
1502: this .selectionProvider.setProvider(selectionProvider);
1503: }
1504: createContextMenu();
1505: }
1506:
1507: public MapEditorSite getMapEditorSite() {
1508: return mapEditorSite;
1509: }
1510:
1511: private class FlashFeatureListener implements ISelectionListener {
1512:
1513: public void selectionChanged(IWorkbenchPart part,
1514: final ISelection selection) {
1515: if (part == MapEditor.this
1516: || getSite().getPage().getActivePart() != part
1517: || selection instanceof IBlockingSelection)
1518: return;
1519:
1520: ISafeRunnable sendAnimation = new ISafeRunnable() {
1521: public void run() {
1522: List<Feature> features = new ArrayList<Feature>();
1523: IStructuredSelection s = (IStructuredSelection) selection;
1524: for (Iterator iter = s.iterator(); iter.hasNext();) {
1525: Object element = iter.next();
1526:
1527: if (element instanceof Feature) {
1528: Feature feature = (Feature) element;
1529: features.add(feature);
1530: }
1531: }
1532: if (features.size() == 0)
1533: return;
1534: if (!renderManager.isDisposed()) {
1535: IAnimation anim = createAnimation(features);
1536: if (anim != null)
1537: AnimationUpdater.runTimer(
1538: map.getRenderManager()
1539: .getMapDisplay(), anim);
1540: }
1541: }
1542:
1543: public void handleException(Throwable exception) {
1544: ProjectUIPlugin.log(
1545: "Exception preparing animation", exception); //$NON-NLS-1$
1546: }
1547: };
1548:
1549: try {
1550: sendAnimation.run();
1551: } catch (Exception e) {
1552: ProjectUIPlugin.log("", e); //$NON-NLS-1$
1553: }
1554: // PlatformGIS.run(sendAnimation);
1555: }
1556:
1557: private IAnimation createAnimation(List<Feature> current) {
1558: final List<IDrawCommand> commands = new ArrayList<IDrawCommand>();
1559: for (Feature feature : current) {
1560: if (feature == null
1561: || feature.getFeatureType()
1562: .getDefaultGeometry() == null)
1563: continue;
1564: DrawFeatureCommand command = null;
1565: if (feature instanceof IAdaptable) {
1566: Layer layer = (Layer) ((IAdaptable) feature)
1567: .getAdapter(Layer.class);
1568: if (layer != null)
1569: try {
1570: command = new DrawFeatureCommand(feature,
1571: layer);
1572: } catch (IOException e) {
1573: // do nothing... thats life
1574: }
1575: }
1576: if (command == null) {
1577: command = new DrawFeatureCommand(feature);
1578: }
1579: command.setMap(getMap());
1580: command.preRender();
1581: commands.add(command);
1582: }
1583: Rectangle2D rect = new Rectangle();
1584: // for( IDrawCommand command : commands ) {
1585: // rect=rect.createUnion(command.getValidArea());
1586: // }
1587: final Rectangle validArea = (Rectangle) rect;
1588: class FeatureAnimation extends AbstractDrawCommand
1589: implements IAnimation {
1590:
1591: private int runs = 0;
1592:
1593: public short getFrameInterval() {
1594: return 300;
1595: }
1596:
1597: public void nextFrame() {
1598: runs++;
1599: }
1600:
1601: public boolean hasNext() {
1602: return runs < 6;
1603: }
1604:
1605: public void run(IProgressMonitor monitor)
1606: throws Exception {
1607: if (runs % 2 == 0) {
1608: for (IDrawCommand command : commands) {
1609: command.setGraphics(graphics, display);
1610: command.setMap(getMap());
1611: command.run(monitor);
1612: }
1613: }
1614: }
1615:
1616: public Rectangle getValidArea() {
1617: return validArea;
1618: }
1619:
1620: public void setValid(boolean valid) {
1621: super .setValid(valid);
1622: for (IDrawCommand command : commands) {
1623: command.setValid(valid);
1624: }
1625: }
1626:
1627: }
1628: return new FeatureAnimation();
1629: }
1630: }
1631:
1632: public boolean isVisible() {
1633: return visible;
1634: }
1635:
1636: }
|