| /******************************************************************************* |
| * Copyright (c) 2004, 2005 Sybase, Inc. 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: |
| * Sybase, Inc. - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.jst.jsf.facesconfig.ui.pageflow; |
| |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceChangeEvent; |
| import org.eclipse.core.resources.IResourceChangeListener; |
| import org.eclipse.core.resources.IResourceDelta; |
| import org.eclipse.core.resources.IResourceDeltaVisitor; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.draw2d.PositionConstants; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.gef.ContextMenuProvider; |
| import org.eclipse.gef.DefaultEditDomain; |
| import org.eclipse.gef.EditPart; |
| 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.RootEditPart; |
| import org.eclipse.gef.commands.CommandStack; |
| import org.eclipse.gef.commands.CommandStackEvent; |
| import org.eclipse.gef.commands.CommandStackEventListener; |
| import org.eclipse.gef.editparts.ScalableFreeformRootEditPart; |
| import org.eclipse.gef.editparts.ScalableRootEditPart; |
| import org.eclipse.gef.editparts.ZoomManager; |
| import org.eclipse.gef.palette.PaletteRoot; |
| import org.eclipse.gef.requests.CreationFactory; |
| import org.eclipse.gef.ui.actions.ActionRegistry; |
| import org.eclipse.gef.ui.actions.DeleteAction; |
| import org.eclipse.gef.ui.actions.GEFActionConstants; |
| import org.eclipse.gef.ui.actions.RedoAction; |
| import org.eclipse.gef.ui.actions.SelectionAction; |
| import org.eclipse.gef.ui.actions.StackAction; |
| import org.eclipse.gef.ui.actions.UndoAction; |
| import org.eclipse.gef.ui.actions.UpdateAction; |
| import org.eclipse.gef.ui.actions.ZoomInAction; |
| import org.eclipse.gef.ui.actions.ZoomOutAction; |
| import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette; |
| import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler; |
| import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; |
| import org.eclipse.gef.ui.parts.SelectionSynchronizer; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.preference.PreferenceConverter; |
| import org.eclipse.jface.resource.FontRegistry; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.util.TransferDropTargetListener; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jst.jsf.common.ui.internal.logging.Logger; |
| import org.eclipse.jst.jsf.facesconfig.ui.EditorPlugin; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.action.AlignmentAction; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.action.OpenEditorAction; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.action.ShowPropertyViewAction; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.command.PreExecuteCommandStack; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.ConfigurableRootEditPart; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.IConnectionPreference; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.IFigurePreference; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.ILayerPanePreference; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.INodePreference; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.PageflowEditPartsFactory; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.editpart.PageflowNodeEditPart; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.Pageflow; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.model.PageflowPage; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.synchronization.FC2PFTransformer; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.EditPartMarkerUtil; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.PageflowAnnotationUtil; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.PageflowModelManager; |
| import org.eclipse.jst.jsf.facesconfig.ui.pageflow.util.PageflowResourceFactory; |
| import org.eclipse.jst.jsf.facesconfig.ui.preference.GEMPreferences; |
| import org.eclipse.jst.jsf.facesconfig.ui.util.WebrootUtil; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.FontData; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IEditorSite; |
| import org.eclipse.ui.ISelectionListener; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.actions.ActionFactory; |
| import org.eclipse.ui.ide.IGotoMarker; |
| import org.eclipse.ui.part.FileEditorInput; |
| import org.eclipse.ui.plugin.AbstractUIPlugin; |
| import org.eclipse.ui.views.contentoutline.IContentOutlinePage; |
| import org.eclipse.ui.views.properties.IPropertySheetPage; |
| import org.eclipse.ui.views.properties.PropertySheetPage; |
| |
| /** |
| * This the the main editor page for modifying a complete pageflow. |
| */ |
| public class PageflowEditor extends GraphicalEditorWithFlyoutPalette implements |
| IAdaptable, IPropertyChangeListener, IGotoMarker { |
| /** log instance */ |
| private static final Logger log = EditorPlugin |
| .getLogger(PageflowEditor.class); |
| |
| /** pageflow context menu registration ID */ |
| private static final String PAGEFLOW_CONTEXTMENU_REG_ID = ".pageflow.editor.contextmenu"; |
| |
| /** the edit domain */ |
| private final DefaultEditDomain domain; |
| |
| /** the palette root */ |
| private PaletteRoot paletteRoot = null; |
| |
| /** the parent multi-page editor */ |
| private IEditorPart parentEditor = null; |
| |
| /** the graphical viewer */ |
| private GraphicalViewer viewer = null; |
| |
| /** the undoable <code>IPropertySheetPage</code> */ |
| private PropertySheetPage undoablePropertySheetPage = null; |
| |
| /** the editor's action registry */ |
| private ActionRegistry actionRegistry = null; |
| |
| /** |
| * The id of the editor page |
| */ |
| public static final String PAGE_ID = "org.eclipse.jst.jsf.facesconfig.ui.pageflow.PageflowEditor"; |
| |
| /** the list of action ids that are to EditPart actions */ |
| private List editPartActionIDs = new ArrayList(); |
| |
| /** the selection listener */ |
| private ISelectionListener selectionListener = new ISelectionListener() { |
| public void selectionChanged(IWorkbenchPart part, ISelection selection) { |
| updateActions(); |
| } |
| }; |
| |
| /** the selection synchronizer for the edit part viewer */ |
| private SelectionSynchronizer synchronizer = null; |
| |
| /** the shared key handler */ |
| private KeyHandler sharedKeyHandler = null; |
| |
| /** pageflow model manager */ |
| private PageflowModelManager pageflowManager; |
| |
| /** the dirty status of this page */ |
| private boolean isDirty = false; |
| |
| /** the command stack of this page */ |
| private CommandStack commandStack; |
| |
| private FC2PFTransformer modelsTransform; |
| |
| List stackActions = new ArrayList(); |
| |
| /** |
| * @return the faces-config to pageflow model |
| */ |
| public FC2PFTransformer getModelsTransform() { |
| if (modelsTransform == null) { |
| modelsTransform = new FC2PFTransformer(); |
| } |
| return modelsTransform; |
| } |
| |
| /** |
| * update the editor actions |
| */ |
| public void updateActions() { |
| updateActions(stackActions); |
| updateActions(editPartActionIDs); |
| } |
| |
| /** |
| * This class listens for command stack changes of the page and decides if |
| * the editor is dirty or not. |
| * |
| */ |
| private class PageCommandStackListener implements CommandStackEventListener { |
| public void stackChanged(CommandStackEvent event) { |
| if (((CommandStack) event.getSource()).isDirty()) { |
| // at least one command stack is dirty, |
| // so the multi page editor is dirty too |
| setDirty(true); |
| } |
| updateActions(); |
| } |
| } |
| |
| /** |
| * This class listens to changes to the file system in the workspace, and |
| * validate the current pageflow based on web files' status. |
| */ |
| private class ResourceTracker implements IResourceChangeListener, |
| IResourceDeltaVisitor { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) |
| */ |
| public void resourceChanged(IResourceChangeEvent event) { |
| IResourceDelta delta = event.getDelta(); |
| try { |
| if (delta != null) { |
| delta.accept(this); |
| } |
| } catch (CoreException exception) { |
| // Pageflow.PageflowEditor.Error.ResourceChange = Failed in the |
| // resource change. |
| log.error("Pageflow.PageflowEditor.Error.ResourceChange", |
| exception); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) |
| */ |
| public boolean visit(IResourceDelta delta) { |
| // if the delta is not a file instance, just return true |
| if (!(delta.getResource() instanceof IFile)) { |
| return true; |
| } |
| |
| // web file is changed. |
| if (WebrootUtil.isValidWebFile(((IFile) delta.getResource()) |
| .getFullPath())) { |
| webPageChanged(((IFile) delta.getResource()).getFullPath()); |
| return false; |
| } |
| return false; |
| } |
| } |
| |
| /** the resource tracker instance */ |
| private ResourceTracker resourceTracker = null; |
| |
| /** |
| * Returns the resource tracker instance |
| * |
| * @return - Returns the resource tracker instance |
| */ |
| private ResourceTracker getResourceTracker() { |
| if (null == resourceTracker) { |
| resourceTracker = new ResourceTracker(); |
| } |
| return resourceTracker; |
| } |
| |
| /** |
| * Changes the dirty state. |
| * |
| * @param dirty - |
| * dirty state |
| */ |
| protected void setDirty(boolean dirty) { |
| if (isDirty != dirty) { |
| isDirty = dirty; |
| } |
| } |
| |
| /** |
| * Updates the specified actions. |
| * |
| * @param actionIds - |
| * the list of ids of actions to update |
| */ |
| protected void updateActions(List actionIds) { |
| for (Iterator ids = actionIds.iterator(); ids.hasNext();) { |
| IAction action = getActionRegistry().getAction(ids.next()); |
| if (null != action && action instanceof UpdateAction) { |
| ((UpdateAction) action).update(); |
| } |
| } |
| } |
| |
| /** |
| * Creates a new PageflowPage instance. |
| * <p> |
| * By design this page uses its own <code>EditDomain</code>. The main |
| * goal of this approach is that this page has its own undo/redo command |
| * stack. |
| * |
| * @param parent - |
| * the parent multi page editor |
| */ |
| public PageflowEditor(IEditorPart parent) { |
| domain = new DefaultEditDomain(parent); |
| domain.setCommandStack(getCommandStack()); |
| this.setEditDomain(domain); |
| parentEditor = parent; |
| } |
| |
| /** |
| * Adds an <code>CommandStack</code> action to this editor. |
| * <p> |
| * <code>CommandStack</code> actions are actions that depend and work on |
| * the <code>CommandStack</code>. |
| * |
| * @param action - |
| * the <code>CommandStack</code> action |
| */ |
| protected void addStackAction(StackAction action) { |
| getActionRegistry().registerAction(action); |
| stackActions.add(action.getId()); |
| } |
| |
| /** |
| * Creates different kinds of actions and registers them to the |
| * ActionRegistry. |
| */ |
| protected void createActions() { |
| // register delete action |
| addEditPartAction(new DeleteAction((IWorkbenchPart) this)); |
| // register undo/redo action |
| addStackAction(new UndoAction(this)); |
| addStackAction(new RedoAction(this)); |
| |
| // Allows opening of JSP files from the pageflow |
| addEditPartAction(new OpenEditorAction(this)); |
| |
| // Allows showing property view for the pageflow |
| SelectionAction action = new ShowPropertyViewAction(this); |
| action |
| .setImageDescriptor(getImageDescriptorForView("org.eclipse.ui.views.PropertySheet")); |
| addEditPartAction(action); |
| // Allows showing property view for the pageflow |
| // addEditPartAction(new ShowPaletteViewAction((IWorkbenchPart) this)); |
| |
| // register alignment actions |
| addEditPartAction(new AlignmentAction((IWorkbenchPart) this, |
| PositionConstants.LEFT)); |
| addEditPartAction(new AlignmentAction((IWorkbenchPart) this, |
| PositionConstants.RIGHT)); |
| addEditPartAction(new AlignmentAction((IWorkbenchPart) this, |
| PositionConstants.TOP)); |
| addEditPartAction(new AlignmentAction((IWorkbenchPart) this, |
| PositionConstants.BOTTOM)); |
| addEditPartAction(new AlignmentAction((IWorkbenchPart) this, |
| PositionConstants.CENTER)); |
| addEditPartAction(new AlignmentAction((IWorkbenchPart) this, |
| PositionConstants.MIDDLE)); |
| |
| // register zoom in/out action |
| IAction zoomIn = new ZoomInAction(getZoomManager(getGraphicalViewer())); |
| IAction zoomOut = new ZoomOutAction( |
| getZoomManager(getGraphicalViewer())); |
| addAction(zoomIn); |
| addAction(zoomOut); |
| |
| // getSite().getKeyBindingService().registerAction(zoomIn); |
| // getSite().getKeyBindingService().registerAction(zoomOut); |
| } |
| |
| /** |
| * Returns the zoom manager of the specified viewer. |
| * |
| * @param viewer_ - |
| * the viewer to get the zoom manager from |
| * @return - the zoom manager |
| */ |
| private ZoomManager getZoomManager(GraphicalViewer viewer_) { |
| // get zoom manager from root edit part |
| RootEditPart rootEditPart = viewer_.getRootEditPart(); |
| ZoomManager zoomManager = null; |
| if (rootEditPart instanceof ScalableFreeformRootEditPart) { |
| zoomManager = ((ScalableFreeformRootEditPart) rootEditPart) |
| .getZoomManager(); |
| } else if (rootEditPart instanceof ScalableRootEditPart) { |
| zoomManager = ((ScalableRootEditPart) rootEditPart) |
| .getZoomManager(); |
| } |
| return zoomManager; |
| } |
| |
| /** |
| * Adds an action to this editor's <code>ActionRegistry</code>. |
| * |
| * @param action - |
| * the action to add. |
| */ |
| protected void addAction(IAction action) { |
| getActionRegistry().registerAction(action); |
| } |
| |
| /** |
| * Adds an <code>EditPart</code> action to this editor. |
| * <p> |
| * <code>EditPart</code> actions are actions that depend and work on the |
| * selected <code>EditPart</code>s. |
| * |
| * @param action - |
| * the <code>EditPart</code> action |
| */ |
| protected void addEditPartAction(SelectionAction action) { |
| getActionRegistry().registerAction(action); |
| editPartActionIDs.add(action.getId()); |
| } |
| |
| /** |
| * Returns the action registry of this editor. |
| * |
| * @return - the action registry |
| */ |
| public ActionRegistry getActionRegistry() { |
| if (null == actionRegistry) { |
| actionRegistry = new ActionRegistry(); |
| } |
| |
| return actionRegistry; |
| } |
| |
| /** |
| * Creates the GraphicalViewer on the specified <code>Composite</code>. |
| * |
| * @param parent - |
| * the parent composite |
| */ |
| public void createGraphicalViewer(Composite parent) { |
| viewer = new ScrollingGraphicalViewer(); |
| viewer.createControl(parent); |
| |
| // configure the viewer |
| viewer.getControl().setBackground(parent.getBackground()); |
| |
| viewer.setRootEditPart(new ConfigurableRootEditPart()); |
| // _viewer.setRootEditPart(new ScalableFreeformRootEditPart()); |
| viewer.setKeyHandler(new GraphicalViewerKeyHandler(viewer)); |
| |
| // hook the viewer into the editor |
| registerEditPartViewer(viewer); |
| |
| // configure the viewer with context menu and template drag and drop |
| configureEditPartViewer(viewer); |
| |
| // initialize the viewer with input |
| viewer.setEditPartFactory(new PageflowEditPartsFactory()); |
| // viewer.setContents(getPageflow()); |
| |
| // support the resource drag&drop |
| viewer |
| .addDropTargetListener((TransferDropTargetListener) new ResourceTransferDropTargetListener( |
| viewer, getParentEditor()) { |
| protected CreationFactory getFactory(Object obj) { |
| return getResourceFactory((IResource) obj); |
| } |
| }); |
| |
| // apply Editor's preferences |
| // propertyChange(null); |
| // add listener to Editor's preferences changing |
| EditorPlugin.getDefault().getPreferenceStore() |
| .addPropertyChangeListener(this); |
| } |
| |
| private CreationFactory getResourceFactory(IResource resource) { |
| return new PageflowResourceFactory(resource); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public final void doSave(IProgressMonitor monitor) { |
| // our policy: delegate saving to the parent |
| getParentEditor().doSave(monitor); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see ISaveablePart#doSaveAs() |
| */ |
| public final void doSaveAs() { |
| // our policy: delegate saving to the parent |
| getParentEditor().doSaveAs(); |
| } |
| |
| /** |
| * Saves the pageflow under the specified path. |
| * @param file |
| * |
| * @param progressMonitor |
| * @throws CoreException |
| */ |
| public void doSave(IFile file, IProgressMonitor progressMonitor) |
| throws CoreException { |
| if (((FileEditorInput) getEditorInput()).getFile() != file) { |
| // TODO: save to other page. |
| } |
| if (null == progressMonitor) { |
| progressMonitor = new NullProgressMonitor(); |
| } |
| // Pageflow.Label.Saving = Saving |
| progressMonitor.beginTask(PageflowMessages.Pageflow_Label_Saving + " " |
| + file.getFullPath(), 2); |
| |
| if (null == getPageflowManager()) { |
| // Pageflow.PageflowEditor.Alert.nullModelManager = No model manager |
| // found for saving the file. |
| EditorPlugin.getAlerts().throwCoreException( |
| "Pageflow.PageflowEditor.Alert.nullModelManager"); |
| } |
| |
| // save pageflow to file |
| try { |
| getPageflowManager().save(getPageflowFilePath(file)); |
| |
| progressMonitor.worked(1); |
| file.refreshLocal(IResource.DEPTH_ZERO, new SubProgressMonitor( |
| progressMonitor, 1)); |
| progressMonitor.done(); |
| setDirty(false); |
| } catch (FileNotFoundException e) { |
| // Pageflow.PageflowEditor.Alert.errorSaveFileInfo = The current |
| // pageflow model could not be saved. |
| EditorPlugin.getAlerts().throwCoreException(e); |
| } catch (IOException e) { |
| // Pageflow.PageflowEditor.Alert.errorSaveFileInfo = The current |
| // pageflow model could not be saved. |
| EditorPlugin.getAlerts().throwCoreException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see IEditorPart#init(org.eclipse.ui.IEditorSite, |
| * org.eclipse.ui.IEditorInput) |
| */ |
| public void init(IEditorSite site, IEditorInput input) |
| throws PartInitException { |
| setSite(site); |
| setInput(input); |
| IFile fileFacesConfig = null; |
| try { |
| fileFacesConfig = ((FileEditorInput) input).getFile(); |
| |
| // load and validate pageflow |
| if (null == createPageflow(getPageflowFilePath(fileFacesConfig))) { |
| // Pageflow.PageflowEditor.Error.invalidPageflowFile = The |
| // specified input is not a valid pageflow. |
| log.error("Pageflow.PageflowEditor.Error.invalidPageflowFile"); |
| throw new PartInitException( |
| EditorPlugin |
| .getResourceString("Pageflow.PageflowEditor.Error.invalidPageflowFile")); |
| } |
| |
| } catch (CoreException e) { |
| // Pageflow.PageflowEditor.Error.invalidPageflowFile = The specified |
| // input is not a valid pageflow. |
| log.error("Pageflow.PageflowEditor.Error.invalidPageflowFile", e); |
| throw new PartInitException(e.getStatus()); |
| } catch (IOException e) { |
| // Pageflow.PageflowEditor.Alert.errorSaveFileInfo = The current |
| // pageflow model could not be saved. |
| log.error("Pageflow.PageflowEditor.Alert.errorSaveFileInfo", e); |
| } |
| |
| // add selection change listener |
| getSite().getWorkbenchWindow().getSelectionService() |
| .addSelectionListener(getSelectionListener()); |
| |
| // Add resource change listener |
| fileFacesConfig.getWorkspace().addResourceChangeListener( |
| getResourceTracker()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.IWorkbenchPart#dispose() |
| */ |
| public void dispose() { |
| // remove selection change listener |
| getModelsTransform().dispose(); |
| getSite().getWorkbenchWindow().getSelectionService() |
| .removeSelectionListener(getSelectionListener()); |
| |
| // remove listener to Editor's preferences changing |
| EditorPlugin.getDefault().getPreferenceStore() |
| .removePropertyChangeListener(this); |
| |
| if (getEditorInput() != null) { |
| IFile file = (IFile) getEditorInput().getAdapter(IResource.class); |
| if (file != null) { |
| file.getWorkspace().removeResourceChangeListener( |
| getResourceTracker()); |
| } |
| } |
| super.dispose(); |
| } |
| |
| /** |
| * get the pageflow file path based on faces-config.xml file path |
| * |
| * @return |
| */ |
| private IPath getPageflowFilePath(IFile file) { |
| IPath pageflowFilePath; |
| pageflowFilePath = PageflowModelManager.makePageflowPath(file |
| .getFullPath()); |
| return pageflowFilePath; |
| } |
| |
| /** |
| * Returns the pageflow object from the specified file. |
| * |
| * @param file - |
| * the file resource |
| * @return -the pageflow object from the specified file |
| * @throws IOException |
| */ |
| private Pageflow createPageflow(IPath pathPageflow) throws CoreException, |
| IOException { |
| Pageflow pageflow = null; |
| |
| try { |
| getPageflowManager().load(pathPageflow); |
| } catch (Exception e) { |
| // Pageflow.PageflowEditor.Error.invalidPageflowFile = The specified |
| // input is not a valid pageflow. |
| // _log.error("Pageflow.PageflowEditor.Error.invalidPageflowFile", |
| // e); |
| getPageflowManager().createPageflow(pathPageflow); |
| } |
| IFile fileFacesConfig = ((FileEditorInput) getEditorInput()).getFile(); |
| // it should update related config file |
| if (!fileFacesConfig.getFullPath().toString().trim().equalsIgnoreCase( |
| getPageflowManager().getModel().getConfigfile())) { |
| getPageflowManager().getModel().setConfigfile( |
| fileFacesConfig.getFullPath().toString()); |
| getPageflowManager().save(pathPageflow); |
| } |
| pageflow = getPageflowManager().getModel(); |
| if (null == pageflow) { |
| // Pageflow.PageflowEditor.Error.invalidPageflowModel = The model in |
| // the pageflow file is not a valid pageflow model. |
| log.error("Pageflow.PageflowEditor.Error.invalidPageflowModel"); |
| EditorPlugin.getAlerts().throwCoreException( |
| "Pageflow.PageflowEditor.Error.invalidPageflowModel"); |
| } |
| return pageflow; |
| } |
| |
| /** get the pageflow manager for this page |
| * @return the model manager |
| */ |
| public PageflowModelManager getPageflowManager() { |
| if (pageflowManager == null) { |
| pageflowManager = new PageflowModelManager(); |
| } |
| return pageflowManager; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see ISaveablePart#isDirty() |
| */ |
| public final boolean isDirty() { |
| return isDirty; |
| } |
| |
| /** |
| * Returns the <code>CommandStack</code> of this editor page. |
| * |
| * @return - the <code>CommandStack</code> of this editor page |
| */ |
| public final CommandStack getCommandStack() { |
| if (commandStack == null) { |
| commandStack = new PreExecuteCommandStack(); |
| commandStack |
| .addCommandStackEventListener(new PageCommandStackListener()); |
| } |
| return commandStack; |
| } |
| |
| /** |
| * Returns the default <code>PaletteRoot</code> for this editor and all |
| * its pages. |
| * |
| * @return - the default <code>PaletteRoot</code> |
| */ |
| protected PaletteRoot getPaletteRoot() { |
| if (null == paletteRoot) { |
| // create root |
| paletteRoot = new PageflowPaletteRoot(); |
| } |
| return paletteRoot; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see ISaveablePart#isSaveAsAllowed() |
| */ |
| public final boolean isSaveAsAllowed() { |
| // our policy: delegate saving to the parent |
| return getParentEditor().isSaveAsAllowed(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see IWorkbenchPart#setFocus() |
| */ |
| public void setFocus() { |
| getGraphicalViewer().getControl().setFocus(); |
| } |
| |
| /** |
| * Returns the multi page pageflow editor this editor page is contained in. |
| * |
| * @return - the parent multi page editor |
| */ |
| protected final IEditorPart getParentEditor() { |
| return parentEditor; |
| } |
| |
| /** |
| * Returns the edit domain this editor page uses. |
| * |
| * @return - the edit domain this editor page uses |
| */ |
| public final DefaultEditDomain getEditDomain() { |
| return domain; |
| } |
| |
| /** |
| * Hooks a <code>EditPartViewer</code> to the rest of the Editor. |
| * <p> |
| * By default, the viewer is added to the SelectionSynchronizer, which can |
| * be used to keep 2 or more EditPartViewers in sync. The viewer is also |
| * registered as the ISelectionProvider for the Editor's PartSite. |
| * |
| * @param viewer_ - |
| * the viewer to hook into the editor |
| */ |
| protected void registerEditPartViewer(EditPartViewer viewer_) { |
| // register viewer to edit domain |
| getEditDomain().addViewer(viewer_); |
| |
| // the multi page pageflow editor keeps track of synchronizing |
| getSelectionSynchronizer().addViewer(viewer_); |
| |
| // add viewer as selection provider |
| getSite().setSelectionProvider(viewer_); |
| } |
| |
| /** |
| * Configures the specified <code>EditPartViewer</code> including context |
| * menu, key handler, etc. |
| * |
| * @param viewer_ - |
| * the pageflow graphical viewer. |
| */ |
| protected void configureEditPartViewer(EditPartViewer viewer_) { |
| // configure the shared key handler |
| if (null != viewer_.getKeyHandler()) { |
| viewer_.getKeyHandler().setParent(getSharedKeyHandler()); |
| } |
| // create the ActionRegistry |
| createActions(); |
| |
| // append the parent editor's action registry. |
| ActionRegistry actionRegistry_ = (ActionRegistry) getParentEditor() |
| .getAdapter(ActionRegistry.class); |
| if (actionRegistry_ != null) { |
| for (Iterator iter = actionRegistry_.getActions(); iter.hasNext();) { |
| getActionRegistry().registerAction((IAction) iter.next()); |
| } |
| } |
| // configure and register the context menu |
| ContextMenuProvider provider = new PageflowEditorContextMenuProvider( |
| viewer_, getActionRegistry()); |
| viewer_.setContextMenu(provider); |
| getSite().registerContextMenu( |
| EditorPlugin.getPluginId() + PAGEFLOW_CONTEXTMENU_REG_ID, |
| provider, getSite().getSelectionProvider()); //$NON-NLS-1$ |
| |
| // enable viewer as drop target for template transfers |
| viewer_ |
| .addDropTargetListener((TransferDropTargetListener) new PageflowTemplateTransferDropTargetListener( |
| viewer_)); |
| |
| } |
| |
| /** |
| * Returns the pageflow that is edited. |
| * |
| * @return - the pageflow that is edited |
| */ |
| public Pageflow getPageflow() { |
| return getPageflowManager().getModel(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see AbstractEditorPage#getGraphicalViewerForZoomSupport() |
| */ |
| public GraphicalViewer getGraphicalViewer() { |
| return viewer; |
| } |
| |
| /** |
| * @param contents |
| */ |
| public void setGraphicalViewerContents(Object contents) { |
| viewer.setContents(contents); |
| propertyChange(null); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see IAdaptable#getAdapter(Class) |
| */ |
| public Object getAdapter(Class type) { |
| if (type == IContentOutlinePage.class) { |
| return getOutlinePage(); |
| } else if (type == CommandStack.class) { |
| return getCommandStack(); |
| } else if (type == ActionRegistry.class) { |
| return getActionRegistry(); |
| } else if (type == IPropertySheetPage.class) { |
| return getPropertySheetPage(); |
| } else if (type == ZoomManager.class) { |
| return getZoomManager(getGraphicalViewer()); |
| } |
| return super.getAdapter(type); |
| } |
| |
| /** |
| * Returns the outline page for the outline view with lazy creation |
| * |
| * @return - the outline page |
| */ |
| protected PageflowEditorOutlinePage getOutlinePage() { |
| PageflowEditorOutlinePage outlinePage = new PageflowEditorOutlinePage( |
| this); |
| outlinePage.initialize(this); |
| return outlinePage; |
| } |
| |
| /** |
| * Returns the undoable <code>PropertySheetPage</code> for this editor. |
| * |
| * @return - the undoable <code>PropertySheetPage</code> |
| */ |
| protected IPropertySheetPage getPropertySheetPage() { |
| if (null == undoablePropertySheetPage) { |
| undoablePropertySheetPage = new PropertySheetPage(); |
| |
| /** set the property source for property sheet page */ |
| undoablePropertySheetPage |
| .setRootEntry(new org.eclipse.gef.ui.properties.UndoablePropertySheetEntry( |
| (CommandStack) getAdapter(CommandStack.class))); |
| |
| } |
| |
| return undoablePropertySheetPage; |
| } |
| |
| /** |
| * Returns the selection syncronizer object. The synchronizer can be used to |
| * sync the selection of 2 or more EditPartViewers. |
| * |
| * @return - the syncrhonizer |
| */ |
| protected SelectionSynchronizer getSelectionSynchronizer() { |
| if (null == synchronizer) { |
| synchronizer = new SelectionSynchronizer(); |
| } |
| return synchronizer; |
| } |
| |
| /** |
| * Returns the shared KeyHandler that should be used for all viewers. |
| * |
| * @return - the shared KeyHandler |
| */ |
| protected KeyHandler getSharedKeyHandler() { |
| if (null == sharedKeyHandler) { |
| sharedKeyHandler = new KeyHandler(); |
| |
| // configure common keys for all viewers |
| sharedKeyHandler |
| .put(KeyStroke.getPressed(SWT.DEL, 127, 0), |
| getActionRegistry().getAction( |
| ActionFactory.DELETE.getId())); |
| sharedKeyHandler.put(KeyStroke.getPressed(SWT.F2, 0), |
| getActionRegistry().getAction( |
| GEFActionConstants.DIRECT_EDIT)); |
| } |
| return sharedKeyHandler; |
| } |
| |
| /** |
| * Returns the selection listener. |
| * |
| * @return - the <code>ISelectionListener</code> |
| */ |
| protected ISelectionListener getSelectionListener() { |
| return selectionListener; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) |
| */ |
| public void propertyChange(PropertyChangeEvent event) { |
| String property = (event == null) ? null : event.getProperty(); |
| |
| propagateProperty(property, viewer.getRootEditPart()); |
| } |
| |
| /** |
| * propagate property change to children edit part |
| * |
| * @param property - |
| * property's string name |
| * @param part - |
| * parent edit part. |
| */ |
| private void propagateProperty(String property, EditPart part) { |
| processPropertyChange(property, part); |
| |
| if (part instanceof GraphicalEditPart) { |
| // get the connections edit part |
| Iterator iterConns = ((GraphicalEditPart) part) |
| .getSourceConnections().iterator(); |
| while (iterConns.hasNext()) { |
| EditPart child = (EditPart) iterConns.next(); |
| propagateProperty(property, child); |
| } |
| } |
| Iterator iter = part.getChildren().iterator(); |
| while (iter.hasNext()) { |
| EditPart child = (EditPart) iter.next(); |
| propagateProperty(property, child); |
| } |
| } |
| |
| /** |
| * process the property change FIXME: The property change should be category |
| * to improve the performance. |
| * |
| * @param property - |
| * property's string name |
| * @param part |
| */ |
| private void processPropertyChange(String property, EditPart part) { |
| IPreferenceStore store = EditorPlugin.getDefault().getPreferenceStore(); |
| |
| if (property != null |
| && property.equals(GEMPreferences.USE_SYSTEM_COLORS)) { |
| // reload all properties - it's easiest |
| property = null; |
| } |
| |
| if (property == null || GEMPreferences.SNAP_TO_GRID.equals(property)) { |
| boolean bSnapToGrid = store.getBoolean(GEMPreferences.SNAP_TO_GRID); |
| if (part instanceof ILayerPanePreference) { |
| ((ILayerPanePreference) part).setGridVisible(bSnapToGrid); |
| } |
| } |
| |
| if (property == null || GEMPreferences.GRID_WIDTH.equals(property) |
| || GEMPreferences.GRID_HEIGHT.equals(property)) { |
| Dimension gridSpacing = new Dimension(store |
| .getInt(GEMPreferences.GRID_WIDTH), store |
| .getInt(GEMPreferences.GRID_HEIGHT)); |
| if (part instanceof ILayerPanePreference) { |
| ((ILayerPanePreference) part).setGridSpacing(gridSpacing); |
| } |
| } |
| |
| if (property == null || GEMPreferences.GRID_COLOR.equals(property)) { |
| Color gridFgColor = GEMPreferences.getColor(store, |
| GEMPreferences.GRID_COLOR); |
| if (part instanceof ILayerPanePreference) { |
| ((ILayerPanePreference) part) |
| .setGridForegroundColor(gridFgColor); |
| } |
| } |
| |
| if (property == null || GEMPreferences.CANVAS_COLOR.equals(property)) { |
| Color containerBgColor = GEMPreferences.getColor(store, |
| GEMPreferences.CANVAS_COLOR); |
| if (part instanceof IFigurePreference) { |
| ((IFigurePreference) part).setBackgroundColor(containerBgColor); |
| } |
| } |
| |
| if (property == null || GEMPreferences.LINE_WIDTH.equals(property)) { |
| int linkLineWidth = store.getInt(GEMPreferences.LINE_WIDTH); |
| |
| if (part instanceof IConnectionPreference) { |
| ((IConnectionPreference) part).setLineWidth(linkLineWidth); |
| } |
| } |
| |
| if (property == null || GEMPreferences.LINE_COLOR.equals(property)) { |
| Color linkLineColor = GEMPreferences.getColor(store, |
| GEMPreferences.LINE_COLOR); |
| if (part instanceof IConnectionPreference) { |
| ((IConnectionPreference) part) |
| .setForegroundColor(linkLineColor); |
| } |
| } |
| |
| if (property == null |
| || GEMPreferences.SHOW_LINE_LABELS.equals(property)) { |
| boolean bLinkLabelVisible = store |
| .getBoolean(GEMPreferences.SHOW_LINE_LABELS); |
| if (part instanceof IConnectionPreference) { |
| ((IConnectionPreference) part) |
| .setLabelVisible(bLinkLabelVisible); |
| } |
| } |
| |
| if (property == null || GEMPreferences.LINE_LABEL_FONT.equals(property) |
| || GEMPreferences.LINE_LABEL_FONT_COLOR.equals(property)) { |
| Font linkLabelFont = getLinkLabelFont(); |
| Color linkLabelFgColor = GEMPreferences.getColor(store, |
| GEMPreferences.LINE_LABEL_FONT_COLOR); |
| if (part instanceof IConnectionPreference) { |
| ((IConnectionPreference) part).setFont(linkLabelFont); |
| ((IConnectionPreference) part) |
| .setLabelForegroundColor(linkLabelFgColor); |
| } |
| } |
| |
| if (property == null |
| || GEMPreferences.LINE_LABEL_COLOR.equals(property)) { |
| Color linkLabelBgColor = GEMPreferences.getColor(store, |
| GEMPreferences.LINE_LABEL_COLOR); |
| if (part instanceof IConnectionPreference) { |
| ((IConnectionPreference) part) |
| .setLabelBackgroundColor(linkLabelBgColor); |
| } |
| } |
| |
| if (property == null || GEMPreferences.LINE_ROUTING.equals(property)) { |
| String connectionStyle = store |
| .getString(GEMPreferences.LINE_ROUTING); |
| int style; |
| if (GEMPreferences.LINE_ROUTING_MANHATTAN.equals(connectionStyle)) { |
| style = ILayerPanePreference.LINE_ROUTING_MANHATTAN; |
| } else { |
| style = ILayerPanePreference.LINE_ROUTING_MANUAL; |
| } |
| |
| if (part instanceof ILayerPanePreference) { |
| ((ILayerPanePreference) part).setConnectionRouterStyle(style); |
| } else if (part instanceof IConnectionPreference) { |
| ((IConnectionPreference) part).setConnectionRouterStyle(style); |
| } |
| } |
| |
| if (property == null |
| || GEMPreferences.FIGURE_LABEL_FONT.equals(property) |
| || GEMPreferences.FIGURE_LABEL_FONT_COLOR.equals(property)) { |
| Font nodeLabelFont = getNodeLabelFont(); |
| Color nodeLabelFgColor = GEMPreferences.getColor(store, |
| GEMPreferences.FIGURE_LABEL_FONT_COLOR); |
| |
| if (part instanceof INodePreference) { |
| ((INodePreference) part).setFont(nodeLabelFont); |
| ((INodePreference) part).setForegroundColor(nodeLabelFgColor); |
| } |
| } |
| |
| if (property == null || GEMPreferences.LABEL_PLACEMENT.equals(property)) { |
| int placement = PositionConstants.SOUTH; |
| String nodeLabelPlacement = store |
| .getString(GEMPreferences.LABEL_PLACEMENT); |
| if (GEMPreferences.LABEL_PLACEMENT_TOP.equals(nodeLabelPlacement)) |
| placement = PositionConstants.NORTH; |
| else if (GEMPreferences.LABEL_PLACEMENT_BOTTOM |
| .equals(nodeLabelPlacement)) |
| placement = PositionConstants.SOUTH; |
| else if (GEMPreferences.LABEL_PLACEMENT_LEFT |
| .equals(nodeLabelPlacement)) |
| placement = PositionConstants.WEST; |
| else if (GEMPreferences.LABEL_PLACEMENT_RIGHT |
| .equals(nodeLabelPlacement)) |
| placement = PositionConstants.EAST; |
| if (part instanceof INodePreference) |
| ((INodePreference) part).setTextPlacement(placement); |
| } |
| } |
| |
| private Font getLinkLabelFont() { |
| FontRegistry registry = JFaceResources.getFontRegistry(); |
| IPreferenceStore store = EditorPlugin.getDefault().getPreferenceStore(); |
| FontData fontData = PreferenceConverter.getFontData(store, |
| GEMPreferences.LINE_LABEL_FONT); |
| if (!registry.get(fontData.toString()).equals(registry.defaultFont())) |
| return registry.get(fontData.toString()); |
| |
| registry.put(fontData.toString(), new FontData[] {fontData}); |
| return registry.get(fontData.toString()); |
| } |
| |
| private Font getNodeLabelFont() { |
| FontRegistry registry = JFaceResources.getFontRegistry(); |
| IPreferenceStore store = EditorPlugin.getDefault().getPreferenceStore(); |
| FontData fontData = PreferenceConverter.getFontData(store, |
| GEMPreferences.FIGURE_LABEL_FONT); |
| if (!registry.get(fontData.toString()).equals(registry.defaultFont())) |
| return registry.get(fontData.toString()); |
| |
| registry.put(fontData.toString(), new FontData[] {fontData}); |
| return registry.get(fontData.toString()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.ide.IGotoMarker#gotoMarker(org.eclipse.core.resources.IMarker) |
| */ |
| public void gotoMarker(IMarker marker) { |
| // The LOCATION attribute in the marker should be the ID string |
| Object id = null; |
| try { |
| id = marker.getAttribute(IMarker.LOCATION); |
| } catch (CoreException e) { |
| // Pageflow.PageflowEditor.Error.invalidMarkerAttribute = Unable to |
| // get marker's attribute |
| log |
| .error( |
| "Pageflow.PageflowEditor.Error.invalidMarkerAttribute", |
| e); |
| } |
| if (id instanceof String) { |
| GraphicalEditPart part = EditPartMarkerUtil.findEditPart( |
| (GraphicalEditPart) getGraphicalViewer().getRootEditPart(), |
| (String) id); |
| if (part != null) { |
| getGraphicalViewer().reveal(part); |
| getGraphicalViewer().select(part); |
| return; |
| } |
| } |
| |
| } |
| |
| /** |
| * the related web page is changed in outside editor, the pageflow should be |
| * revalidated to update the validation icons |
| * |
| * @param fullPath |
| */ |
| public void webPageChanged(IPath fullPath) { |
| PageflowPage page = getPageflowManager().foundPage( |
| WebrootUtil.getWebPath(fullPath)); |
| |
| if (page != null && getGraphicalViewer() != null |
| && getGraphicalViewer().getRootEditPart() != null) { |
| GraphicalEditPart pagePart = EditPartMarkerUtil.findEditPart( |
| (GraphicalEditPart) getGraphicalViewer().getRootEditPart(), |
| page.getId()); |
| PageflowAnnotationUtil |
| .validatePage((PageflowNodeEditPart) pagePart); |
| } |
| } |
| |
| /** |
| * Get the image desriptor from the view's id. |
| * |
| * @param viewid |
| * @return |
| */ |
| private ImageDescriptor getImageDescriptorForView(String viewid) { |
| IConfigurationElement[] elements = Platform.getExtensionRegistry() |
| .getConfigurationElementsFor("org.eclipse.ui.views"); |
| for (int i = 0; i < elements.length; i++) { |
| String name = elements[i].getName(); |
| String id = elements[i].getAttribute("id"); |
| if ("view".equals(name) && viewid.equals(id)) { |
| String iconPath = elements[i].getAttribute("icon"); |
| if (iconPath != null) { |
| return AbstractUIPlugin.imageDescriptorFromPlugin( |
| elements[i].getDeclaringExtension().getContributor().getName(), |
| iconPath); |
| } |
| } |
| } |
| return null; |
| } |
| } |