blob: d7bac5b0024a7bc411c48674ac541a61964ec116 [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2005, 2013 SAP AG.
* 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:
* SAP AG - initial API, implementation and documentation
* mwenz - Bug 323034 - Aligned vertical gaps between groups
* mgorning - Bug 352874 - Exports of Diagrams > 3000x3000 px
* mwenz - Bug 370888 - API Access to export and print
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.graphiti.ui.internal.util.ui.print;
import java.util.List;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.ui.internal.Messages;
import org.eclipse.graphiti.ui.internal.editor.GFFigureCanvas;
import org.eclipse.graphiti.ui.internal.fixed.FixedScaledGraphics;
import org.eclipse.graphiti.ui.internal.services.GraphitiUiInternal;
import org.eclipse.graphiti.ui.print.IPrintPreferences;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
/**
* This is an abstract dialog, where the user can choose between the whole
* figure or a selection.
*
* @noinstantiate This class is not intended to be instantiated by clients.
* @noextend This class is not intended to be subclassed by clients.
*/
public class AbstractFigureSelectionDialog extends Dialog implements SelectionListener {
// initial values
protected GraphicalViewer _graphicalViewer;
/**
* <code>_allFigure</code> represents a figure that contains all printable
* layers
*/
protected IFigure _allFigure;
/**
* <code>_selectionFigure</code> represents a figure which corresponds to
* the selected EditPart
*/
protected IFigure _selectionFigure;
protected boolean _insideInternalModify = false;
private Button _allFigureButton;
private Button _selectionFigureButton;
// selected values
/**
* <code>_figure</code> corresponds either to the value of
* <code>_allFigure</code> or to the value of <code>_selectionFigure</code>
*/
protected IFigure _figure;
private Image _imageSelection;
/**
* Image corresponding to the whole diagram (unscaled) or <b>null</b> if the
* diagram is too large
*/
private Image _imageAll;
/**
* Image corresponding to either one selected part of the diagram or the
* whole diagram (non-scaled version) - can be <b>null</b> if the diagram is
* too large and nothing is selected
*/
protected Image _image;
/**
* Image corresponding to either one selected part of the diagram or the
* whole diagram (scaled version)
*/
private Image _scaledImage;
protected IPrintPreferences _preferences;
private GraphicalEditPart _selectedEditPart;
/**
* Creates a new AbstractPrintFigureDialog.
*
* @param shell
* The Shell of this dialog.
* @param graphicalViewer
* The GraphicalViewer, which to print.
*/
public AbstractFigureSelectionDialog(Shell shell, GraphicalViewer graphicalViewer) {
super(shell);
_graphicalViewer = graphicalViewer;
_preferences = new DefaultPrintPreferences();
determinePossibleFigures();
}
@Override
protected void configureShell(Shell newShell) {
newShell.setText(Messages.AbstractFigureSelectionDialog_0_xtxt);
super.configureShell(newShell);
}
protected Group createChooseFigureGroup(Composite composite) {
Group figureGroup = new Group(composite, SWT.NONE);
figureGroup.setText(Messages.AbstractFigureSelectionDialog_1_xtxt);
GridLayout layout = new GridLayout(1, false);
figureGroup.setLayout(layout);
figureGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
boolean singleSelection = isFigureSelected();
_allFigureButton = new Button(figureGroup, SWT.RADIO);
_allFigureButton.setText(Messages.AbstractFigureSelectionDialog_2_xbut);
_allFigureButton.setSelection(!singleSelection);
GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL);
_allFigureButton.setLayoutData(data);
_allFigureButton.addSelectionListener(this);
_selectionFigureButton = new Button(figureGroup, SWT.RADIO);
_selectionFigureButton.setText(Messages.AbstractFigureSelectionDialog_3_xbut);
_selectionFigureButton.setSelection(singleSelection);
_selectionFigureButton.setEnabled(_selectionFigure != null);
data = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL);
_selectionFigureButton.setLayoutData(data);
_selectionFigureButton.addSelectionListener(this);
return figureGroup;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse
* .swt.events.SelectionEvent)
*/
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
* .events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e) {
if (_insideInternalModify) // avoid endless-loops
return;
if (e.getSource() == _allFigureButton || e.getSource() == _selectionFigureButton) {
_figure = _allFigureButton.getSelection() ? _allFigure : _selectionFigure;
_image = _allFigureButton.getSelection() ? _imageAll : _imageSelection;
updateControls();
}
}
public void updateControls() {
// not used
}
public final IFigure getFigure() {
return _figure;
}
public final GraphicalViewer getGraphicalViewer() {
return _graphicalViewer;
}
// determine _allFigure, _selectionFigure and _figure
private void determinePossibleFigures() {
_allFigure = null;
_selectionFigure = null;
_figure = null;
// shrink canvas to minimal necessary dimensions
GraphicalViewer viewer = getGraphicalViewer();
org.eclipse.swt.widgets.Control control = viewer.getControl();
if (control instanceof GFFigureCanvas) {
GFFigureCanvas canvas = (GFFigureCanvas) control;
canvas.regainSpace();
}
EditPart rootEditPart = viewer.getRootEditPart();
if (!(rootEditPart instanceof GraphicalEditPart))
return;
// determine _allFigure
GraphicalEditPart graphicalRootEditPart = (GraphicalEditPart) rootEditPart;
IFigure rootFigure = ((LayerManager) graphicalRootEditPart).getLayer(LayerConstants.PRINTABLE_LAYERS);
if (rootFigure == null)
return;
_allFigure = rootFigure;
// determine _selectionFigure
@SuppressWarnings("unchecked")
List<EditPart> selectedEditParts = viewer.getSelectedEditParts();
for (EditPart selectedEditPart : selectedEditParts) {
if (!(selectedEditPart instanceof GraphicalEditPart)
|| (selectedEditPart == getGraphicalViewer().getContents())) {
_selectionFigure = null;
break;
}
_selectedEditPart = (GraphicalEditPart) selectedEditPart;
_selectionFigure = _selectedEditPart.getFigure();
break;
}
// determine _figure
_figure = (_selectionFigure == null) ? _allFigure : _selectionFigure;
// _allFigureButton.setSelection(_figure == _allFigure);
}
public void setScaledImage(double scaleFactor, double upperBoundPixels) {
cleanUp();
_imageAll = null;
_scaledImage = null;
_image = null;
// create _imageAll based on _allFigure
initImageAll(upperBoundPixels);
// create _scaledImage based either on _allFigure or on _selectionFigure
// use scaleFactor to determine scaled version
initScaledImage(scaleFactor, upperBoundPixels);
initImage();
}
public void setScaledImage(double scaleFactor) {
setScaledImage(scaleFactor, 10000.0d);
}
private void initImage() {
{
if (_selectionFigure != null) {
_imageSelection = new Image(Display.getDefault(), _selectionFigure.getBounds().width,
_selectionFigure.getBounds().height);
GC gc = new GC(_imageSelection);
SWTGraphics graphics = new SWTGraphics(gc);
graphics.translate(-_selectionFigure.getBounds().x, -_selectionFigure.getBounds().y);
_selectionFigure.paint(graphics);
addRelatedEditParts(graphics, _selectedEditPart);
if (gc != null)
gc.dispose();
if (graphics != null)
graphics.dispose();
_image = _imageSelection;
} else {
if (_imageAll != null) {
_image = _imageAll;
} else {
_image = null;
}
}
}
}
private void initImageAll(double upperBoundPixels) {
{
int width = _allFigure.getBounds().width;
int height = _allFigure.getBounds().height;
// check whether the dimensions of the image to be created would
// be small enough to prevent runtime exceptions
if (width <= upperBoundPixels && height <= upperBoundPixels) {
_imageAll = new Image(Display.getDefault(), width, height);
GC gc = new GC(_imageAll);
SWTGraphics graphics = new SWTGraphics(gc);
/* move all figures into the positive region */
EditPart contents = getGraphicalViewer().getContents();
if (contents instanceof GraphicalEditPart) {
IFigure contentsFigure = ((GraphicalEditPart) contents).getFigure();
Rectangle contentBounds = contentsFigure.getBounds();
graphics.translate(-contentBounds.x, -contentBounds.y);
}
_allFigure.paint(graphics);
if (gc != null)
gc.dispose();
if (graphics != null)
graphics.dispose();
} else {
_imageAll = null;
}
}
}
private void initScaledImage(double scaleFactor, double upperBoundPixels) {
{
GC gc = null;
FixedScaledGraphics graphics = null;
if (!isFigureSelected()) {
// if the scale factor is too high, the operating system will
// not be able to provide a handle,
// because the Image would require too much space. "no more
// Handles"-Exception or "out of Memory" Error
// will be thrown
if (scaleFactor * _allFigure.getBounds().width > upperBoundPixels
|| scaleFactor * _allFigure.getBounds().height > upperBoundPixels) {
scaleFactor = Math.min(upperBoundPixels / _allFigure.getBounds().width, upperBoundPixels
/ _allFigure.getBounds().height);
}
_scaledImage = new Image(Display.getDefault(), (int) (_allFigure.getBounds().width * scaleFactor),
(int) (scaleFactor * _allFigure.getBounds().height));
gc = new GC(_scaledImage);
graphics = new FixedScaledGraphics(new SWTGraphics(gc));
graphics.scale(scaleFactor);
/* move all figures into the positive region */
EditPart contents = getGraphicalViewer().getContents();
if (contents instanceof GraphicalEditPart) {
IFigure contentsFigure = ((GraphicalEditPart) contents).getFigure();
Rectangle contentBounds = contentsFigure.getBounds();
graphics.translate(-contentBounds.x, -contentBounds.y);
}
_allFigure.paint(graphics);
} else {
if (scaleFactor * _selectionFigure.getBounds().width > upperBoundPixels
|| scaleFactor * _selectionFigure.getBounds().height > upperBoundPixels) {
scaleFactor = Math.min(upperBoundPixels / _selectionFigure.getBounds().width, upperBoundPixels
/ _selectionFigure.getBounds().height);
}
_scaledImage = new Image(null, (int) (_selectionFigure.getBounds().width * scaleFactor),
(int) (scaleFactor * _selectionFigure.getBounds().height));
gc = new GC(_scaledImage);
graphics = new FixedScaledGraphics(new SWTGraphics(gc));
graphics.scale(scaleFactor);
graphics.translate(-_selectionFigure.getBounds().x, -_selectionFigure.getBounds().y);
_selectionFigure.paint(graphics);
addRelatedEditParts(graphics, _selectedEditPart);
}
if (gc != null)
gc.dispose();
if (graphics != null)
graphics.dispose();
}
}
private void addRelatedEditParts(Graphics graphics, GraphicalEditPart ep) {
List<EditPart> relatedEditParts = GraphitiUiInternal.getGefService().getConnectionsContainedInEditPart(ep);
for (Object conn : relatedEditParts) {
if (conn instanceof GraphicalEditPart) {
GraphicalEditPart conn2 = (GraphicalEditPart) conn;
if (conn2.getModel() instanceof PictogramElement) {
PictogramElement pe = (PictogramElement) conn2.getModel();
if (!pe.isVisible())
continue;
IFigure figure = conn2.getFigure();
figure.paint(graphics);
}
}
}
}
public Image getImage() {
return _image;
}
public Image getScaledImage() {
return _scaledImage;
}
private boolean isFigureSelected() {
return _selectedEditPart != null && (_selectionFigureButton == null || _selectionFigureButton.getSelection());
}
public void cleanUp() {
if (_scaledImage != null)
_scaledImage.dispose();
if (_image != null)
_image.dispose();
if (_imageAll != null)
_imageAll.dispose();
if (_imageSelection != null)
_imageSelection.dispose();
}
}