blob: 2392baa28cef5c1804df7b53e9cf9a88510b7076 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Soyatec - initial API and implementation
*******************************************************************************/
package org.eclipse.xwt.tools.ui.designer.core.editor;
import java.lang.reflect.Field;
import java.util.EventObject;
import java.util.Iterator;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.xwt.tools.ui.palette.page.ContributePalettePage;
import org.eclipse.xwt.tools.ui.palette.page.CustomPalettePage;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.ContextMenuProvider;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.KeyHandler;
import org.eclipse.gef.KeyStroke;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CommandStackListener;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.actions.GEFActionConstants;
import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.gef.ui.views.palette.PalettePage;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRewriteTarget;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.part.MultiPageEditorSite;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.eclipse.wst.sse.core.internal.text.BasicStructuredDocument;
import org.eclipse.wst.sse.core.internal.text.JobSafeStructuredDocument;
import org.eclipse.wst.sse.core.internal.undo.StructuredTextUndoManager;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;
import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;
import org.eclipse.xwt.tools.ui.designer.core.DesignerPlugin;
import org.eclipse.xwt.tools.ui.designer.core.component.CustomSashForm;
import org.eclipse.xwt.tools.ui.designer.core.editor.IVisualRenderer.Result;
import org.eclipse.xwt.tools.ui.designer.core.editor.commandstack.CombinedCommandStack;
import org.eclipse.xwt.tools.ui.designer.core.editor.dnd.DropContext;
import org.eclipse.xwt.tools.ui.designer.core.editor.dnd.DropTargetAdapter;
import org.eclipse.xwt.tools.ui.designer.core.editor.dnd.GraphicalViewerDropCreationListener;
import org.eclipse.xwt.tools.ui.designer.core.editor.dnd.palette.PaletteDropAdapter;
import org.eclipse.xwt.tools.ui.designer.core.editor.outline.DesignerOutlinePage;
import org.eclipse.xwt.tools.ui.designer.core.editor.text.StructuredTextHelper;
import org.eclipse.xwt.tools.ui.designer.core.model.IModelBuilder;
import org.eclipse.xwt.tools.ui.designer.core.model.ModelChangeListener;
import org.eclipse.xwt.tools.ui.designer.core.parts.RefreshContext;
import org.eclipse.xwt.tools.ui.designer.core.parts.root.DesignerRootEditPart;
import org.eclipse.xwt.tools.ui.designer.core.problems.ConfigurableProblemHandler;
import org.eclipse.xwt.tools.ui.designer.core.problems.ProblemHandler;
import org.eclipse.xwt.tools.ui.designer.core.util.DisplayUtil;
/**
* @author jliu (jin.liu@soyatec.com)
*/
@SuppressWarnings("restriction")
public abstract class Designer extends MultiPageEditorPart implements
ISelectionChangedListener, CommandStackListener {
public static final String DESIGNER_INPUT = "DESIGNER INPUT";
public static final String DESIGNER_TEXT_EDITOR = "DESIGNER TEXT EDITOR";
public static final String DEFAULT_DESIGNER_CONTEXT_MENU_ID = "#DesignerContext"; //$NON-NLS-1$
// UI editor.
protected CustomSashForm pageContainer;
private CustomPalettePage palettePage;
private IPropertySheetPage propertyPage;
private DesignerOutlinePage outlinePage;
private ProblemHandler problemHandler;
// GEF editor.
private GraphicalViewer graphicalViewer;
private EditDomain editDomain;
private ISelectionSynchronizer selectionSynchronizer;
private ActionRegistry actionRegistry;
private ActionGroup actionGroup;
// Source editor.
private StructuredTextEditor fTextEditor;
private IPropertyListener fPropertyListener;
private DropTargetAdapter dropListener;
private EObject documentRoot;
private IVisualRenderer visualsRender;
private CombinedCommandStack commandStack = new CombinedCommandStack();
private IModelBuilder modelBuilder;
private boolean installed = false;
private ModelChangeListener modelBuilderListener;
protected Display display;
private LoadingFigureController loadingFigureController;
private EditPartFactory editPartFactory;
private KeyHandler fSharedKeyHandler;
private Refresher refresher;
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.part.MultiPageEditorPart#init(org.eclipse.ui.IEditorSite,
* org.eclipse.ui.IEditorInput)
*/
public void init(IEditorSite site, IEditorInput input)
throws PartInitException {
super.init(site, input);
site.setSelectionProvider(null);// clear multi-page selection provider.
display = site.getShell().getDisplay();
loadingFigureController = new LoadingFigureController();
editDomain = new EditDomain(this);
editDomain.setCommandStack(commandStack.getCommandStack4GEF());
setPartName(input.getName());
getEditDomain().setData(DESIGNER_INPUT, input);
getCommandStack().getCommandStack4GEF().addCommandStackListener(this);
createActions();
configureActions();
refresher = new Refresher(display);
}
public Refresher getRefresher() {
return refresher;
}
protected void configureActions() {
actionGroup.updateActions(ActionGroup.PROPERTY_GRP);
actionGroup.updateActions(ActionGroup.STACK_GRP);
if (graphicalViewer != null) {
Iterator<?> actions = getActionRegistry().getActions();
while (actions.hasNext()) {
Object object = (Object) actions.next();
if (object instanceof SelectionAction) {
((SelectionAction) object)
.setSelectionProvider(graphicalViewer);
}
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.MultiPageEditorPart#setFocus()
*/
public void setFocus() {
if (graphicalViewer != null && graphicalViewer.getControl() != null) {
graphicalViewer.getControl().setFocus();
}
super.setFocus();
}
private void dispatchModelEvent(final Notification event) {
if (event.isTouch() || !installed) {
return;
}
if (display != null && display.getThread() == Thread.currentThread()) {
performModelChanged(event);
} else if (display != null) {
DisplayUtil.asyncExec(display, new Runnable() {
public void run() {
performModelChanged(event);
}
});
}
}
protected void performModelChanged(Notification event) {
if (visualsRender == null || event.isTouch()) {
return;
}
Result result;
try {
result = getVisualsRender().refreshVisuals(event);
} catch (RuntimeException e) {
return;
}
if (result == null || !result.refreshed) {
return;
}
EditPart toRefresh = null;
Object notifier = result.visuals;
// When the eventType is ADD, we need to refresh all children.
if (notifier == null) {
toRefresh = getGraphicalViewer().getRootEditPart();
} else {
toRefresh = getEditPart(notifier);
if (toRefresh == null) {
while (notifier != null && notifier instanceof EObject) {
Object parentNode = ((EObject) notifier).eContainer();
while (getEditPart(parentNode) != null) {
toRefresh = getEditPart(parentNode).getParent();
break;
}
notifier = parentNode;
}
}
}
if (toRefresh == null) {
return;
}
refresher.refreshInJob(toRefresh);
getOutlinePage().refresh(toRefresh);
// highlight changed one.
if (toRefresh.isSelectable()) {
graphicalViewer.setSelection(new StructuredSelection(toRefresh));
}
}
public void refresh(EditPart editPart, RefreshContext context) {
refresher.refresh(editPart, context);
getOutlinePage().refresh(editPart);
}
public EditPart getEditPart(Object model) {
return (EditPart) graphicalViewer.getEditPartRegistry().get(model);
}
private void setDocumentRoot(EObject document) {
this.documentRoot = document;
}
public EObject getDocumentRoot() {
return documentRoot;
}
/**
* Start loading models.
*/
private void tryToLoadModels() {
loadingFigureController.showLoadingFigure(true);
loadingFigureController.startListener(getGraphicalViewer());
UIJob setupJob = new UIJob("Setup") {
public IStatus runInUIThread(IProgressMonitor monitor) {
if (modelBuilder.doLoad(Designer.this, monitor)) {
setDocumentRoot(modelBuilder.getDiagram());
}
if (!isDisposed()) {
try {
setupGraphicalViewer();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return Status.OK_STATUS;
}
};
setupJob.setDisplay(display);
setupJob.setPriority(Job.SHORT);
final IModelBuilder modelBuilder = getModelBuilder();
if (getDocument() != null && modelBuilder != null) {
setupJob.schedule();
}
}
protected void runWithDialog(IRunnableWithProgress runnable) {
try {
ProgressMonitorDialog d = new ProgressMonitorDialog(getSite()
.getShell());
d.run(true, false, runnable);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void setupGraphicalViewer() {
IVisualRenderer vr = getVisualsRender();
if (vr != null) {
vr.createVisuals();
getEditDomain().setViewerData(getGraphicalViewer(),
IVisualRenderer.KEY, vr);
}
setContent(getDocumentRoot());
loadingFigureController.showLoadingFigure(false);
installed = true;
}
protected void setContent(EObject diagram) {
GraphicalViewer graphicalViewer = getGraphicalViewer();
if (graphicalViewer != null) {
EditPart diagramEp = getDiagramEditPart();
graphicalViewer.setContents(diagramEp);
if (diagramEp != null) {
refresher.refreshAsynchronous(diagramEp);
}
}
DesignerOutlinePage outlinePage = getOutlinePage();
if (outlinePage != null) {
outlinePage.setContents(diagram);
}
}
public IVisualRenderer getVisualsRender() {
if (visualsRender == null) {
visualsRender = createVisualsRender();
}
return visualsRender;
}
/**
* @return
*/
private EditPart getDiagramEditPart() {
return getEditPartFactory().createEditPart(
getGraphicalViewer().getRootEditPart(), getDocumentRoot());
}
public GraphicalViewer getGraphicalViewer() {
return graphicalViewer;
}
protected synchronized boolean isDisposed() {
return editDomain == null;
}
public IFile getFile() {
IEditorInput editorInput = getEditorInput();
return (IFile) editorInput.getAdapter(IFile.class);
}
/**
* @return the modelBuilder
*/
public IModelBuilder getModelBuilder() {
if (modelBuilder == null) {
modelBuilder = createModelBuilder();
}
if (modelBuilderListener == null) {
modelBuilderListener = new ModelChangeListener() {
public void notifyChanged(final Notification event) {
dispatchModelEvent(event);
}
};
}
if (!modelBuilder.hasListener(modelBuilderListener)) {
modelBuilder.addModelListener(modelBuilderListener);
}
return modelBuilder;
}
protected abstract IModelBuilder createModelBuilder();
/**
* Initialize and create actions.
*/
protected void createActions() {
if (actionGroup == null) {
actionGroup = new ActionGroup(this);
}
actionGroup.createActions();
}
/**
* Lazily creates and returns the action registry.
*
* @return the action registry
*/
public ActionRegistry getActionRegistry() {
if (actionRegistry == null)
actionRegistry = new ActionRegistry();
return actionRegistry;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.part.MultiPageEditorPart#createPageContainer(org.eclipse
* .swt.widgets.Composite)
*/
protected Composite createPageContainer(Composite parent) {
ViewForm diagramPart = new ViewForm(parent, SWT.FLAT);
ToolBar toolBar = createToolBar(diagramPart);
if (toolBar != null && !toolBar.isDisposed()) {
diagramPart.setTopLeft(toolBar);
}
pageContainer = new CustomSashForm(diagramPart, SWT.VERTICAL);
pageContainer.setBackgroundMode(SWT.INHERIT_DEFAULT);
createGraphicalViewer(pageContainer);
diagramPart.setContent(pageContainer);
return pageContainer;
}
protected boolean isEditable() {
return true;
}
/**
* Create Graphical Viewer for GEF Editor.
*
* @param parent
*/
private void createGraphicalViewer(Composite parent) {
graphicalViewer = new ScrollingGraphicalViewer();
graphicalViewer.createControl(parent);
graphicalViewer.getControl().setBackground(
ColorConstants.listBackground);
configureGraphicalViewer();
}
/**
* Configure GraphicalViewer
*/
protected void configureGraphicalViewer() {
graphicalViewer.addSelectionChangedListener(this);
editDomain.addViewer(graphicalViewer);
getSite().setSelectionProvider(graphicalViewer);
getSelectionSynchronizer().addProvider(graphicalViewer);
graphicalViewer.setEditPartFactory(getEditPartFactory());
ContextMenuProvider menuProvider = createMenuProvider(graphicalViewer,
getActionRegistry());
if (menuProvider != null) {
graphicalViewer.setContextMenu(menuProvider);
menuProvider.setRemoveAllWhenShown(true);
getSite()
.registerContextMenu(
getClass().getSimpleName() + ".contextMenu", menuProvider, graphicalViewer); //$NON-NLS-1$
}
DesignerRootEditPart rootEditPart = new DesignerRootEditPart();
graphicalViewer.setRootEditPart(rootEditPart);
graphicalViewer.setKeyHandler(new GraphicalViewerKeyHandler(
graphicalViewer).setParent(getCommonKeyHandler()));
setupGraphicalViewerDropCreation(graphicalViewer);
Iterator<?> actions = getActionRegistry().getActions();
while (actions.hasNext()) {
Object object = (Object) actions.next();
if (object instanceof SelectionAction) {
((SelectionAction) object)
.setSelectionProvider(graphicalViewer);
}
}
}
protected void setupGraphicalViewerDropCreation(GraphicalViewer viewer) {
viewer.addDropTargetListener(new GraphicalViewerDropCreationListener(
viewer));
}
/**
* Returns the KeyHandler with common bindings for both the Outline and
* Graphical Views. For example, delete is a common action.
*/
protected KeyHandler getCommonKeyHandler() {
if (fSharedKeyHandler == null) {
fSharedKeyHandler = new KeyHandler();
fSharedKeyHandler
.put(KeyStroke.getPressed(SWT.DEL, SWT.DEL, 0),
getActionRegistry().getAction(
ActionFactory.DELETE.getId()));
fSharedKeyHandler.put(KeyStroke.getPressed(SWT.F2, 0),
getActionRegistry().getAction(
GEFActionConstants.DIRECT_EDIT));
}
return fSharedKeyHandler;
}
protected ContextMenuProvider createMenuProvider(EditPartViewer viewer,
ActionRegistry actionRegistry) {
return new DesignerMenuProvider(viewer, actionRegistry);
}
/**
* Returns the selection syncronizer object. The synchronizer can be used to
* sync the selection of 2 or more EditPartViewers.
*
* @return
*/
public ISelectionSynchronizer getSelectionSynchronizer() {
if (selectionSynchronizer == null) {
selectionSynchronizer = createSelectionSynchronizer();
}
return selectionSynchronizer;
}
protected ISelectionSynchronizer createSelectionSynchronizer() {
return new SelectionSynchronizer();
}
/**
* Create a ToolBar for editor with global actions.
*
* @param parent
* @return
*/
protected ToolBar createToolBar(Composite parent) {
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.MultiPageEditorPart#createPages()
*/
protected void createPages() {
createSourcePage();
createExternalPages();
updateContainer();
}
/**
* Update TabFolder.
*/
private void updateContainer() {
Composite container = getContainer();
if (container == null || !(container instanceof CTabFolder)) {
return;
}
CTabFolder tabFolder = (CTabFolder) container;
tabFolder.setTabPosition(SWT.TOP);
tabFolder.setSimple(false);
ToolBar toolBar = new ToolBar(tabFolder, SWT.FLAT | SWT.WRAP
| SWT.RIGHT);
configureContainerToolBar(toolBar);
tabFolder.setTopRight(toolBar);
tabFolder.setTabHeight(Math.max(toolBar.computeSize(SWT.DEFAULT,
SWT.DEFAULT).y, tabFolder.getTabHeight()));
}
/**
* ToolBar of container, it is really at the middle of the editor.
*/
protected void configureContainerToolBar(ToolBar toolBar) {
}
protected void createExternalPages() {
}
/**
* Create and add a StructuredTextEditor as a Source Page.
*/
private void createSourcePage() {
// Subclass of StructuredTextEditor is not allowed.
fTextEditor = new StructuredTextEditor();
final StructuredTextUndoManager undoManager = new StructuredTextUndoManager(
commandStack);
TextFileDocumentProvider provider = new TextFileDocumentProvider() {
public IDocument getDocument(Object element) {
JobSafeStructuredDocument document = (JobSafeStructuredDocument) super
.getDocument(element);
if (document != null) {
try {
Field fUndoManager = BasicStructuredDocument.class
.getDeclaredField("fUndoManager");
fUndoManager.setAccessible(true);
Object object = fUndoManager.get(document);
if (object != null && object != undoManager) {
fUndoManager.set(document, null);
document.setUndoManager(undoManager);
} else if (object == null) {
document.setUndoManager(undoManager);
}
} catch (Exception e) {
DesignerPlugin.logError(e);
}
}
return document;
}
};
fTextEditor.initializeDocumentProvider(provider);
fTextEditor.setEditorPart(this);
if (fPropertyListener == null) {
fPropertyListener = new PropertyListener();
}
fTextEditor.addPropertyListener(fPropertyListener);
try {
int fSourcePageIndex = addPage(fTextEditor, getEditorInput());
setPageText(fSourcePageIndex, "Source");
firePropertyChange(PROP_TITLE);
tryToLoadModels();
} catch (PartInitException e) {
e.printStackTrace();
}
SourceSelectionProvider selectionProvider = new SourceSelectionProvider(
this, fTextEditor);
getSelectionSynchronizer().addProvider(selectionProvider);
fTextEditor.setAction(ITextEditorActionConstants.DELETE, null);
if (pageContainer != null) {
pageContainer.setWeights(new int[] { 1, 1 });
}
configureTextEditor();
}
protected IEditorSite createSite(IEditorPart editor) {
IEditorSite site = null;
if (editor == fTextEditor) {
site = new MultiPageEditorSite(this, editor) {
public String getId() {
// sets this id so nested editor is considered xml source
// page
return ContentTypeIdForXML.ContentTypeID_XML + ".source"; //$NON-NLS-1$;
}
};
} else {
site = super.createSite(editor);
}
return site;
}
/**
* Configure Text Editor,
*/
protected void configureTextEditor() {
if (getPalettePage() == null) {
return;
}
if (dropListener == null) {
dropListener = new DropTargetAdapter();
DropContext dropContext = getDropContext();
if (dropContext != null) {
dropListener.addDropAdapter(new PaletteDropAdapter(this,
dropContext));
}
}
StyledText styledText = getTextWidget();
if (styledText == null || dropListener == null) {
return;
}
DropTarget dropTarget = (DropTarget) styledText
.getData(DND.DROP_TARGET_KEY);
if (dropTarget != null) {
dropTarget.removeDropListener(dropListener);
dropTarget.dispose();
}
dropTarget = new DropTarget(styledText, DND.DROP_MOVE | DND.DROP_COPY);
dropTarget.setTransfer(new Transfer[] { getPalettePage()
.getPaletteTransfer() });
dropTarget.addDropListener(dropListener);
styledText.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
StyledText styledText = (StyledText) e.widget;
DropTarget dropTarget = (DropTarget) styledText
.getData(DND.DROP_TARGET_KEY);
if (dropTarget != null) {
dropTarget.removeDropListener(dropListener);
}
}
});
getProblemHandler().handle();
}
public void format() {
StructuredTextViewer textViewer = getTextViewer();
if (textViewer != null
&& textViewer
.canDoOperation(StructuredTextViewer.FORMAT_DOCUMENT)) {
textViewer.doOperation(StructuredTextViewer.FORMAT_DOCUMENT);
} else if (getDocument() != null) {
StructuredTextHelper.format(getDocument());
}
}
public void formatWithCompound(Runnable runnable) {
if (runnable == null) {
format();
return;
}
StructuredTextViewer textViewer = getTextViewer();
if (textViewer == null) {
runnable.run();
return;
}
IRewriteTarget rewriteTarget = textViewer.getRewriteTarget();
if (rewriteTarget != null) {
rewriteTarget.beginCompoundChange();
}
runnable.run();
format();
if (rewriteTarget != null) {
rewriteTarget.endCompoundChange();
}
}
public StyledText getTextWidget() {
if (getTextViewer() != null) {
return getTextViewer().getTextWidget();
}
return null;
}
public StructuredTextViewer getTextViewer() {
if (fTextEditor != null) {
return fTextEditor.getTextViewer();
}
return null;
}
public IDocument getDocument() {
IDocument document = null;
if (fTextEditor != null) {
IDocumentProvider documentProvider = fTextEditor
.getDocumentProvider();
IEditorInput editorInput = fTextEditor.getEditorInput();
if (documentProvider == null || editorInput == null) {
return null;
}
document = documentProvider.getDocument(editorInput);
}
return document;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.
* IProgressMonitor)
*/
public void doSave(IProgressMonitor monitor) {
fTextEditor.doSave(monitor);
if (modelBuilder != null) {
modelBuilder.doSave(monitor);
}
// getCommandStack().flush();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.EditorPart#doSaveAs()
*/
public void doSaveAs() {
fTextEditor.doSaveAs();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.MultiPageEditorPart#dispose()
*/
public void dispose() {
getModelBuilder().removeModelListener(modelBuilderListener);
getModelBuilder().dispose();
getCommandStack().getCommandStack4GEF()
.removeCommandStackListener(this);
getCommandStack().flush();
getGraphicalViewer().removeSelectionChangedListener(this);
if (modelBuilder != null) {
modelBuilder.dispose();
}
if (visualsRender != null) {
visualsRender.dispose();
}
fSharedKeyHandler = null;
getActionRegistry().dispose();
getProblemHandler().clear();
super.dispose();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.MultiPageEditorPart#getAdapter(java.lang.Class)
*/
public Object getAdapter(Class adapter) {
if (ActionRegistry.class == adapter) {
return getActionRegistry();
} else if (org.eclipse.gef.EditDomain.class.isAssignableFrom(adapter)) {
return getEditDomain();
} else if (PalettePage.class.isAssignableFrom(adapter)) {
return getPalettePage();
} else if (CommandStack.class == adapter) {
return getCommandStack().getCommandStack4GEF();
} else if (GraphicalViewer.class == adapter) {
return getGraphicalViewer();
} else if (adapter == IPropertySheetPage.class) {
return getPropertySheetPage();
} else if (adapter == IContentOutlinePage.class) {
return getOutlinePage();
} else if (adapter == ProblemHandler.class) {
return getProblemHandler();
} else if (adapter == EditPart.class && getGraphicalViewer() != null) {
return getGraphicalViewer().getRootEditPart();
} else if (adapter == IFigure.class && getGraphicalViewer() != null) {
return ((GraphicalEditPart) getGraphicalViewer().getRootEditPart())
.getFigure();
} else if (adapter == IProject.class) {
return getProject();
} else if (adapter == IFile.class) {
return getFile();
}
return super.getAdapter(adapter);
}
public ProblemHandler getProblemHandler() {
if (problemHandler == null) {
problemHandler = new ConfigurableProblemHandler(this);
}
return problemHandler;
}
/**
* @return
*/
protected DesignerOutlinePage getOutlinePage() {
if (outlinePage == null) {
outlinePage = createOutlinePage();
if (outlinePage != null) {
getSelectionSynchronizer().addProvider(
outlinePage.getTreeViewer());
}
}
return outlinePage;
}
protected abstract DesignerOutlinePage createOutlinePage();
public IPropertySheetPage getPropertySheetPage() {
if (propertyPage == null || propertyPage.getControl() == null
|| propertyPage.getControl().isDisposed()) {
propertyPage = createPropertyPage();
}
return propertyPage;
}
protected IPropertySheetPage createPropertyPage() {
return new PropertySheetPage();
}
/**
* @return
*/
private CustomPalettePage getPalettePage() {
if (palettePage == null) {
palettePage = new ContributePalettePage(this, editDomain);
}
return palettePage;
}
public CombinedCommandStack getCommandStack() {
return commandStack;
}
/**
* @return the editDomain
*/
public EditDomain getEditDomain() {
return editDomain;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
*/
public boolean isSaveAsAllowed() {
return fTextEditor.isSaveAsAllowed();
}
protected EditPart convert(EditPartViewer viewer, EditPart part) {
Object temp = viewer.getEditPartRegistry().get(part.getModel());
EditPart newPart = null;
if (temp != null) {
newPart = (EditPart) temp;
}
return newPart;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(
* org.eclipse.jface.viewers.SelectionChangedEvent)
*/
public final void selectionChanged(SelectionChangedEvent event) {
Object source = event.getSource();
if (source == null) {
return;
}
while (Display.getDefault().readAndDispatch())
;
IEditorPart activeEditor = getSite().getPage().getActiveEditor();
if (Designer.this.equals(activeEditor)) {
performSelectionChanged(event);
}
}
/**
* Perform Selection event.
*
* @param event
*/
protected void performSelectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
if (selection.isEmpty()) {
return;
}
DisplayUtil.asyncExec(new Runnable() {
public void run() {
if (actionGroup != null) {
actionGroup.updateActions(ActionGroup.SELECTION_GRP);
}
ActionRegistry actionRegistry = getActionRegistry();
Iterator<?> actions = actionRegistry.getActions();
while (actions.hasNext()) {
Object object = (Object) actions.next();
if (object instanceof SelectionAction) {
((SelectionAction) object).update();
}
}
}
});
}
public void gotoDefinition(EObject node) {
EditPart editPart = getEditPart(node);
if (editPart != null) {
graphicalViewer.setSelection(new StructuredSelection(editPart));
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.commands.CommandStackListener#commandStackChanged(java
* .util.EventObject)
*/
public void commandStackChanged(EventObject event) {
if (actionGroup != null) {
actionGroup.updateActions(ActionGroup.STACK_GRP);
}
}
public StructuredTextEditor getTextEditor() {
return fTextEditor;
}
/*
* This method is just to make firePropertyChanged accessible from some
* (anonomous) inner classes.
*/
void _firePropertyChange(int property) {
super.firePropertyChange(property);
}
public IProject getProject() {
return getFile().getProject();
}
/**
* EditPart Factory.
*
* @return
*/
public EditPartFactory getEditPartFactory() {
if (editPartFactory == null) {
editPartFactory = createEditPartFactory();
}
return editPartFactory;
}
protected abstract EditPartFactory createEditPartFactory();
protected abstract IVisualRenderer createVisualsRender();
/**
* DropContext.
*
* @return
*/
protected abstract DropContext getDropContext();
/**
* Internal IPropertyListener
*/
class PropertyListener implements IPropertyListener {
public void propertyChanged(Object source, int propId) {
switch (propId) {
// had to implement input changed "listener" so that
// StructuredTextEditor could tell it containing editor that
// the input has change, when a 'resource moved' event is
// found.
case IEditorPart.PROP_INPUT: {
}
case IEditorPart.PROP_DIRTY: {
if (source == getTextEditor()) {
if (getTextEditor().getEditorInput() != getEditorInput()) {
setInput(getTextEditor().getEditorInput());
/*
* title should always change when input changes. create
* runnable for following post call
*/
Runnable runnable = new Runnable() {
public void run() {
_firePropertyChange(IWorkbenchPart.PROP_TITLE);
}
};
/*
* Update is just to post things on the display queue
* (thread). We have to do this to get the dirty
* property to get updated after other things on the
* queue are executed.
*/
((Control) getTextEditor().getAdapter(Control.class))
.getDisplay().asyncExec(runnable);
}
}
break;
}
case IWorkbenchPart.PROP_TITLE: {
// update the input if the title is changed
if (source == getTextEditor()) {
if (getTextEditor().getEditorInput() != getEditorInput()) {
setInput(getTextEditor().getEditorInput());
}
}
break;
}
default: {
// propagate changes. Is this needed? Answer: Yes.
if (source == getTextEditor()) {
_firePropertyChange(propId);
}
break;
}
}
}
}
}