Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 915bd3bcd5e71ff29b648f2c7a763eee512deb1b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*******************************************************************************
 * Copyright (c) 2012, 2016 THALES GLOBAL SERVICES.
 * 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:
 *    Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.diagram.ui.tools.internal.actions.layout;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.Request;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.DSemanticDiagram;
import org.eclipse.sirius.diagram.business.api.diagramtype.DiagramTypeDescriptorRegistry;
import org.eclipse.sirius.diagram.business.api.diagramtype.IDiagramDescriptionProvider;
import org.eclipse.sirius.diagram.business.api.diagramtype.IDiagramTypeDescriptor;
import org.eclipse.sirius.diagram.ui.tools.internal.actions.AbstractDiagramAction;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;

/**
 * Abstract class to define a common enablement computation.
 * 
 * @author mporhel
 */
public abstract class AbstractCopyPasteFormatAction extends AbstractDiagramAction {
    private IWorkbenchPart representationPart;

    /**
     * Default constructor.
     * 
     * @param workbenchPage
     *            the active workbench page
     * @param actionWorkbenchPart
     *            the part concerned by this action. Could be null.
     */
    public AbstractCopyPasteFormatAction(final IWorkbenchPage workbenchPage, IWorkbenchPart actionWorkbenchPart) {
        super(workbenchPage);
        this.representationPart = actionWorkbenchPart;

    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#createTargetRequest()
     */
    @Override
    protected final Request createTargetRequest() {
        return null;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#isSelectionListener()
     */
    @Override
    protected final boolean isSelectionListener() {
        return true;
    }

    @Override
    public void dispose() {
        super.dispose();
        representationPart = null;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#calculateEnabled()
     */
    @Override
    protected final boolean calculateEnabled() {
        boolean enable = false;
        if (representationPart != null && !representationPart.equals(getWorkbenchPart())) {
            return super.isEnabled();
        }
        Collection<DSemanticDecorator> dSelection = getDSelection(getSelectedObjects());

        DDiagram parentDiagram = null;
        for (DSemanticDecorator dsem : dSelection) {
            if (dsem instanceof DDiagram) {
                parentDiagram = (DDiagram) dsem;
            } else if (dsem instanceof DDiagramElement) {
                parentDiagram = ((DDiagramElement) dsem).getParentDiagram();
            }

            if (parentDiagram != null) {
                break;
            }
        }

        if (parentDiagram != null) {
            Predicate<DSemanticDecorator> allowsPasteFormat = allowsCopyPasteFormat(parentDiagram);
            if (Iterables.all(dSelection, allowsPasteFormat)) {
                enable = super.calculateEnabled();
            }
        }
        return enable;
    }

    /**
     * Get current selected diagram elements.
     * 
     * @param selection
     *            Selection
     * @return Selected elements.
     */
    private Collection<DSemanticDecorator> getDSelection(Collection<?> selection) {
        if (selection != null && !selection.isEmpty()) {
            final Collection<DSemanticDecorator> elements = new ArrayList<>();
            for (IGraphicalEditPart part : Iterables.filter(selection, IGraphicalEditPart.class)) {
                EObject semanticElement = part.resolveSemanticElement();
                if (semanticElement instanceof DDiagramElement) {
                    elements.add((DDiagramElement) semanticElement);
                } else if (semanticElement instanceof DSemanticDiagram) {
                    elements.add((DSemanticDiagram) semanticElement);
                }
            }
            return elements;
        }
        return Collections.emptyList();
    }

    /**
     * Indicates if the given ddiagram is allowing copy/paste format.
     * 
     * @param diagram
     *            the diagram to inspect
     * @return true if the given ddiagram is allowing copy/paste format actions,
     *         false otherwise
     */
    public static Predicate<DSemanticDecorator> allowsCopyPasteFormat(DDiagram diagram) {
        // default return value is true (for basic DDiagram that are not handled
        // by any DiagramDescriptionProvider).
        Predicate<DSemanticDecorator> result = Predicates.alwaysTrue();

        // If an aird has been opened from the Package Explorer View, then
        // we return false as no diagram is associated to this editor
        if (diagram == null || diagram.getDescription() == null) {
            return Predicates.alwaysFalse();
        }

        // If diagram is not null, we search for a possible
        // DiagramDescriptionProvider handling this type of diagram
        for (final IDiagramTypeDescriptor diagramTypeDescriptor : DiagramTypeDescriptorRegistry.getInstance().getAllDiagramTypeDescriptors()) {
            if (diagramTypeDescriptor.getDiagramDescriptionProvider().handles(diagram.getDescription().eClass().getEPackage())) {
                // This DiagramDescriptionProvider may forbid copy/paste format.
                final IDiagramDescriptionProvider provider = diagramTypeDescriptor.getDiagramDescriptionProvider();
                result = new Predicate<DSemanticDecorator>() {
                    @Override
                    public boolean apply(DSemanticDecorator input) {
                        return provider.allowsCopyPasteFormat(input);
                    }
                };
                break;
            }
        }

        return result;
    }
}

Back to the top