001: /*
002: * uDig - User Friendly Desktop Internet GIS client http://udig.refractions.net (C) 2004, Refractions Research Inc. This
003: * library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
004: * License as published by the Free Software Foundation; version 2.1 of the License. This library is distributed in the
005: * hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
006: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
007: */
008: package net.refractions.udig.printing.ui.internal.editor;
009:
010: import java.io.IOException;
011: import java.lang.reflect.InvocationTargetException;
012: import java.util.EventObject;
013: import java.util.List;
014:
015: import net.refractions.udig.printing.model.Box;
016: import net.refractions.udig.printing.model.Page;
017: import net.refractions.udig.printing.ui.internal.Messages;
018: import net.refractions.udig.printing.ui.internal.PrintAction;
019: import net.refractions.udig.printing.ui.internal.PrintingPlugin;
020: import net.refractions.udig.printing.ui.internal.editor.parts.PartFactory;
021: import net.refractions.udig.printing.ui.internal.editor.parts.TreePartFactory;
022: import net.refractions.udig.project.internal.Map;
023: import net.refractions.udig.project.internal.Project;
024: import net.refractions.udig.project.internal.ProjectPackage;
025: import net.refractions.udig.project.internal.ProjectPlugin;
026: import net.refractions.udig.project.ui.internal.ProjectUIPlugin;
027:
028: import org.eclipse.core.runtime.IAdaptable;
029: import org.eclipse.core.runtime.IProgressMonitor;
030: import org.eclipse.emf.common.notify.Notification;
031: import org.eclipse.emf.ecore.InternalEObject;
032: import org.eclipse.emf.ecore.impl.ENotificationImpl;
033: import org.eclipse.emf.ecore.resource.Resource;
034: import org.eclipse.gef.ContextMenuProvider;
035: import org.eclipse.gef.DefaultEditDomain;
036: import org.eclipse.gef.EditPartViewer;
037: import org.eclipse.gef.GraphicalViewer;
038: import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
039: import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
040: import org.eclipse.gef.palette.PaletteRoot;
041: import org.eclipse.gef.ui.actions.ActionRegistry;
042: import org.eclipse.gef.ui.palette.PaletteViewer;
043: import org.eclipse.gef.ui.palette.PaletteViewerProvider;
044: import org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences;
045: import org.eclipse.gef.ui.parts.ContentOutlinePage;
046: import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
047: import org.eclipse.gef.ui.parts.TreeViewer;
048: import org.eclipse.jface.action.IAction;
049: import org.eclipse.jface.operation.IRunnableWithProgress;
050: import org.eclipse.jface.preference.IPreferenceStore;
051: import org.eclipse.swt.SWT;
052: import org.eclipse.swt.widgets.Composite;
053: import org.eclipse.swt.widgets.Control;
054: import org.eclipse.ui.IActionBars;
055: import org.eclipse.ui.IEditorInput;
056: import org.eclipse.ui.IEditorPart;
057: import org.eclipse.ui.PlatformUI;
058: import org.eclipse.ui.actions.ActionFactory;
059: import org.eclipse.ui.part.PageBook;
060: import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
061:
062: /**
063: * An editor for print pages. Uses GEF to edit the layout of the pages.
064: *
065: * @author Richard Gould
066: * @since 0.3
067: */
068: public class PageEditor extends GraphicalEditorWithFlyoutPalette
069: implements IAdaptable {
070:
071: public final static String EDIT_MAP = "edit map"; //$NON-NLS-1$
072: public final static String ID = "net.refractions.udig.printing.ui.internal.editor.pageEditor"; //$NON-NLS-1$
073:
074: private boolean savePreviouslyNeeded;
075: private Page page;
076: private PaletteRoot paletteRoot;
077: private PageEditorOutlinePage outlinePage;
078:
079: public PageEditor() {
080: setEditDomain(new DefaultEditDomain(this ));
081: }
082:
083: protected void configureGraphicalViewer() {
084: super .configureGraphicalViewer();
085:
086: getGraphicalViewer().setRootEditPart(
087: new ScalableFreeformRootEditPart());
088:
089: getGraphicalViewer().setEditPartFactory(new PartFactory());
090:
091: ContextMenuProvider provider = new PageContextMenuProvider(
092: getGraphicalViewer(), getActionRegistry());
093: getGraphicalViewer().setContextMenu(provider);
094: getSite().registerContextMenu(
095: "net.refractions.udig.printing.editor.contextmenu", //$NON-NLS-1$
096: provider, getGraphicalViewer());
097: }
098:
099: public void commandStackChanged(EventObject event) {
100: if (isDirty()) {
101: if (!this .savePreviouslyNeeded) {
102: this .savePreviouslyNeeded = true;
103: firePropertyChange(IEditorPart.PROP_DIRTY);
104: }
105: } else {
106: savePreviouslyNeeded = false;
107: firePropertyChange(IEditorPart.PROP_DIRTY);
108: }
109: super .commandStackChanged(event);
110: }
111:
112: protected void setInput(IEditorInput input) {
113: super .setInput(input);
114:
115: page = (Page) ((PageEditorInput) input).getProjectElement();
116:
117: setPartName(page.getName());
118: }
119:
120: protected void initializeGraphicalViewer() {
121: getGraphicalViewer().setContents(this .page);
122: }
123:
124: @Override
125: protected void createGraphicalViewer(Composite parent) {
126: GraphicalViewer viewer = new PrintingScrollingGraphicalViewer(
127: this );
128: viewer.createControl(parent);
129: setGraphicalViewer(viewer);
130: configureGraphicalViewer();
131: hookGraphicalViewer();
132: initializeGraphicalViewer();
133: }
134:
135: public void doSave(IProgressMonitor monitor) {
136: // TODO fix this at some point, currently doesn't work
137: // Platform.run(new SafeRunnable(){
138: //
139: // public void run() throws Exception {
140: // page.getProject().eResource().save(null);
141: // }
142: //
143: // });
144: // setDirty(false);
145: }
146:
147: public void doSaveAs() {
148: }
149:
150: /* TODO Permit saving at some point */
151: public boolean isDirty() {
152: return false;
153: }
154:
155: /* TODO Permit saving at some point */
156: public boolean isSaveAsAllowed() {
157: return true;
158: }
159:
160: @SuppressWarnings("unchecked")
161: protected void createActions() {
162: super .createActions();
163: ActionRegistry registry = getActionRegistry();
164:
165: // IAction action;
166: //
167: // action = new DirectEditAction((IWorkbenchPart)this);
168: // registry.registerAction(action);
169: // getSelectionActions().add(action.getId());
170: //
171: // action = new EditMapAction(this);
172: // registry.registerAction(action);
173: // getSelectionActions().add(action.getId());
174:
175: List<BoxAction> actions = PrintingPlugin
176: .getBoxExtensionActions(this );
177:
178: for (IAction action : actions) {
179: registry.registerAction(action);
180: getSelectionActions().add(action.getId());
181: }
182:
183: }
184:
185: protected PaletteRoot getPaletteRoot() {
186:
187: if (paletteRoot == null) {
188: paletteRoot = PageEditorPaletteFactory.createPalette();
189: }
190:
191: return paletteRoot;
192:
193: // PaletteRoot root = new PaletteRoot();
194: //
195: // List catagories = new ArrayList();
196: //
197: // PaletteGroup controls = new PaletteGroup("Controls");
198: //
199: // ToolEntry tool = new SelectionToolEntry();
200: // controls.add(tool);
201: // root.setDefaultEntry(tool);
202: //
203: // controls.add(new MarqueeToolEntry());
204: //
205: // PaletteSeparator separator = new PaletteSeparator(
206: // PrintingPlugin.PLUGIN_ID + ".palette.separator");
207: //
208: // separator.setUserModificationPermission(
209: // PaletteEntry.PERMISSION_NO_MODIFICATION);
210: // controls.add(separator);
211: //
212: // root.addAll(catagories);
213: //
214: // return root;
215: }
216:
217: protected FlyoutPreferences getPalettePreferences() {
218: return PageEditorPaletteFactory.createPalettePreferences();
219: }
220:
221: protected PaletteViewerProvider createPaletteViewerProvider() {
222: return new PaletteViewerProvider(getEditDomain()) {
223: protected void configurePaletteViewer(PaletteViewer viewer) {
224: super .configurePaletteViewer(viewer);
225: // create a drag source listener for this palette viewer
226: // together with an appropriate transfer drop target listener, this will enable
227: // model element creation by dragging a CombinatedTemplateCreationEntries
228: // from the palette into the editor
229: // @see ShapesEditor#createTransferDropTargetListener()
230: viewer
231: .addDragSourceListener(new TemplateTransferDragSourceListener(
232: viewer));
233: }
234: };
235: }
236:
237: public void createPartControl(Composite parent) {
238: super .createPartControl(parent);
239:
240: // enable printing
241: IActionBars actionBars = getEditorSite().getActionBars();
242: actionBars.setGlobalActionHandler(ActionFactory.PRINT.getId(),
243: new PrintAction());
244: }
245:
246: public Object getAdapter(Class type) {
247: if (type == IContentOutlinePage.class) {
248: if (outlinePage == null) {
249: outlinePage = new PageEditorOutlinePage(this ,
250: new TreeViewer());
251: }
252: return outlinePage;
253: }
254: if (type.isAssignableFrom(Map.class)) {
255: Map found = null;
256: for (Box box : page.getBoxes()) {
257: if (box instanceof IAdaptable) {
258: Object obj2 = ((IAdaptable) box)
259: .getAdapter(Map.class);
260: if (obj2 instanceof Map) {
261: /*
262: * If multiple maps are found, return null. This will prevent entities
263: * that operate only on one map from losing their context.
264: * (Imagine the layers view with two map objects selected. It would
265: * only display the layers from one of the objects - confusing to user)
266: */
267: if (found != null) {
268: found = null;
269: break;
270: }
271: found = (Map) obj2;
272: }
273: }
274: }
275: if (found != null) {
276: return found;
277: }
278: }
279: return super .getAdapter(type);
280: }
281:
282: private void disposeOutlinePage() {
283: this .outlinePage = null;
284: }
285:
286: private Page getModel() {
287: return page;
288: }
289:
290: @Override
291: public void dispose() {
292:
293: if (PlatformUI.getWorkbench().isClosing()) {
294: ProjectPlugin.getPlugin().turnOffEvents();
295:
296: // save the map's URI in the preferences so that it will be loaded the next time udig is
297: // run.
298:
299: Resource resource = this .page.eResource();
300: if (resource != null) {
301: try {
302: IPreferenceStore p = ProjectUIPlugin.getDefault()
303: .getPreferenceStore();
304: int numEditors = p.getInt(ID);
305: String id = ID + ":" + numEditors; //$NON-NLS-1$
306: numEditors++;
307: p.setValue(ID, numEditors);
308: String value = resource.getURI().toString();
309: p.setValue(id, value);
310: } catch (Exception e) {
311: ProjectUIPlugin.log(
312: "Failure saving which maps are open", e); //$NON-NLS-1$
313: }
314: }
315: }
316:
317: try {
318: getSite().getWorkbenchWindow().run(false, false,
319: new IRunnableWithProgress() {
320:
321: public void run(IProgressMonitor monitor)
322: throws InvocationTargetException,
323: InterruptedException {
324: Project p = page.getProjectInternal();
325: try {
326: if (p != null) {
327: if (p.eResource() != null
328: && p.eResource()
329: .isModified()) {
330: p
331: .eResource()
332: .save(
333: ProjectPlugin
334: .getPlugin().saveOptions);
335: }
336: saveAndUnload();
337: } else {
338: saveAndUnload();
339: }
340: } catch (IOException e) {
341: ProjectPlugin.log("", e);
342: }
343:
344: // need to kick the Project so viewers will update
345: p
346: .eNotify(new ENotificationImpl(
347: (InternalEObject) p,
348: Notification.SET,
349: ProjectPackage.PROJECT__ELEMENTS_INTERNAL,
350: null, null));
351: }
352:
353: private void saveAndUnload() throws IOException {
354: final Resource resource = page.eResource();
355:
356: resource
357: .save(ProjectPlugin.getPlugin().saveOptions);
358: if (!resource.getContents().contains(
359: ProjectPlugin.getPlugin()
360: .getProjectRegistry()))
361: ;
362: resource.unload();
363: }
364: });
365: } catch (Exception e) {
366: ProjectPlugin.log("", e);
367: }
368: super .dispose();
369:
370: }
371:
372: public class PageEditorOutlinePage extends ContentOutlinePage {
373:
374: private PageEditor editor;
375: private PageBook pagebook;
376:
377: /**
378: * Construct <code>PageEditorOutlinePage</code>.
379: *
380: * @param viewer
381: */
382: public PageEditorOutlinePage(PageEditor editor,
383: EditPartViewer viewer) {
384: super (viewer);
385:
386: if (editor == null) {
387: throw new IllegalArgumentException(
388: Messages.PageEditor_error_nullEditor);
389: }
390: this .editor = editor;
391: }
392:
393: /**
394: * TODO summary sentence for createControl ...
395: *
396: * @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite)
397: * @param parent
398: */
399: public void createControl(Composite parent) {
400: pagebook = new PageBook(parent, SWT.NONE);
401: Control outline = getViewer().createControl(pagebook);
402: getViewer().setEditDomain(editor.getEditDomain());
403: getViewer().setEditPartFactory(new TreePartFactory());
404: // getViewer().setKeyHandler(editor.getCommonKeyHandler());
405:
406: ContextMenuProvider cmProvider = new PageContextMenuProvider(
407: getViewer(), editor.getActionRegistry());
408: getViewer().setContextMenu(cmProvider);
409: getSite()
410: .registerContextMenu(
411: "net.refractions.udig.printing.outline.contextmenu", //$NON-NLS-1$
412: cmProvider,
413: getSite().getSelectionProvider());
414: editor.getSelectionSynchronizer().addViewer(getViewer());
415: getViewer().setContents(editor.getModel());
416: pagebook.showPage(outline);
417:
418: }
419:
420: /**
421: * TODO summary sentence for getControl ...
422: *
423: * @see org.eclipse.ui.part.IPage#getControl()
424: * @return
425: */
426: public Control getControl() {
427: return pagebook;
428: }
429:
430: /**
431: * TODO summary sentence for dispose ...
432: *
433: * @see org.eclipse.ui.part.IPage#dispose()
434: */
435: public void dispose() {
436: editor.getSelectionSynchronizer().removeViewer(getViewer());
437: super.dispose();
438: editor.disposeOutlinePage();
439: }
440: }
441: }
|