Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: cbf129eb3f0bdd95ae214a74a14e723bc7911bb9 (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
/*******************************************************************************
 * Copyright (c) 2010 THALES GLOBAL SERVICES.
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.diagram.ui.business.internal.query;

import org.eclipse.sirius.diagram.DEdge;
import org.eclipse.sirius.diagram.EdgeTarget;
import org.eclipse.sirius.diagram.business.api.query.DDiagramElementQuery;
import org.eclipse.sirius.diagram.description.FoldingStyle;

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

/**
 * Queries relative to a {@link EdgeTarget}.
 * 
 * @author pcdavid
 */
public class EdgeTargetQuery {
    /**
     * Represents the possible states of a folding point, i.e. an element from
     * which the user can fold/unfold incident edges.
     * 
     * @author pcdavid
     */
    public enum FoldingState {
        /**
         * Indicates the element is currently fully folded, i.e. all the edges
         * foldable from this point are folded
         */
        FOLDED,
        /**
         * Indicates that some of the edges foldable from this point are folded
         * and some are unfolded.
         */
        MIXED,
        /**
         * Indicates the element is currently fully unfolded, i.e. all the edges
         * foldable from this point are unfolded, or that the element is not a
         * folding point (so there is nothing to fold).
         */
        UNFOLDED;
    }

    private final EdgeTarget target;

    /**
     * Constructor.
     * 
     * @param target
     *            the edge target to query.
     */
    public EdgeTargetQuery(EdgeTarget target) {
        this.target = target;
    }

    /**
     * Test whether the element is the folding point of any edge which supports
     * folding and is visible.
     * 
     * @return <code>true</code> if the element is the folding point of any edge
     *         which supports folding and is visible.
     */
    public boolean isFoldingPoint() {
        Iterable<DEdge> foldables = getAllFoldableEdges();
        return !Iterables.isEmpty(foldables);
    }

    /**
     * Returns all the edges to follow from the edge target when walking the
     * graph on folding/unfolding of edges.
     * 
     * @return all the edges to follow on folding/unfolding of edges.
     */
    public Iterable<DEdge> getFoldableEdgesToFollow() {
        return Iterables.filter(getAllFoldableEdges(), new Predicate<DEdge>() {
            public boolean apply(DEdge input) {
                return !new DDiagramElementQuery(input).isExplicitlyFolded();
            }
        });
    }

    /**
     * Returns all the edges for which the edge target is the folding point.
     * 
     * @return all the edges for which the edge target is the folding point.
     */
    public Iterable<DEdge> getAllFoldableEdges() {
        Iterable<DEdge> incomingFoldables = Iterables.filter(Iterables.filter(target.getIncomingEdges(), DEdge.class), DEdgeQuery.hasFoldingStyle(FoldingStyle.TARGET_LITERAL));
        Iterable<DEdge> outgoingFoldables = Iterables.filter(Iterables.filter(target.getOutgoingEdges(), DEdge.class), DEdgeQuery.hasFoldingStyle(FoldingStyle.SOURCE_LITERAL));
        Iterable<DEdge> allFoldables = Iterables.concat(incomingFoldables, outgoingFoldables);
        return Iterables.filter(allFoldables, new Predicate<DEdge>() {
            public boolean apply(DEdge input) {
                return input != null && input.eContainer() != null;
            }
        });
    }

    /**
     * Returns the current folding state of the part, or more precisely of the
     * edges which support folding from this point.
     * 
     * @return a {@link FoldingState} indicating the current folding state of
     *         the part.
     */
    public FoldingState getFoldingState() {
        FoldingState result = FoldingState.UNFOLDED;
        boolean hasFoldedFoldables = false;
        boolean hasUnfoldedFoldables = false;
        for (DEdge edge : getAllFoldableEdges()) {
            if (new DDiagramElementQuery(edge).isExplicitlyFolded()) {
                hasFoldedFoldables = true;
            } else {
                hasUnfoldedFoldables = true;
            }
        }
        if (hasFoldedFoldables && hasUnfoldedFoldables) {
            result = FoldingState.MIXED;
        } else if (hasFoldedFoldables) {
            result = FoldingState.FOLDED;
        }
        return result;
    }
}

Back to the top