/* Spatial Operations & Editing Tools for uDig * * Axios Engineering under a funding contract with: * Diputación Foral de Gipuzkoa, Ordenación Territorial * * http://b5m.gipuzkoa.net * http://www.axios.es * * (C) 2006, Diputación Foral de Gipuzkoa, Ordenación Territorial (DFG-OT). * DFG-OT agrees to licence under Lesser General Public License (LGPL). * * You can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software * Foundation; version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package es.axios.udig.ui.editingtools.precisiontools.commons.view; import java.util.ArrayList; import java.util.List; import java.util.Observable; import java.util.Observer; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.Map.Entry; import javax.measure.unit.Unit; import net.refractions.udig.project.EditManagerEvent; import net.refractions.udig.project.IEditManager; import net.refractions.udig.project.IEditManagerListener; import net.refractions.udig.project.command.UndoableComposite; import net.refractions.udig.project.command.UndoableMapCommand; import net.refractions.udig.project.ui.tool.IToolContext; import net.refractions.udig.tools.edit.EditToolHandler; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.custom.ViewForm; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import es.axios.geotools.util.UnitList; import es.axios.udig.ui.commons.message.InfoMessage; import es.axios.udig.ui.commons.message.InfoMessage.Type; import es.axios.udig.ui.editingtools.internal.i18n.Messages; import es.axios.udig.ui.editingtools.precisiontools.commons.internal.PrecisionToolsContext; /** * Abstract composite for the parameters view of the precision tools. * * @author Aritz Davila (www.axios.es) * @author Mauricio Pazos (www.axios.es) */ public abstract class AbstractParametersComposite extends Composite implements Observer { /** * The thread that creates the SWT controls, is needed because only the * creator thread could edit SWT controls. */ protected Thread fatherThread = null; protected PrecisionToolsContext toolContext = null; protected IEditManagerListener editManagerListener = null; protected IToolContext context = null; protected CLabel messageImage = null; protected CLabel messageText = null; protected Composite compositeLegend = null; protected Composite compositeOperations = null; protected ViewForm viewForm = null; protected CLabel labelReferenceLine = null; protected String referenceLine = ""; //$NON-NLS-1$ protected String referenceLineToolTip = ""; //$NON-NLS-1$ private Set<Entry<String, Unit<?>>> unitset; private boolean loadComplete = false; public AbstractParametersComposite(Composite parent, int style) { super(parent, style); init(); this.setVisible(false); } /** * Initializes the listener and layout. */ private void init() { // Store the thread which creates the controls. this.fatherThread = Thread.currentThread(); initListener(); GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 1; this.setLayout(gridLayout); GridData gridData2 = new GridData(); gridData2.horizontalAlignment = GridData.FILL; gridData2.grabExcessHorizontalSpace = true; gridData2.horizontalSpan = 3; gridData2.grabExcessVerticalSpace = false; gridData2.verticalAlignment = GridData.BEGINNING; viewForm = new ViewForm(this, SWT.NONE); viewForm.setLayout(gridLayout); viewForm.setLayoutData(gridData2); createCompositeLegend(viewForm); viewForm.setTopLeft(compositeLegend); createCompositeOperations(viewForm); viewForm.setContent(compositeOperations); initializeUnitSet(); } private void initializeUnitSet() { Display.getCurrent().asyncExec(new Runnable() { public void run() { Set<Unit<?>> commonLengthUnits = UnitList.getCommonLengthUnits(); SortedMap<String, Unit<?>> units = new TreeMap<String, Unit<?>>(); for (Unit<?> unit : commonLengthUnits) { units.put(UnitList.getUnitName(unit), unit); } unitset = units.entrySet(); loadComplete = true; } }); } protected String getUnitName(Unit<?> mapUnits) { String shorUnitName = ""; //$NON-NLS-1$ if (loadComplete) { for (Entry<String, Unit<?>> entry : unitset) { if (entry.getValue().equals(mapUnits)) { shorUnitName = entry.getKey(); } } } return shorUnitName; } private void createCompositeOperations(Composite parent) { GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 4; GridData gridData2 = new GridData(); gridData2.horizontalAlignment = GridData.FILL; gridData2.grabExcessHorizontalSpace = true; gridData2.horizontalSpan = 4; gridData2.grabExcessVerticalSpace = false; gridData2.verticalAlignment = GridData.FILL; compositeOperations = new Composite(parent, SWT.NONE); compositeOperations.setLayout(gridLayout); compositeOperations.setLayoutData(gridData2); GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = false; gridData.horizontalSpan = 4; gridData.verticalAlignment = GridData.FILL; labelReferenceLine = new CLabel(compositeOperations, SWT.NONE); labelReferenceLine.setLayoutData(gridData); labelReferenceLine.setText(Messages.PrecisionTool_reference_line + ":" + referenceLine); //$NON-NLS-1$ labelReferenceLine.setToolTipText(Messages.PrecisionTool_reference_line); } private void createCompositeLegend(Composite parent) { GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 3; GridData gridData2 = new GridData(); gridData2.horizontalAlignment = GridData.FILL; gridData2.grabExcessHorizontalSpace = true; gridData2.horizontalSpan = 3; gridData2.grabExcessVerticalSpace = false; gridData2.verticalAlignment = GridData.BEGINNING; compositeLegend = new Composite(parent, SWT.NONE); compositeLegend.setLayout(gridLayout); compositeLegend.setLayoutData(gridData2); messageImage = new CLabel(compositeLegend, SWT.NONE); GridData gridData7 = new GridData(); gridData7.horizontalAlignment = GridData.BEGINNING; gridData7.minimumWidth = 30; gridData7.widthHint = 30; messageImage.setLayoutData(gridData7); messageText = new CLabel(compositeLegend, SWT.NONE); GridData gridData8 = new GridData(); gridData8.horizontalAlignment = GridData.FILL; gridData8.grabExcessHorizontalSpace = true; gridData8.grabExcessVerticalSpace = true; gridData8.verticalAlignment = GridData.FILL; messageText.setLayoutData(gridData8); messageText.setFont(JFaceResources.getDialogFont()); InfoMessage infoMessage = new InfoMessage(Messages.PrecisionParallel_InitialMessage, Type.INFORMATION); messageImage.setImage(infoMessage.getImage()); messageText.setText(infoMessage.getText()); } /** * Add an empty label. */ protected void addEmptyLabel(Composite parent) { GridData gridData1 = new GridData(); gridData1.horizontalAlignment = GridData.FILL; gridData1.grabExcessHorizontalSpace = true; gridData1.grabExcessVerticalSpace = false; gridData1.verticalAlignment = GridData.BEGINNING; CLabel lbl = new CLabel(this, SWT.NONE); lbl.setLayoutData(gridData1); lbl.setText(""); //$NON-NLS-1$ } /** * Set the {@link PrecisionToolsContext}, add this composite as observer and * show its widget. * * @param toolContext */ public void setToolContext(PrecisionToolsContext toolContext) { assert toolContext != null : "Can not be null"; //$NON-NLS-1$ this.toolContext = toolContext; this.toolContext.addObserver(this); this.setVisible(true); setCustomToolContext(); } /** * Each subclass set it's specific context. */ protected abstract void setCustomToolContext(); /** * Creates the common widget for all the composites. */ protected void createContent() { GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 3; gridLayout.makeColumnsEqualWidth = false; GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.END; gridData.grabExcessHorizontalSpace = true; gridData.horizontalSpan = 3; gridData.grabExcessVerticalSpace = false; gridData.verticalAlignment = GridData.BEGINNING; Composite composite = new Composite(compositeOperations, SWT.NONE); composite.setLayout(gridLayout); composite.setLayoutData(gridData); } /** * Apply the changes */ protected void applyChanges() { // implemented on each subclass } /** * Rollback, cancel the current changes. */ public void discardChanges() { // implemented on each subclass } /** * Commit. Not a real commit, it makes the same as a double-click, add the * feature to the layer. */ public void acceptChanges() { if (toolContext == null) { return; } EditToolHandler handler = toolContext.getHandler(); List<UndoableMapCommand> commands = new ArrayList<UndoableMapCommand>(); commands.add(handler.getCommand(handler.getAcceptBehaviours())); UndoableComposite undoableComposite = new UndoableComposite(commands); undoableComposite.setMap(handler.getContext().getMap()); handler.getContext().sendASyncCommand(undoableComposite); handler.getContext().getViewportPane().repaint(); } /** * Display an information message on the view form. */ protected abstract void displayMessage(Type type); /** * Clears the data showed on the composite. */ protected abstract void clearData(); /** * Fill the object with data. */ protected abstract void populate(); /** * Updates the composite. */ public abstract void update(Observable o, Object arg); /** * Creates the default listeners. */ private void initListener() { this.editManagerListener = new IEditManagerListener() { public void changed(EditManagerEvent event) { updateEditManagerAction(event); } }; } /** * When a roll back occurs or commit. */ private void updateEditManagerAction(EditManagerEvent event) { int eventType = event.getType(); switch (eventType) { case EditManagerEvent.POST_ROLLBACK: case EditManagerEvent.POST_COMMIT: clearData(); break; default: break; } } public void setContext(IToolContext context) { IEditManager editManager; if (context == null) { // initialize or reinitialize editManager = getCurrentEditManager(); if (editManager != null) { removeListenerFrom(editManager); } } else { // sets maps and its layers as current editManager = context.getEditManager(); if (editManager != null) { addListenersTo(editManager); } } this.context = context; } /** * Removes the listener from the edit manager. * * @param editManager */ private void removeListenerFrom(IEditManager editManager) { assert editManager != null; assert this.editManagerListener != null; editManager.removeListener(this.editManagerListener); } /** * Get the current edit manager. * * @return */ private IEditManager getCurrentEditManager() { if (this.context == null) { return null; } return context.getEditManager(); } /** * Add listener to the edit manager. * * @param editManager */ private void addListenersTo(IEditManager editManager) { assert editManager != null; assert this.editManagerListener != null; editManager.addListener(this.editManagerListener); } }