/*******************************************************************************
* Copyright (c) 2010-2015 Henshin developers. 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:
* TU Berlin, University of Luxembourg, SES S.A.
*******************************************************************************/
package de.tub.tfs.muvitor.ui;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.draw2d.ConnectionLayer;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.Viewport;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.parts.ScrollableThumbnail;
import org.eclipse.draw2d.parts.Thumbnail;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.KeyHandler;
import org.eclipse.gef.KeyStroke;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.SnapToGrid;
import org.eclipse.gef.Tool;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CommandStackListener;
import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
import org.eclipse.gef.dnd.TemplateTransferDropTargetListener;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.rulers.RulerProvider;
import org.eclipse.gef.tools.MarqueeSelectionTool;
import org.eclipse.gef.ui.actions.ActionBarContributor;
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.SelectionAction;
import org.eclipse.gef.ui.actions.UpdateAction;
import org.eclipse.gef.ui.actions.WorkbenchPartAction;
import org.eclipse.gef.ui.actions.ZoomComboContributionItem;
import org.eclipse.gef.ui.actions.ZoomInAction;
import org.eclipse.gef.ui.actions.ZoomOutAction;
import org.eclipse.gef.ui.palette.FlyoutPaletteComposite;
import org.eclipse.gef.ui.palette.PaletteViewer;
import org.eclipse.gef.ui.palette.PaletteViewerProvider;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.gef.ui.parts.SelectionSynchronizer;
import org.eclipse.gef.ui.rulers.RulerComposite;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.SubActionBars;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.RetargetAction;
//import org.eclipse.ui.internal.PartPane.Sashes;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.part.PageBookView;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.osgi.service.prefs.Preferences;
import de.tub.tfs.muvitor.actions.ExportViewerImageAction;
import de.tub.tfs.muvitor.actions.MoveNodeAction;
import de.tub.tfs.muvitor.actions.MuvitorActionBarContributor;
import de.tub.tfs.muvitor.actions.SelectAllInMultiViewerAction;
import de.tub.tfs.muvitor.actions.TrimViewerAction;
import de.tub.tfs.muvitor.animation.IGraphicalViewerProvider;
import de.tub.tfs.muvitor.gef.editparts.AdapterGraphicalEditPart;
import de.tub.tfs.muvitor.gef.palette.MuvitorPaletteRoot;
import de.tub.tfs.muvitor.ui.MuvitorPage.MultiViewerPageViewer;
import de.tub.tfs.muvitor.ui.MuvitorPage.MuvitorRulerProvider;
import de.tub.tfs.muvitor.ui.utils.MuvitorNotifierService;
import de.tub.tfs.muvitor.ui.utils.SelectionProviderIntermediate;
import de.tub.tfs.muvitor.ui.utils.ZoomManagerDelegate;
public abstract class MultiDimensionalPage<T extends EObject> extends Page implements IAdaptable,
CommandStackListener, IGraphicalViewerProvider, ISelectionListener {
private int[] dimensionSizes = null;//new int[]{5,29,5,29,29};
private int[] dimensions = null;//new int[]{1,3,1,3,1};
@SuppressWarnings("rawtypes")
private MultiDimensionalViewer[][] viewers = null;
/**
* The action registry that holds the actions for this page.
*/
private final ActionRegistry actionRegistry = new ActionRegistry();
/**
* The main {@link Control} of this page.
*/
protected FlyoutPaletteComposite flyoutPaletteComposite;
/**
* The main {@link MuvitorTreeEditor} this page is a part of.
*/
private final MuvitorTreeEditor editor;
/**
* The viewer that is
* <ul>
* <li>showed in the {@link Thumbnail},
* <li>the current {@link ISelectionProvider} for this page's
* {@link IPageSite} and
* <li>observed for selection changes
* <li>providing a {@link ZoomManager} for the zoom actions via a
* {@link ZoomManagerDelegate}.
* </ul>
*
* @see #setCurrentViewer(roneditor.ui.part.createActions.MultiViewerPageViewer)
*/
private MultiDimensionalViewer<T> currentViewer;
/**
* A thumbnail showing a miniature of what the viewer contains.
*/
private ScrollableThumbnail thumbnail;
/**
* The {@link EditDomain} managing this page like an encapsulated editor.
*/
private EditDomain editDomain;
/**
* The model which is shown in the viewer.
*/
private final EObject model;
/**
* This subclassed {@link ZoomManager} is set for the zoom actions and the
* returned by {@link #getAdapter(Class)} for the
* {@link ZoomComboContributionItem} created in the
* {@link ActionBarContributor}. It delegates to the {@link ZoomManager} of
* {@link #currentViewer}.
*
* @see #setCurrentViewer(MultiViewerPageViewer)
*/
private final ZoomManagerDelegate zoomManagerDelegate = new ZoomManagerDelegate();
/**
* This enables this page to switch the actual selection-providing viewer.
*
* @see #setCurrentViewer(MultiViewerPageViewer)
*/
private final SelectionProviderIntermediate selectionProvider = new SelectionProviderIntermediate();
/**
* A shared {@link KeyHandler} for the viewers on this page.
*/
private KeyHandler keyHandler;
/**
* The EMF adapter listening to this pages's model EObject.
*/
final private Adapter adapter = new AdapterImpl() {
@Override
public void notifyChanged(final Notification msg) {
MultiDimensionalPage.this.notifyChanged(msg);
}
};
//private MuvitorPageBookView pageview = null;
EObject[] models = null;
/* public MultiDimensionalPage(MuvitorPageBookView pageview) {
this.editor = (MuvitorTreeEditor) pageview.getEditor();
this.model = pageview.getModel();
this.pageview = pageview;
}
*/
final protected Map<Adapter, EObject> adapters = new HashMap<Adapter, EObject>();
/**
* Convenience method to register an {@link Adapter} on this editpart's
* model.
*
* @param adapter
* an {@link Adapter} to register on this editpart's model
* @see #registerAdapter(Adapter, EObject)
*/
public final void registerAdapter(final Adapter adapter) {
registerAdapter(adapter, getCastedModel());
}
/**
* Via this method subclasses can install {@link Adapter}s in
* {@link #activate()} listening to changes on a specific {@link EObject}.
* All registered adapters will be deregistered by default in
* {@link #deactivate()}.
*
* @param adapter
* an {@link Adapter} to register on the model
* @param model
* an {@link EObject} to observe with the passed adapter
*/
public final void registerAdapter(final Adapter adapter, final EObject model) {
adapters.put(adapter, model);
model.eAdapters().add(adapter);
}
/**
* Convenience method to let {@link #notifyChanged(Notification)} receive
* notifications from additional EObjects. This method registers an
* {@link Adapter} on some EObject that just forwards its notifications.
*
* @param adapter
* an {@link Adapter} to register on this editpart's model
* @see #registerAdapter(Adapter, EObject)
*/
public final void registerAdapter(final EObject model) {
registerAdapter(new AdapterImpl() {
@Override
public final void notifyChanged(final Notification msg) {
MultiDimensionalPage.this.notifyChanged(msg);
}
}, model);
}
/**
* @param view
* the MuvitorPageBookView that hosts this page
* @param dim
* number of viewers for each row e.g. dim = new int[]{3,2,1} means 3 viewers for first row, two viewers for the second one and 1 viewer in the last raw.
*
*/
public MultiDimensionalPage(MuvitorPageBookView view,int[] dim,int[] sizes){
this.editor = (MuvitorTreeEditor) view.getEditor();
this.model = view.getModel();
//this.pageview = view;
this.dimensions = dim;
this.dimensionSizes = sizes;
}
abstract protected ContextMenuProviderWithActionRegistry createContextMenuProvider(
EditPartViewer viewer) ;
final public EObject getModel() {
return model;
}
@SuppressWarnings("rawtypes")
final public GraphicalViewer getViewer(final EObject model) {
for (final MultiDimensionalViewer[] arr : viewers) {
for (MultiDimensionalViewer<T> viewer : arr){
if (viewer.getContents() != null
&& viewer.getContents().getModel() == model) {
return viewer;
}
}
}
return null;
}
final public void setViewersContents(final int viewerPosition,
final EObject model) {
Assert.isTrue(viewerPosition < getNumberOfViewers(),
"AbstractMultiViewerPage tried to set contents for viewer on position"
+ viewerPosition + " but has only "
+ getNumberOfViewers() + "viewers!");
getViewers()[viewerPosition].setContents(model);
// hide empty viewers
if (model == null) {
setViewerVisibility(viewerPosition, false);
}
}
final public void setViewerVisibility(final int viewerPosition,
final boolean visible) {
Assert.isTrue(viewerPosition < getNumberOfViewers(),
"AbstractMultiViewerPage tried to switch visibility of viewer on position"
+ viewerPosition + " but has only "
+ getNumberOfViewers() + "viewers!");
final Control control = getViewers()[viewerPosition].getControl();
control.setVisible(visible);
control.getParent().layout(true);
}
final public void maximiseViewer(final int viewerPosition) {
if (viewerPosition >= 0){
final Control control = getViewers()[viewerPosition].getControl();
if (control == null || control.getParent() == null || control.getParent().getParent() == null || control.getParent().getParent().getParent() == null)
return;
((SashForm)control.getParent().getParent().getParent()).setMaximizedControl(control.getParent().getParent());
((SashForm)control.getParent().getParent().getParent()).layout();
((SashForm)control.getParent().getParent().getParent()).redraw();
} else {
final Control control = getViewers()[0].getControl();
if (control == null || control.getParent() == null || control.getParent().getParent() == null || control.getParent().getParent().getParent() == null)
return;
((SashForm)control.getParent().getParent().getParent()).setMaximizedControl(null);
((SashForm)control.getParent().getParent().getParent()).layout();
((SashForm)control.getParent().getParent().getParent()).redraw();
}
}
final protected SelectionSynchronizer getSelectionSynchronizer() {
final SelectionSynchronizer synchronizer = (SelectionSynchronizer) getEditor()
.getAdapter(SelectionSynchronizer.class);
Assert
.isNotNull(synchronizer,
"The editor did not deliver a selection synchronizer instance for the page!");
return synchronizer;
}
@Override
public void dispose() {
for (final Entry<Adapter, EObject> entry : adapters.entrySet()) {
entry.getValue().eAdapters().remove(entry.getKey());
}
getModel().eAdapters().remove(adapter);
getActionRegistry().dispose();
((CommandStack) getEditor().getAdapter(CommandStack.class))
.removeCommandStackListener(this);
for (final GraphicalViewer viewer : getViewers()) {
getSelectionSynchronizer().removeViewer(viewer);
}
getSite().getPage().removeSelectionListener(this);
if (thumbnail != null) {
thumbnail.deactivate();
thumbnail = null;
}
super.dispose();
}
@Override
final public Control getControl() {
return flyoutPaletteComposite;
}
/**
* Sets focus to a part in the page.
*/
@Override
public void setFocus() {
if (getControl() != null) {
getControl().setFocus();
}
}
@Override
final public void selectionChanged(final IWorkbenchPart part,
final ISelection selection) {
updateActions();
}
@SuppressWarnings("unchecked")
final protected void updateActions() {
for (final Iterator<IAction> iter = getActionRegistry().getActions(); iter
.hasNext();) {
final IAction action = iter.next();
if (action instanceof UpdateAction) {
((UpdateAction) action).update();
}
}
}
@SuppressWarnings("rawtypes")
public Object getAdapter(final Class adapter) {
if (adapter == ZoomManager.class) {
return zoomManagerDelegate;
} else if (adapter == IPropertySheetPage.class) {
return editor.getAdapter(adapter);
}
return null;
}
final protected ActionRegistry getActionRegistry() {
return actionRegistry;
}
final protected MuvitorTreeEditor getEditor() {
return editor;
}
final void setCurrentViewer(final MultiDimensionalViewer<T> viewer) {
Assert.isNotNull(viewer,
"AbstractMultiViewerPage can not be set to viewer 'null'!");
// update current viewer only if the passed is different to it
if (currentViewer == viewer) {
// this may happen if we switch from the tree viewer to this viewer,
// so we have to update the actions
updateActions();
return;
}
currentViewer = viewer;
currentViewer.getControl().setFocus();
// set current viewer as actual selection provider for this page's site
selectionProvider.setSelectionProviderDelegate(currentViewer);
updateActions();
// update current viewer as source of Thumbnail
final ScalableFreeformRootEditPart rootEditPart = (ScalableFreeformRootEditPart) currentViewer
.getRootEditPart();
thumbnail.setViewport((Viewport) rootEditPart.getFigure());
thumbnail.setSource(rootEditPart
.getLayer(LayerConstants.PRINTABLE_LAYERS));
thumbnail.setVisible(true);
// update current viewer's ZoomManager for ZoomManagerDelegate
zoomManagerDelegate.setCurrentZoomManager((ZoomManager) currentViewer
.getProperty(ZoomManager.class.toString()));
}
final public void commandStackChanged(final EventObject event) {
updateActions();
}
@Override
public void init(final IPageSite pageSite) {
super.init(pageSite);
getModel().eAdapters().add(adapter);
((CommandStack) getEditor().getAdapter(CommandStack.class))
.addCommandStackListener(this);
}
final protected IAction registerAction(final IAction action) {
getActionRegistry().registerAction(action);
return action;
}
final private void createActions() {
// create standard zoom actions for this page
registerActionAsHandler(new ZoomInAction(zoomManagerDelegate));
registerActionAsHandler(new ZoomOutAction(zoomManagerDelegate));
// register shared standard GEF actions from the editor
// save is treated specially and does not need this
registerSharedActionAsHandler(ActionFactory.REVERT.getId());
registerSharedActionAsHandler(ActionFactory.DELETE.getId());
registerSharedActionAsHandler(ActionFactory.UNDO.getId());
registerSharedActionAsHandler(ActionFactory.REDO.getId());
//registerActionAsHandler(new SelectAllInMultiViewerAction(this));
// register shared actions from editor to put them in the local context
// menu
registerSharedAction(ExportViewerImageAction.ID);
registerSharedAction(TrimViewerAction.ID);
registerSharedAction(GEFActionConstants.TOGGLE_RULER_VISIBILITY);
registerSharedAction(GEFActionConstants.TOGGLE_GRID_VISIBILITY);
// register shared standard node-moving actions from the main editor for
// the local key handler
registerSharedAction(MoveNodeAction.LEFT);
registerSharedAction(MoveNodeAction.RIGHT);
registerSharedAction(MoveNodeAction.UP);
registerSharedAction(MoveNodeAction.DOWN);
registerSharedAction(MoveNodeAction.PREC_LEFT);
registerSharedAction(MoveNodeAction.PREC_RIGHT);
registerSharedAction(MoveNodeAction.PREC_UP);
registerSharedAction(MoveNodeAction.PREC_DOWN);
// register shared standard aligning actions from the main editor for
// the context menu
registerSharedAction(GEFActionConstants.ALIGN_LEFT);
registerSharedAction(GEFActionConstants.ALIGN_CENTER);
registerSharedAction(GEFActionConstants.ALIGN_RIGHT);
registerSharedAction(GEFActionConstants.ALIGN_TOP);
registerSharedAction(GEFActionConstants.ALIGN_MIDDLE);
registerSharedAction(GEFActionConstants.ALIGN_BOTTOM);
createCustomActions();
}
final protected IAction registerActionAsHandler(final IAction action) {
final String id = action.getId();
getSite().getActionBars().setGlobalActionHandler(id,
registerAction(action));
return action;
}
final protected IAction registerSharedAction(final String id) {
final ActionRegistry editorRegistry = (ActionRegistry) getEditor()
.getAdapter(ActionRegistry.class);
Assert
.isNotNull(editorRegistry,
"The editor did not deliver an ActionRegistry instance for the page!");
final IAction action = editorRegistry.getAction(id);
Assert.isNotNull(action,
"The editor did not deliver an action with the id '" + id
+ "' for the page!");
return registerAction(action);
}
@SuppressWarnings({ "deprecation", "unchecked" })
@Override
final public void createControl(final Composite parent) {
final Plugin plugin = MuvitorActivator.getDefault();
flyoutPaletteComposite = new FlyoutPaletteComposite(parent, SWT.NONE,
getSite().getPage(),
new PaletteViewerProvider(getEditDomain()),
FlyoutPaletteComposite.createFlyoutPreferences(plugin
.getPluginPreferences()));
// This sets the state of the flyout palette to "pinned open"
plugin.getPluginPreferences().setValue("org.eclipse.gef.pstate", 4);
// create control that hosts graphical viewer
final Composite viewerControl = createGraphicalViewerComposite();
flyoutPaletteComposite.setGraphicalControl(viewerControl);
// install thumbnail
installThumbnailInPalette();
// set first viewer as default current viewer
setCurrentViewer(getViewers()[0]);
// set selection provider intermediate for the page's site
getSite().setSelectionProvider(selectionProvider);
// a listener to the global selection service
getSite().getPage().addSelectionListener(this);
// create actions, this is done here because zoom actions need a
// viewer's zoom manager
createActions();
// add key strokes defined by concrete subclasses
setupKeyHandler(getKeyHandler());
}
final protected EditDomain getEditDomain() {
if (null == editDomain) {
editDomain = new EditDomain() {
/**
* Overridden to set different behavior for the
* {@link MarqueeSelectionTool}.
*
* @see org.eclipse.gef.EditDomain#setActiveTool(org.eclipse.gef.Tool)
*/
@Override
public void setActiveTool(final Tool tool) {
if (tool instanceof MarqueeSelectionTool) {
// this may be changed according individual needs
((MarqueeSelectionTool) tool)
.setMarqueeBehavior(MarqueeSelectionTool.BEHAVIOR_NODES_CONTAINED);
}
super.setActiveTool(tool);
}
};
editDomain.setPaletteRoot(createPaletteRoot());
final CommandStack commandStack = (CommandStack) getEditor()
.getAdapter(CommandStack.class);
Assert
.isNotNull(commandStack,
"The editor did not deliver a command stack instance for the page!");
editDomain.setCommandStack(commandStack);
}
return editDomain;
}
final private void installThumbnailInPalette() {
// get the FigureCanvas of the PaletteViewer
final FigureCanvas figureCanvas = (FigureCanvas) getEditDomain()
.getPaletteViewer().getControl();
// install a SashForm on the parent of the FigureCanvas
final SashForm sashForm = new SashForm(figureCanvas.getParent(),
SWT.VERTICAL);
// move the original figureCanvas onto the SashForm
figureCanvas.setParent(sashForm);
// create a new FigureCanvas and put a new Thumbnail on it
final FigureCanvas thumbCanvas = new FigureCanvas(sashForm);
thumbnail = new ScrollableThumbnail();
thumbnail.setBorder(new MarginBorder(3));
thumbCanvas.setContents(thumbnail);
// adjust the position of the thumbnail on the canvas
sashForm.setWeights(getThumbSashWeights());
}
protected Composite getCustomContents(int i,Composite parent) {
return null;
}
final protected KeyHandler getKeyHandler() {
if (keyHandler == null) {
keyHandler = new KeyHandler();
// this may be null
keyHandler.setParent((KeyHandler) getEditor().getAdapter(
KeyHandler.class));
keyHandler
.put(KeyStroke.getPressed(SWT.DEL, 127, 0),
getActionRegistry().getAction(
ActionFactory.DELETE.getId()));
keyHandler.put(KeyStroke.getPressed(SWT.F2, 0), getActionRegistry()
.getAction(GEFActionConstants.DIRECT_EDIT));
// Arrow keys run the correspondent MoveNodeActions
keyHandler.put(KeyStroke.getPressed(SWT.ARROW_LEFT, 0),
getActionRegistry().getAction(MoveNodeAction.LEFT));
keyHandler.put(KeyStroke.getPressed(SWT.ARROW_RIGHT, 0),
getActionRegistry().getAction(MoveNodeAction.RIGHT));
keyHandler.put(KeyStroke.getPressed(SWT.ARROW_UP, 0),
getActionRegistry().getAction(MoveNodeAction.UP));
keyHandler.put(KeyStroke.getPressed(SWT.ARROW_DOWN, 0),
getActionRegistry().getAction(MoveNodeAction.DOWN));
// SHIFT + Arrow keys run the correspondent precise MoveNodeActions
keyHandler.put(KeyStroke.getPressed(SWT.ARROW_LEFT, SWT.SHIFT),
getActionRegistry().getAction(MoveNodeAction.PREC_LEFT));
keyHandler.put(KeyStroke.getPressed(SWT.ARROW_RIGHT, SWT.SHIFT),
getActionRegistry().getAction(MoveNodeAction.PREC_RIGHT));
keyHandler.put(KeyStroke.getPressed(SWT.ARROW_UP, SWT.SHIFT),
getActionRegistry().getAction(MoveNodeAction.PREC_UP));
keyHandler.put(KeyStroke.getPressed(SWT.ARROW_DOWN, SWT.SHIFT),
getActionRegistry().getAction(MoveNodeAction.PREC_DOWN));
}
return keyHandler;
}
final public MultiDimensionalViewer<T> getCurrentViewer() {
return currentViewer;
}
final protected IAction registerSharedActionAsHandler(final String id) {
final IAction editorAction = registerSharedAction(id);
getSite().getActionBars().setGlobalActionHandler(id, editorAction);
return editorAction;
}
abstract protected void createCustomActions();
abstract protected EditPartFactory createEditPartFactory();
protected MuvitorPaletteRoot createPaletteRoot() {
// TODO Auto-generated method stub
return null;
}
public int getNumberOfViewers() {
int numberOfViewers = 0;
for (int i = 0; i < dimensions.length; i++) {
numberOfViewers += dimensions[i];
}
return numberOfViewers;
}
public int getDimension(int dim) {
// TODO Auto-generated method stub
return dimensions[dim];
}
public int[] getDimensionSize() {
return dimensionSizes;
}
protected int[] getThumbSashWeights() {
// TODO Auto-generated method stub
return new int[] { 3, 1 };
}
@SuppressWarnings("unchecked")
public T getCastedModel(){
return (T)getModel();
}
public EObject[] getViewerContents() {
//((ActiGra)getCastedModel().eContainer()).getObjectGraphs().add(coDomain);
//((ActiGra)getCastedModel().eContainer()).getObjectGraphs().add(domain);
return getContentsForIndex(0);
}
/**
*
* getContentsForIndex(int i) has to return an array with all Eobjects that should be displayed in the MultidimensionalPage if you created this Page with the dimension {3,2,1} then getContentsForIndex should return an array with the length of 6 the first three elements will be the 3 EObjects for the first row, the fourth and fith element will be put into the second row and the last element will be shown in the last row.
* @param i
* the index for the currently selected tab
* @see getNumberOfItems()
*/
protected abstract EObject[] getContentsForIndex(int i);
abstract protected void setupKeyHandler(KeyHandler kh) ;
abstract protected void notifyChanged(Notification msg);
@SuppressWarnings({ "rawtypes", "unchecked" })
public MultiDimensionalViewer[] getPageViewers(){
ArrayList<MultiDimensionalViewer<T>> list = new ArrayList<MultiDimensionalViewer<T>>();
for (int i = 0; i < viewers.length; i++) {
for (int j = 0; j < viewers[i].length; j++) {
list.add(viewers[i][j]);
}
}
return list.toArray(new MultiDimensionalViewer[]{});
}
protected Composite createGraphicalViewerComposite() {
viewers = new MultiDimensionalViewer[getNumberOfItems()][getNumberOfViewers()];
// create composite that hold the graphical viewers
CTabFolder folder = new CTabFolder(flyoutPaletteComposite,SWT.BOTTOM);
folder.setSimple(false);
folder.setMRUVisible(true);
folder.setLayout(new FillLayout());
for (int index = 0;index < getNumberOfItems();index++){
CTabItem item = new CTabItem(folder, SWT.NULL);
Composite viewerComposite = null;
if (enableSashComposite(index)){
viewerComposite = new SashForm(folder, SWT.BORDER | SWT.VERTICAL | SWT.SMOOTH);
} else {
viewerComposite = new Composite(folder,
SWT.BORDER );
}
GridLayout gridLayout = new GridLayout(1,true);
viewerComposite.setLayout(gridLayout);
item.setControl(viewerComposite);
item.setText(getName(index));
GridData d = new GridData();
d.grabExcessHorizontalSpace = true;
d.grabExcessVerticalSpace = true;
d.minimumHeight = 40;
d.widthHint = 2000;
d.heightHint = 2000;
viewerComposite.setLayoutData(d);
// prepare shared edit part factory
final EditPartFactory editPartFactory = createEditPartFactory();
// prepare contents to set
final EObject[] contents = getContentsForIndex(index);
Composite container = null;
int counter = 0;
int dim = 0;
// create viewers
for (int i = 0; i < getNumberOfViewers(); i++) {
if (counter == 0){
container = new SashForm(viewerComposite,SWT.BORDER);
container.setLayout(new FillLayout());
}
if (counter == getDimension(dim)){
dim++;
counter = 0;
container = new SashForm(viewerComposite,SWT.BORDER);
container.setLayout(new FillLayout());
}
final MultiDimensionalViewer<T> viewer = new MultiDimensionalViewer<T>(this);
getEditDomain().addViewer(viewer);
final RulerComposite rulerComp = new RulerComposite(
container, SWT.NONE);
// set the new viewer on the ruler composite
viewer.createControl(rulerComp);
viewers[index][i] = viewer;
viewer.setKeyHandler(getKeyHandler());
getSelectionSynchronizer().addViewer(viewer);
final ScalableFreeformRootEditPart rootEditPart = new ScalableFreeformRootEditPart();
viewer.setRootEditPart(rootEditPart);
viewer.setEditPartFactory(editPartFactory);
GridData d1 = new GridData();
d1.grabExcessHorizontalSpace = true;
d1.grabExcessVerticalSpace = grabExcessVerticalSpace(dim, counter);
d1.widthHint = 2000;
d1.heightHint = getHeight(dim, counter);
d1.minimumHeight = getMinimumHeight(dim, counter);
container.setLayoutData(d1);
viewer.setContents(contents[i]);
final ContextMenuProviderWithActionRegistry cmp = createContextMenuProvider(viewer);
cmp.setActionRegistry(getActionRegistry());
viewer.setContextMenu(cmp);
// set antialias on connection layer, this may be turned off if
// causing trouble
((ConnectionLayer) rootEditPart
.getLayer(LayerConstants.CONNECTION_LAYER))
.setAntialias(SWT.ON);
// initialize viewer's ZoomManager
final ZoomManager zoomManager = (ZoomManager) viewer
.getProperty(ZoomManager.class.toString());
final List<String> zoomLevels = new ArrayList<String>(3);
zoomLevels.add(ZoomManager.FIT_ALL);
zoomLevels.add(ZoomManager.FIT_WIDTH);
zoomLevels.add(ZoomManager.FIT_HEIGHT);
zoomManager.setZoomLevelContributions(zoomLevels);
zoomManager.setZoomAnimationStyle(ZoomManager.ANIMATE_ZOOM_IN_OUT);
// some optional coloring
viewer.getControl().setBackground(
PlatformUI.getWorkbench().getDisplay().getSystemColor(
SWT.COLOR_LIST_BACKGROUND));
viewer.getControl().setForeground(
PlatformUI.getWorkbench().getDisplay().getSystemColor(
SWT.COLOR_LIST_FOREGROUND));
// prepare viewer for showing rulers and grid
rulerComp.setGraphicalViewer(viewer);
viewer.setProperty(RulerProvider.PROPERTY_HORIZONTAL_RULER,
new MuvitorRulerProvider());
viewer.setProperty(RulerProvider.PROPERTY_VERTICAL_RULER,
new MuvitorRulerProvider());
viewer.setProperty(RulerProvider.PROPERTY_RULER_VISIBILITY,
Boolean.FALSE);
viewer.setProperty(SnapToGrid.PROPERTY_GRID_SPACING, new Dimension(
20, 20));
counter++;
if (container instanceof SashForm){
if (counter == dimensions[dim])
((SashForm) container).setWeights(getChildDimensions(dim));
}
}
if (viewerComposite instanceof SashForm){
((SashForm) viewerComposite).setWeights(getDimensionSize());
}
}
//pageview.updatePageLayout();
folder.setSelection(0);
return folder;
}
protected int[] getChildDimensions(int dim) {
// TODO Auto-generated method stub
int[] result = new int[this.dimensions[dim]];
Arrays.fill(result, 1);
return result;
}
protected boolean enableSashComposite(int index) {
// TODO Auto-generated method stub
return true;
}
protected abstract String getName(int index);
/**
*
* @return this function should return the number of tabs that should be displayed
*/
abstract protected int getNumberOfItems();
@SuppressWarnings("rawtypes")
protected MultiDimensionalViewer[] getViewers() {
// TODO Auto-generated method stub
return viewers[0];
}
final public class MuvitorRulerProvider extends RulerProvider {
@Override
public int getUnit() {
return RulerProvider.UNIT_PIXELS;
}
@Override
public Object getRuler() {
return MuvitorRulerProvider.this;
}
}
protected int getHeight(int dim,int counter){
return 2000;
}
protected boolean grabExcessVerticalSpace(int dim, int counter){
return true;
}
protected int getMinimumHeight(int dim,int counter){
return getDimensionSize()[dim];
}
/**
* This can be used to display messages in this page's status line.
*
* @return The {@link IStatusLineManager} from the {@link IActionBars} of
* this page's {@link IPageSite}
*/
public final IStatusLineManager getStatusLineManager() {
return getSite().getActionBars().getStatusLineManager();
}
/**
* This can be used to add actions to this page's tool bar.
*
* @return The {@link IToolBarManager} from the {@link IActionBars} of this
* page's {@link IPageSite}
*/
public final IToolBarManager getToolBarManager() {
return getSite().getActionBars().getToolBarManager();
}
}