blob: 28de728363ffc9f176c5f65b49a48732b17acfa2 [file] [log] [blame]
kchong38cbf172006-03-29 03:38:21 +00001/*******************************************************************************
2 * Copyright (c) 2001, 2006 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
kchong2be71b32006-04-11 16:32:03 +000011package org.eclipse.wst.xsd.ui.internal.adt.editor;
kchong38cbf172006-03-29 03:38:21 +000012
13import java.util.ArrayList;
14import java.util.EventObject;
15import java.util.Iterator;
16import java.util.List;
17
18import org.eclipse.core.resources.IMarker;
19import org.eclipse.core.resources.IResourceChangeListener;
20import org.eclipse.core.resources.ResourcesPlugin;
21import org.eclipse.core.runtime.IProgressMonitor;
22import org.eclipse.draw2d.ColorConstants;
23import org.eclipse.draw2d.IFigure;
24import org.eclipse.gef.DefaultEditDomain;
25import org.eclipse.gef.EditPart;
26import org.eclipse.gef.GraphicalEditPart;
27import org.eclipse.gef.GraphicalViewer;
28import org.eclipse.gef.LayerConstants;
29import org.eclipse.gef.MouseWheelHandler;
30import org.eclipse.gef.MouseWheelZoomHandler;
31import org.eclipse.gef.commands.CommandStack;
32import org.eclipse.gef.commands.CommandStackListener;
33import org.eclipse.gef.editparts.ZoomManager;
34import org.eclipse.gef.ui.actions.ActionRegistry;
35import org.eclipse.gef.ui.actions.UpdateAction;
36import org.eclipse.gef.ui.actions.ZoomInAction;
37import org.eclipse.gef.ui.actions.ZoomOutAction;
38import org.eclipse.gef.ui.parts.SelectionSynchronizer;
39import org.eclipse.jface.action.IAction;
40import org.eclipse.jface.viewers.ISelectionProvider;
41import org.eclipse.swt.SWT;
42import org.eclipse.swt.layout.FillLayout;
43import org.eclipse.swt.widgets.Composite;
44import org.eclipse.ui.IEditorInput;
45import org.eclipse.ui.IEditorPart;
46import org.eclipse.ui.IEditorSite;
47import org.eclipse.ui.IFileEditorInput;
48import org.eclipse.ui.PartInitException;
49import org.eclipse.ui.ide.IDE;
50import org.eclipse.ui.part.MultiPageEditorPart;
51import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
52import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
kchong2be71b32006-04-11 16:32:03 +000053import org.eclipse.wst.xsd.ui.internal.adt.actions.BaseSelectionAction;
54import org.eclipse.wst.xsd.ui.internal.adt.actions.SetInputToGraphView;
55import org.eclipse.wst.xsd.ui.internal.adt.design.DesignViewGraphicalViewer;
56import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.ADTEditPartFactory;
57import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.RootEditPart;
58import org.eclipse.wst.xsd.ui.internal.adt.facade.IModel;
59import org.eclipse.wst.xsd.ui.internal.adt.outline.ADTContentOutlinePage;
60import org.eclipse.wst.xsd.ui.internal.adt.outline.ADTContentOutlineProvider;
61import org.eclipse.wst.xsd.ui.internal.adt.outline.ADTLabelProvider;
kchong38cbf172006-03-29 03:38:21 +000062
63/**
64 * </ul>
65 * <li>page 0 graph
66 * <li>page 1 source
67 * </ul>
68 */
69public abstract class ADTMultiPageEditor extends MultiPageEditorPart implements IResourceChangeListener, CommandStackListener, ITabbedPropertySheetPageContributor
70{
71 protected IContentOutlinePage fOutlinePage;
72 protected long lastModificationStamp;
73 protected DesignViewGraphicalViewer graphicalViewer;
74
75 protected IModel model;
76 private DefaultEditDomain editDomain;
77 private SelectionSynchronizer synchronizer;
78 private ActionRegistry actionRegistry;
79 private List selectionActions = new ArrayList();
80 private List stackActions = new ArrayList();
81 private List propertyActions = new ArrayList();
82 protected ADTSelectionManager selectionManager;
83
84 /**
85 * Creates a multi-page editor example.
86 */
87 public ADTMultiPageEditor()
88 {
89 super();
90 DefaultEditDomain defaultGEFEditDomain = new DefaultEditDomain(this);
91 setEditDomain(defaultGEFEditDomain);
92 }
93
94 public String getContributorId()
95 {
kchong2be71b32006-04-11 16:32:03 +000096 return "org.eclipse.wst.xsd.ui.internal.editor";
kchong38cbf172006-03-29 03:38:21 +000097 }
98
99
100 public ADTSelectionManager getSelectionManager()
101 {
102 if (selectionManager == null)
103 {
104 selectionManager = new ADTSelectionManager(this);
105 }
106 return selectionManager;
107 }
108
109 protected void createGraphPage()
110 {
111 Composite parent = new Composite(getContainer(), SWT.NONE);
112 parent.setLayout(new FillLayout());
113
114 graphicalViewer = new DesignViewGraphicalViewer(this, getSelectionProvider());//getSelectionManager(), xsdModelAdapterFactory);
115 graphicalViewer.createControl(parent);
116 getEditDomain().addViewer(graphicalViewer);
117
118 configureGraphicalViewer();
119 hookGraphicalViewer();
120 initializeGraphicalViewer();
121 int index = addPage(parent);
122 setPageText(index, "Design");
123 }
124
125 protected ADTSelectionManager selectionProvider;
126 public ADTSelectionManager getSelectionProvider()
127 {
128 return selectionProvider;
129 }
130
131 /**
132 * Creates the pages of the multi-page editor.
133 */
134 protected void createPages()
135 {
136 model = buildModel((IFileEditorInput)getEditorInput());
137
138 selectionProvider = getSelectionManager();
139 getEditorSite().setSelectionProvider(selectionProvider);
140
141 createGraphPage();
142 }
143
144 /**
145 * The <code>MultiPageEditorPart</code> implementation of this
146 * <code>IWorkbenchPart</code> method disposes all nested editors.
147 * Subclasses may extend.
148 */
149 public void dispose()
150 {
151 getCommandStack().removeCommandStackListener(this);
152 ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
153 getActionRegistry().dispose();
154 super.dispose();
155 }
156
157 /**
158 * Saves the multi-page editor's document.
159 */
160 public void doSave(IProgressMonitor monitor)
161 {
162 getEditor(1).doSave(monitor);
163 getCommandStack().markSaveLocation();
164 }
165
166 /**
167 * Saves the multi-page editor's document as another file. Also updates the
168 * text for page 0's tab, and updates this multi-page editor's input to
169 * correspond to the nested editor's.
170 */
171 public void doSaveAs()
172 {
kchonge0f29a32006-04-10 21:31:11 +0000173 IEditorPart editor = getEditor(1);
kchong38cbf172006-03-29 03:38:21 +0000174 editor.doSaveAs();
kchonge0f29a32006-04-10 21:31:11 +0000175 setPageText(1, editor.getTitle());
kchong38cbf172006-03-29 03:38:21 +0000176 setInput(editor.getEditorInput());
kchonge0f29a32006-04-10 21:31:11 +0000177 getCommandStack().markSaveLocation();
kchong38cbf172006-03-29 03:38:21 +0000178 }
179
180 /*
181 * (non-Javadoc) Method declared on IEditorPart
182 */
183 public void gotoMarker(IMarker marker)
184 {
185 setActivePage(0);
186 IDE.gotoMarker(getEditor(0), marker);
187 }
188
189 /**
190 * The <code>MultiPageEditorExample</code> implementation of this method
191 * checks that the input is an instance of <code>IFileEditorInput</code>.
192 */
193 public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException
194 {
195 if (!(editorInput instanceof IFileEditorInput))
196 throw new PartInitException("Invalid Input: Must be IFileEditorInput");
197 super.init(site, editorInput);
198
199 getCommandStack().addCommandStackListener(this);
200 initializeActionRegistry();
201
202 String title = null;
203 if (getEditorInput() != null) {
204 title = getEditorInput().getName();
205 }
206 setPartName(title);
207 }
208
209 /*
210 * (non-Javadoc) Method declared on IEditorPart.
211 */
212 public boolean isSaveAsAllowed()
213 {
214 return true;
215 }
216
217 /**
218 * Calculates the contents of page 2 when the it is activated.
219 */
220 protected void pageChange(int newPageIndex)
221 {
222 super.pageChange(newPageIndex);
223 if (newPageIndex == 1)
224 {
225 }
226 }
227
228 abstract public IModel buildModel(IFileEditorInput editorInput);
229
230 protected void initializeActionRegistry()
231 {
232 createActions();
233 }
234
235 protected void createActions()
236 {
237 ActionRegistry registry = getActionRegistry();
238
239 BaseSelectionAction action = new SetInputToGraphView(this);
240 action.setSelectionProvider(getSelectionManager());
241 registry.registerAction(action);
242 }
243
244
245 public IModel getModel()
246 {
247 return model;
248 }
249
250 //protected XSDModelAdapterFactoryImpl xsdModelAdapterFactory;
251 //protected XSDAdapterFactoryLabelProvider adapterFactoryLabelProvider;
252
253 public Object getAdapter(Class type)
254 {
255 Object result = null;
256 if (type == ZoomManager.class)
257 return graphicalViewer.getProperty(ZoomManager.class.toString());
258
259 if (type == ISelectionProvider.class)
260 {
261 result = getSelectionManager();
262 }
263 /*
264 if (type == org.eclipse.ui.views.properties.IPropertySheetPage.class)
265 {
266 // PropertySheetPage page = new PropertySheetPage();
267 // page.setRootEntry(new UndoablePropertySheetEntry(getCommandStack()));
268 XSDTabbedPropertiesPage page = new XSDTabbedPropertiesPage(this);
269 return page;
270 }*/
271 if (type == GraphicalViewer.class)
272 return graphicalViewer;
273 if (type == CommandStack.class)
274 return getCommandStack();
275 if (type == ActionRegistry.class)
276 return getActionRegistry();
277 if (type == EditPart.class && graphicalViewer != null)
278 return graphicalViewer.getRootEditPart();
279 if (type == IFigure.class && graphicalViewer != null)
280 return ((GraphicalEditPart) graphicalViewer.getRootEditPart()).getFigure();
281
282 if (type == IContentOutlinePage.class)
283 {
284 if (fOutlinePage == null || fOutlinePage.getControl() == null || fOutlinePage.getControl().isDisposed())
285 {
286 ADTContentOutlinePage outlinePage = new ADTContentOutlinePage(this);
287 ADTContentOutlineProvider adtContentProvider = new ADTContentOutlineProvider();
288 outlinePage.setContentProvider(adtContentProvider);
289 ADTLabelProvider adtLabelProvider = new ADTLabelProvider();
290 outlinePage.setLabelProvider(adtLabelProvider);
291 outlinePage.setModel(getModel());
292
293 fOutlinePage = outlinePage;
294 }
295 return fOutlinePage;
296 }
297
298 return super.getAdapter(type);
299 }
300
301 protected DefaultEditDomain getEditDomain()
302 {
303 return editDomain;
304 }
305
306
307 protected void configureGraphicalViewer()
308 {
309 graphicalViewer.getControl().setBackground(ColorConstants.listBackground);
310
311 // Set the root edit part
312 // ScalableFreeformRootEditPart root = new ScalableFreeformRootEditPart();
313 RootEditPart root = new RootEditPart();
314
315 List zoomLevels = new ArrayList(3);
316 zoomLevels.add(ZoomManager.FIT_ALL);
317 zoomLevels.add(ZoomManager.FIT_WIDTH);
318 zoomLevels.add(ZoomManager.FIT_HEIGHT);
319 root.getZoomManager().setZoomLevelContributions(zoomLevels);
320
321 IAction zoomIn = new ZoomInAction(root.getZoomManager());
322 IAction zoomOut = new ZoomOutAction(root.getZoomManager());
323 getActionRegistry().registerAction(zoomIn);
324 getActionRegistry().registerAction(zoomOut);
325
326 getSite().getKeyBindingService().registerAction(zoomIn);
327 getSite().getKeyBindingService().registerAction(zoomOut);
328
329 //ConnectionLayer connectionLayer = (ConnectionLayer) root.getLayer(LayerConstants.CONNECTION_LAYER);
330 //connectionLayer.setConnectionRouter(new BendpointConnectionRouter());
331 IFigure feedbackLayer = root.getLayer(LayerConstants.FEEDBACK_LAYER);
332
333 //connectionLayer.setConnectionRouter(new ShortestPathConnectionRouter(connectionLayer));
334 // connectionLayer.setVisible(false);
335
336 // Zoom
337 ZoomManager manager = (ZoomManager) graphicalViewer.getProperty(ZoomManager.class.toString());
338 if (manager != null)
339 manager.setZoom(1.0);
340 // Scroll-wheel Zoom
341 graphicalViewer.setProperty(MouseWheelHandler.KeyGenerator.getKey(SWT.CTRL), MouseWheelZoomHandler.SINGLETON);
342
343
344
345 graphicalViewer.setRootEditPart(root);
346 graphicalViewer.setEditPartFactory(new ADTEditPartFactory());
347 }
348
349 protected void hookGraphicalViewer()
350 {
351 getSelectionSynchronizer().addViewer(graphicalViewer);
352 getSelectionManager().addSelectionChangedListener(graphicalViewer);
353 }
354
355 protected SelectionSynchronizer getSelectionSynchronizer()
356 {
357 if (synchronizer == null)
358 synchronizer = new SelectionSynchronizer();
359 return synchronizer;
360 }
361
362 protected void initializeGraphicalViewer()
363 {
364 graphicalViewer.setContents(model);
365 }
366
367 protected void setEditDomain(DefaultEditDomain ed)
368 {
369 this.editDomain = ed;
370 }
371
372 protected CommandStack getCommandStack()
373 {
374 return getEditDomain().getCommandStack();
375 }
376
377 protected ActionRegistry getActionRegistry()
378 {
379 if (actionRegistry == null)
380 actionRegistry = new ActionRegistry();
381 return actionRegistry;
382 }
383
384 public void commandStackChanged(EventObject event)
385 {
386 updateActions(stackActions);
387 firePropertyChange(PROP_DIRTY);
388 }
389
390 /**
391 * From GEF GraphicalEditor A convenience method for updating a set of actions
392 * defined by the given List of action IDs. The actions are found by looking
393 * up the ID in the {@link #getActionRegistry() action registry}. If the
394 * corresponding action is an {@link UpdateAction}, it will have its
395 * <code>update()</code> method called.
396 *
397 * @param actionIds
398 * the list of IDs to update
399 */
400 protected void updateActions(List actionIds)
401 {
402 ActionRegistry registry = getActionRegistry();
403 Iterator iter = actionIds.iterator();
404 while (iter.hasNext())
405 {
406 IAction action = registry.getAction(iter.next());
407 if (action instanceof UpdateAction)
408 ((UpdateAction) action).update();
409 }
410 }
411
412 /**
413 * Returns <code>true</code> if the command stack is dirty
414 *
415 * @see org.eclipse.ui.ISaveablePart#isDirty()
416 */
417 public boolean isDirty()
418 {
419 super.isDirty();
420 return getCommandStack().isDirty();
421 }
422}