001: package net.refractions.udig.style.sld.editor;
002:
003: import net.refractions.udig.style.internal.StyleLayer;
004: import net.refractions.udig.style.sld.IEditorPageContainer;
005: import net.refractions.udig.style.sld.IStyleEditorPage;
006: import net.refractions.udig.style.sld.IStyleEditorPageContainer;
007:
008: import org.eclipse.jface.dialogs.Dialog;
009: import org.eclipse.jface.dialogs.DialogPage;
010: import org.eclipse.jface.dialogs.IPageChangedListener;
011: import org.eclipse.jface.dialogs.PageChangedEvent;
012: import org.eclipse.swt.SWT;
013: import org.eclipse.swt.graphics.Point;
014: import org.eclipse.swt.layout.GridData;
015: import org.eclipse.swt.layout.GridLayout;
016: import org.eclipse.swt.widgets.Composite;
017: import org.eclipse.swt.widgets.Control;
018: import org.eclipse.swt.widgets.Label;
019: import org.eclipse.ui.IWorkbench;
020: import org.geotools.event.GTEvent;
021: import org.geotools.event.GTListener;
022: import org.geotools.styling.Style;
023: import org.geotools.styling.StyledLayerDescriptor;
024:
025: /**
026: * <p>Provides a user interface (by extension point) for pages in the SLD Editor.</p>
027: * <p>Note: this will be rewritten in uDig 1.1.1</p>
028: * @author chorner
029: * @since 1.1
030: */
031: public abstract class StyleEditorPage extends DialogPage implements
032: IStyleEditorPage {
033:
034: public static final String XPID = "net.refractions.udig.style.sld.StyleEditorPage"; //$NON-NLS-1$
035:
036: private IStyleEditorPageContainer container = null;
037:
038: /**
039: * Description label.
040: *
041: * @see #createDescriptionLabel(Composite)
042: */
043: private Label descriptionLabel;
044:
045: /**
046: * Caches size of page.
047: */
048: private Point size = null;
049:
050: public StyleEditorPage() {
051: }
052:
053: public void applyData(Object data) {
054:
055: }
056:
057: /**
058: * Creates the page Control.
059: *
060: * Subclasses should not override this method, but instead use createPageContent to create their contents.
061: *
062: * @param parent the parent composite
063: */
064: public void createControl(Composite parent) {
065: Composite page = new Composite(parent, SWT.NONE);
066: page
067: .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
068: true));
069: GridLayout layout = new GridLayout(1, false);
070: layout.marginHeight = 0;
071: layout.marginWidth = 0;
072: page.setLayout(layout);
073: Dialog.applyDialogFont(page);
074: // initialize the dialog units
075: initializeDialogUnits(page);
076: //save the control
077: setControl(page);
078:
079: descriptionLabel = createDescriptionLabel(page);
080: if (descriptionLabel != null) {
081: descriptionLabel.setLayoutData(new GridData(SWT.FILL,
082: SWT.DEFAULT, true, false));
083: }
084:
085: //create the contents
086: createPageContent(page);
087:
088: //invoke the layout
089: parent.layout();
090:
091: //create the listener
092: StyledLayerDescriptor sld = container.getSLD();
093: if (sld != null) {
094: sld.addListener(new StyleChangedListener());
095: }
096:
097: container.addPageChangedListener(new IPageChangedListener() {
098:
099: public void pageChanged(PageChangedEvent event) {
100: if (getEditorPage() == event.getSelectedPage()) {
101: gotFocus(); //the current page just got focus, call the abstract method
102: }
103: }
104:
105: });
106: }
107:
108: /**
109: * Creates the page content.
110: *
111: * Subclasses must define this method and create their child controls here.
112: *
113: * @param parent composite to put the page content in
114: */
115: public abstract void createPageContent(Composite parent);
116:
117: public abstract String getLabel();
118:
119: /**
120: * Initializes the page (optional)
121: *
122: * Subclasses may override this method if they need to initialize.
123: *
124: * @param bench
125: */
126: public void init(IWorkbench bench) {
127: //don't do anything by default
128: }
129:
130: /**
131: * Computes the size for this page's UI control.
132: * <p>
133: * The default implementation of this <code>IPreferencePage</code>
134: * method returns the size set by <code>setSize</code>; if no size
135: * has been set, but the page has a UI control, the framework
136: * method <code>doComputeSize</code> is called to compute the size.
137: * </p>
138: *
139: * @return the size of the preference page encoded as
140: * <code>new Point(width,height)</code>, or
141: * <code>(0,0)</code> if the page doesn't currently have any UI component
142: */
143: public Point computeSize() {
144: if (size != null)
145: return size;
146: Control control = getControl();
147: if (control != null) {
148: size = doComputeSize();
149: return size;
150: }
151: return new Point(0, 0);
152: }
153:
154: /**
155: * Computes the size needed by this page's UI control.
156: * <p>
157: * All pages should override this method and set the appropriate sizes
158: * of their widgets, and then call <code>super.doComputeSize</code>.
159: * </p>
160: *
161: * @return the size of the preference page encoded as
162: * <code>new Point(width,height)</code>
163: */
164: protected Point doComputeSize() {
165: Control page = getControl();
166: if (descriptionLabel != null && page != null) {
167: Point bodySize = page.computeSize(SWT.DEFAULT, SWT.DEFAULT,
168: true);
169: GridData gd = (GridData) descriptionLabel.getLayoutData();
170: gd.widthHint = bodySize.x;
171: }
172: return getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
173: }
174:
175: /**
176: * Invoked when the user clicks cancel.
177: */
178: public abstract boolean performCancel();
179:
180: public IStyleEditorPageContainer getContainer() {
181: return container;
182: }
183:
184: public void setContainer(IEditorPageContainer container) {
185: if (container instanceof IStyleEditorPageContainer) {
186: this .container = (IStyleEditorPageContainer) container;
187: }
188: }
189:
190: public void setSize(Point size) {
191: this .size = size;
192: }
193:
194: @Override
195: public void dispose() {
196: descriptionLabel = null;
197: container = null;
198: size = null;
199: }
200:
201: /**
202: * Returns an error message, if applicable. The dialog automagically calls this method and
203: * displays it with an error icon if it returns a non-null string. Subclasses should determine
204: * the state of their respective pages in this method and return null if everything is okay.
205: */
206: @Override
207: public abstract String getErrorMessage();
208:
209: /**
210: * Creates and returns an SWT label under the given composite.
211: *
212: * @param parent the parent composite
213: * @return the new label
214: */
215: protected Label createDescriptionLabel(Composite parent) {
216: Label result = null;
217: String description = getDescription();
218: if (description != null) {
219: result = new Label(parent, SWT.WRAP);
220: result.setFont(parent.getFont());
221: result.setText(description);
222: }
223: return result;
224: }
225:
226: /**
227: * Determines if the page contents are valid input. Subclasses should override if invalid input
228: * is possible.
229: */
230: public boolean isValid() {
231: return true;
232: }
233:
234: /**
235: * Returns the StyledLayerDescriptor from the style object on the blackboard (and creates one if it is missing).
236: *
237: * @return SLD Object
238: */
239: public StyledLayerDescriptor getSLD() {
240: return container.getSLD();
241: }
242:
243: /**
244: * Returns the current style object from the dialog.
245: *
246: * @return style
247: */
248: public Style getStyle() {
249: return container.getStyle();
250: }
251:
252: /**
253: * Sets the current style object (on our styleblackboard clone).
254: *
255: * @param style
256: */
257: public void setStyle(Style style) {
258: container.setStyle(style);
259: }
260:
261: public StyleEditorPage getEditorPage() {
262: return this ;
263: }
264:
265: public StyleLayer getSelectedLayer() {
266: return container.getSelectedLayer();
267: }
268:
269: /**
270: * Each subclass must implement this method which is called each time the page obtains focus.
271: *
272: */
273: public abstract void gotFocus();
274:
275: /**
276: * Each subclass must implement this method which is called each time the style object is modified on ANY page.
277: */
278: public abstract void styleChanged(GTEvent event);
279:
280: private class StyleChangedListener implements GTListener {
281: public void changed(GTEvent arg0) {
282: getContainer().setExitButtonState(true);
283: styleChanged(arg0);
284: }
285: }
286:
287: }
|