Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 330482 | Differences between
and this patch

Collapse All | Expand All

(-)META-INF/MANIFEST.MF (-1 / +6 lines)
Lines 12-18 Link Here
12
 org.eclipse.wst.xml.ui,
12
 org.eclipse.wst.xml.ui,
13
 org.eclipse.ui,
13
 org.eclipse.ui,
14
 org.eclipse.ui.views,
14
 org.eclipse.ui.views,
15
 org.eclipse.help
15
 org.eclipse.help,
16
 org.eclipse.emf.transaction,
17
 org.eclipse.ui.views.properties.tabbed,
18
 org.eclipse.gef,
19
 org.eclipse.graphiti,
20
 org.eclipse.graphiti.ui
16
Bundle-ActivationPolicy: lazy
21
Bundle-ActivationPolicy: lazy
17
Bundle-RequiredExecutionEnvironment: J2SE-1.5
22
Bundle-RequiredExecutionEnvironment: J2SE-1.5
18
Bundle-Vendor: %providerName
23
Bundle-Vendor: %providerName
(-)plugin.xml (+19 lines)
Lines 148-152 Link Here
148
      id="org.eclipse.sapphire.samples.ezbug.ui.BugDatabaseEditor"
148
      id="org.eclipse.sapphire.samples.ezbug.ui.BugDatabaseEditor"
149
      name="Bug Database Editor (Sapphire Sample)"/>
149
      name="Bug Database Editor (Sapphire Sample)"/>
150
  </extension>
150
  </extension>
151
152
  <extension point="org.eclipse.ui.editors">
153
    <editor
154
      class="org.eclipse.sapphire.samples.map.ui.MapEditor"
155
      default="true"
156
      filenames="map.xml"
157
      id="org.eclipse.sapphire.samples.map.ui.MapEditor"
158
      name="Map Editor"/>
159
  </extension>
160
  
161
  <extension point="org.eclipse.ui.editors">
162
    <editor
163
      class="org.eclipse.sapphire.samples.library.ui.LibraryEditor"
164
      default="true"
165
      filenames="library.xml"
166
      id="org.eclipse.sapphire.samples.library.ui.LibraryEditor"
167
      name="Library Editor"/>
168
  </extension>
169
151
  
170
  
152
</plugin>
171
</plugin>
(-)sdef/LibraryEditor.sdef (+113 lines)
Added Link Here
1
<definition>
2
3
  <import>
4
    <bundle>org.eclipse.sapphire.samples</bundle>
5
    <package>org.eclipse.sapphire.samples.library</package>
6
    <package>org.eclipse.sapphire.samples.library.ui</package>
7
    <package>org.eclipse.sapphire.samples.library.internal</package>
8
  </import>
9
  
10
  <diagram-page>
11
    <id>diagram</id>
12
    <page-name>Diagram</page-name>
13
    <page-header-text>Diagram</page-header-text>
14
    <node>
15
      <hint><name>width</name><value>95</value></hint>
16
      <hint><name>height</name><value>85</value></hint>
17
      <hint><name>resizable</name><value>false</value></hint>    
18
      <id>books</id>
19
      <tool-palette-label>Book</tool-palette-label>
20
      <tool-palette-desc>Book</tool-palette-desc>
21
      <property>Books</property>
22
      <possibleImages>
23
        <imageChoice>
24
          <id>bookImage</id>
25
          <path>images/book.png</path>
26
        </imageChoice>
27
        <imageChoice>
28
          <id>bookNoTitleImage</id>
29
          <path>images/book_no_title.png</path>
30
        </imageChoice>
31
      </possibleImages>
32
      <image>
33
        <value>${Title == null ? "bookNoTitleImage" : "bookImage"}</value>  
34
        <hint><name>x</name><value>0</value></hint>
35
        <hint><name>y</name><value>0</value></hint>
36
        <hint><name>width</name><value>64</value></hint>
37
        <hint><name>height</name><value>64</value></hint>
38
      </image>
39
      <label>
40
        <content>${Title == null ? "&lt;Title&gt;" : Title}</content>
41
        <hint><name>x</name><value>0</value></hint>
42
        <hint><name>y</name><value>70</value></hint>
43
        <hint><name>height</name><value>15</value></hint>
44
      </label>
45
      <instance-id>${Title}</instance-id>
46
      <connection>
47
        <id>connections</id>
48
        <tool-palette-label>Book Reference</tool-palette-label>
49
        <tool-palette-desc>Book Reference</tool-palette-desc>
50
        <property>ReferencedBooks</property>
51
        <label>
52
          <content>Reference</content>
53
        </label>
54
        <endpoint>
55
          <property>ReferencedBook</property>
56
          <value>${Title}</value>
57
          <type>ARROW</type>
58
        </endpoint>
59
        <instance-id>${ReferencedBook}</instance-id>
60
      </connection>
61
    </node>
62
  </diagram-page>
63
  
64
  <editor-page>
65
    <id>overview</id>
66
    <page-name>Overview</page-name>
67
    <page-header-text>Overview</page-header-text>
68
    <root-node>
69
      <node>
70
        <label>Books</label>
71
        <section>
72
          <description>Books in the library</description>
73
          <content>
74
            <property-editor>
75
              <property>Books</property>
76
              <child-property>
77
                <property>Title</property>
78
              </child-property>
79
              <child-property>
80
                <property>Author</property>
81
              </child-property>
82
              <hint><name>show.label.above</name><value>true</value></hint>
83
              <hint>
84
                <name>column.widths</name>
85
                <value>150,150</value>
86
              </hint>
87
            </property-editor>
88
            <separator>
89
              <label>References</label>
90
            </separator>
91
            <switching-panel>
92
              <list-selection-controller>
93
                <property>Books</property>
94
              </list-selection-controller>
95
              <panel>
96
                <key>IBook</key>
97
                <content>
98
                  <property-editor>ReferencedBooks</property-editor>
99
                </content>          
100
              </panel>
101
              <default-panel>
102
                <content>
103
                  <label>Select a book above to configure additional properties.</label>
104
                </content>
105
              </default-panel>
106
            </switching-panel>
107
          </content>  
108
        </section>
109
      </node>
110
    </root-node>
111
  </editor-page>
112
  
113
</definition>
(-)sdef/MapEditor.sdef (+73 lines)
Added Link Here
1
<definition>
2
3
  <import>
4
    <bundle>org.eclipse.sapphire.samples</bundle>
5
    <package>org.eclipse.sapphire.samples.map</package>
6
    <package>org.eclipse.sapphire.samples.map.ui</package>
7
  </import>
8
  
9
  <diagram-page>
10
    <id>diagram</id>
11
    <page-name>Diagram</page-name>
12
    <page-header-text>Diagram</page-header-text>
13
    <node>
14
      <id>destinations</id>
15
      <tool-palette-label>Destination</tool-palette-label>
16
      <tool-palette-desc>Map Destination</tool-palette-desc>
17
      <hint><name>width</name><value>70</value></hint>
18
      <hint><name>height</name><value>85</value></hint>      
19
      <property>Destinations</property>
20
      <label>
21
        <content>${Name == null ? "&lt;Destination&gt;" : Name}</content>
22
      </label>
23
      <instance-id>${Name}</instance-id>
24
    </node>
25
    <connection>
26
      <id>connections</id>
27
      <tool-palette-label>Route</tool-palette-label>
28
      <tool-palette-desc>Map Route</tool-palette-desc>
29
      <property>Routes</property>
30
      <label>
31
        <content>${Distance == null ? "&lt;Distance&gt;" : Distance}</content>
32
      </label>
33
      <endpoint1>
34
        <property>FromDestination</property>
35
        <value>${Name}</value>
36
        <type>NONE</type>
37
      </endpoint1>
38
      <endpoint2>
39
        <property>ToDestination</property>
40
        <value>${Name}</value>
41
        <type>ARROW</type>
42
      </endpoint2>
43
      <instance-id>${FromDestination}-${ToDestination}</instance-id>
44
    </connection>
45
  </diagram-page>
46
  
47
  <editor-page>
48
    <id>overview</id>
49
    <page-name>Overview</page-name>
50
    <page-header-text>Overview</page-header-text>
51
    <root-node>
52
      <node>
53
        <label>Destinations</label>
54
        <section>
55
          <description>Destinations in the map</description>
56
          <content>
57
            <property-editor>Destinations</property-editor>
58
          </content>
59
        </section>
60
      </node>
61
      <node>
62
        <label>Routes</label>
63
        <section>
64
          <description>Routes in the map</description>
65
          <content>
66
            <property-editor>Routes</property-editor>
67
          </content>
68
        </section>
69
      </node>
70
    </root-node>
71
  </editor-page>
72
</definition>
73
    
(-)src/org/eclipse/sapphire/samples/library/IBook.java (+53 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.library;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ListProperty;
5
import org.eclipse.sapphire.modeling.ModelElementList;
6
import org.eclipse.sapphire.modeling.ModelElementType;
7
import org.eclipse.sapphire.modeling.Value;
8
import org.eclipse.sapphire.modeling.ValueProperty;
9
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
10
import org.eclipse.sapphire.modeling.annotations.Label;
11
import org.eclipse.sapphire.modeling.annotations.NonNullValue;
12
import org.eclipse.sapphire.modeling.annotations.Type;
13
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
14
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
15
16
@GenerateImpl
17
18
public interface IBook extends IModelElement 
19
{
20
    ModelElementType TYPE = new ModelElementType( IBook.class );
21
22
    // *** Title ***
23
    
24
    @XmlBinding( path = "title" )
25
    @Label( standard = "title" )
26
    @NonNullValue
27
28
    ValueProperty PROP_TITLE = new ValueProperty( TYPE, "Title" );
29
30
    Value<String> getTitle();
31
    void setTitle( String name );
32
33
    // *** Author ***
34
    
35
    @XmlBinding( path = "Author" )
36
    @Label( standard = "Author" )
37
    @NonNullValue
38
39
    ValueProperty PROP_AUTHOR = new ValueProperty( TYPE, "Author" );
40
41
    Value<String> getAuthor();
42
    void setAuthor( String author );
43
    
44
    // *** ReferencedBooks ***
45
    
46
    @Type( base = IBookReference.class )
47
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "referenced-book", type = IBookReference.class ) )
48
    
49
    ListProperty PROP_REFERENCED_BOOKS = new ListProperty( TYPE, "ReferencedBooks" );
50
    
51
    ModelElementList<IBookReference> getReferencedBooks();
52
    
53
}
(-)src/org/eclipse/sapphire/samples/library/IBookReference.java (+32 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.library;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ModelElementType;
5
import org.eclipse.sapphire.modeling.ReferenceValue;
6
import org.eclipse.sapphire.modeling.ValueProperty;
7
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
8
import org.eclipse.sapphire.modeling.annotations.Label;
9
import org.eclipse.sapphire.modeling.annotations.NonNullValue;
10
import org.eclipse.sapphire.modeling.annotations.Reference;
11
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
12
import org.eclipse.sapphire.samples.library.internal.BookReferenceService;
13
14
@GenerateImpl
15
16
public interface IBookReference extends IModelElement 
17
{
18
	ModelElementType TYPE = new ModelElementType( IBookReference.class );
19
	
20
	// *** ReferencedBook ***
21
	
22
	@Reference( target = IBook.class, service = BookReferenceService.class )
23
	@XmlBinding( path = "referenced-book")
24
	@NonNullValue
25
	@Label(standard = "referenced book")
26
27
	ValueProperty PROP_REFERENCED_BOOK = new ValueProperty( TYPE, "ReferencedBook" );
28
29
    ReferenceValue<IBook> getReferencedBook();
30
    void setReferencedBook( String name );
31
	
32
}
(-)src/org/eclipse/sapphire/samples/library/ILibrary.java (+29 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.library;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ListProperty;
5
import org.eclipse.sapphire.modeling.ModelElementList;
6
import org.eclipse.sapphire.modeling.ModelElementType;
7
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
8
import org.eclipse.sapphire.modeling.annotations.Type;
9
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
10
import org.eclipse.sapphire.modeling.xml.annotations.XmlRootBinding;
11
12
@GenerateImpl
13
@XmlRootBinding( elementName = "library")
14
15
public interface ILibrary extends IModelElement 
16
{
17
	ModelElementType TYPE = new ModelElementType( ILibrary.class );
18
	
19
    // *** Books ***
20
21
    @Type( base = IBook.class )
22
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "book", type = IBook.class ) )
23
    
24
    ListProperty PROP_BOOKS = new ListProperty( TYPE, "Books" );
25
    
26
    ModelElementList<IBook> getBooks();
27
	
28
29
}
(-)src/org/eclipse/sapphire/samples/library/internal/BookReferenceService.java (+29 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.library.internal;
2
3
import org.eclipse.sapphire.modeling.ModelElementList;
4
import org.eclipse.sapphire.modeling.ReferenceService;
5
import org.eclipse.sapphire.samples.library.IBook;
6
import org.eclipse.sapphire.samples.library.ILibrary;
7
8
public class BookReferenceService extends ReferenceService 
9
{
10
11
	@Override
12
	public Object resolve(String reference) 
13
	{
14
		if (reference != null)
15
		{
16
			ILibrary library = element().nearest(ILibrary.class);
17
			ModelElementList<IBook> books = library.getBooks();
18
			for (IBook book : books)
19
			{
20
				if (reference.equals(book.getTitle().getContent()))
21
				{
22
					return book;
23
				}
24
			}
25
		}
26
		return null;
27
	}
28
29
}
(-)src/org/eclipse/sapphire/samples/library/ui/LibraryEditor.java (+93 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.library.ui;
2
3
import org.eclipse.core.runtime.IPath;
4
import org.eclipse.core.runtime.IProgressMonitor;
5
import org.eclipse.core.runtime.Path;
6
import org.eclipse.sapphire.modeling.IModelElement;
7
import org.eclipse.sapphire.modeling.xml.RootXmlResource;
8
import org.eclipse.sapphire.samples.library.ILibrary;
9
import org.eclipse.sapphire.ui.SapphireEditor;
10
import org.eclipse.sapphire.ui.diagram.editor.SapphireDiagramEditorPart;
11
import org.eclipse.sapphire.ui.diagram.graphiti.editor.SapphireDiagramEditor;
12
import org.eclipse.sapphire.ui.diagram.graphiti.editor.SapphireDiagramEditorInput;
13
import org.eclipse.sapphire.ui.editor.views.masterdetails.MasterDetailsPage;
14
import org.eclipse.sapphire.ui.xml.XmlEditorResourceStore;
15
import org.eclipse.ui.PartInitException;
16
import org.eclipse.ui.part.FileEditorInput;
17
import org.eclipse.wst.sse.ui.StructuredTextEditor;
18
19
public class LibraryEditor extends SapphireEditor 
20
{
21
	private ILibrary modelLibrary;
22
	private StructuredTextEditor librarySourceEditor;
23
	private SapphireDiagramEditorPart libraryDiagramPart;
24
	private MasterDetailsPage libraryOverviewPage;
25
	
26
    public LibraryEditor()
27
    {
28
        super( "org.eclipse.sapphire.samples" );
29
    }
30
31
	@Override
32
	protected void createSourcePages() throws PartInitException 
33
	{
34
		this.librarySourceEditor = new StructuredTextEditor();
35
		this.librarySourceEditor.setEditorPart(this);
36
        final FileEditorInput rootEditorInput = (FileEditorInput) getEditorInput();
37
        
38
        int index = addPage( this.librarySourceEditor, rootEditorInput );
39
        setPageText( index, "library.xml" );
40
	}
41
42
	@Override
43
	protected IModelElement createModel() 
44
	{
45
		this.modelLibrary = ILibrary.TYPE.instantiate(new RootXmlResource(new XmlEditorResourceStore(this, this.librarySourceEditor)));
46
		return this.modelLibrary;
47
	}
48
49
	@Override
50
	protected void createDiagramPages() throws PartInitException
51
	{
52
		IPath path = new Path( "org.eclipse.sapphire.samples/sdef/LibraryEditor.sdef/diagram" );
53
		this.libraryDiagramPart = new SapphireDiagramEditorPart(this, this.modelLibrary, path);
54
		SapphireDiagramEditor diagramEditor = this.libraryDiagramPart.getDiagramEditor();
55
		SapphireDiagramEditorInput diagramEditorInput = this.libraryDiagramPart.getDiagramEditorInput();
56
		addPage(0, diagramEditor, diagramEditorInput);
57
		setPageText( 0, "Diagram" );
58
		setPageId(this.pages.get(0), "Diagram");
59
	}
60
	
61
	@Override
62
	protected void createFormPages() throws PartInitException 
63
	{
64
		IPath path = new Path( "org.eclipse.sapphire.samples/sdef/LibraryEditor.sdef/overview" );
65
		this.libraryOverviewPage = new MasterDetailsPage(this, this.modelLibrary, path);
66
        addPage(1, this.libraryOverviewPage);
67
        setPageText(1, "Overview");
68
        setPageId(this.pages.get(1), "Overview");		
69
	}
70
71
	public ILibrary getMap()
72
	{
73
		return this.modelLibrary;
74
	}
75
	
76
	@Override
77
	public void doSave( final IProgressMonitor monitor )
78
	{
79
		super.doSave(monitor);
80
		SapphireDiagramEditor diagramEditor = this.libraryDiagramPart.getDiagramEditor();
81
		diagramEditor.doSave(monitor);
82
	}
83
	
84
    @Override
85
    public void dispose() 
86
    {
87
    	super.dispose();
88
    	if (this.libraryDiagramPart != null)
89
    	{
90
    		this.libraryDiagramPart.dispose();
91
    	}
92
    }
93
}
(-)src/org/eclipse/sapphire/samples/map/IDestination.java (+30 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.map;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ModelElementType;
5
import org.eclipse.sapphire.modeling.Value;
6
import org.eclipse.sapphire.modeling.ValueProperty;
7
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
8
import org.eclipse.sapphire.modeling.annotations.Label;
9
import org.eclipse.sapphire.modeling.annotations.NonNullValue;
10
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
11
12
@GenerateImpl
13
14
public interface IDestination extends IModelElement 
15
{
16
	ModelElementType TYPE = new ModelElementType( IDestination.class );
17
	
18
    // *** Name ***
19
    
20
    @XmlBinding( path = "name" )
21
    @Label( standard = "name" )
22
    @NonNullValue
23
    //@DefaultValue( text = "Destination" )
24
25
    ValueProperty PROP_NAME = new ValueProperty( TYPE, "Name" );
26
27
    Value<String> getName();
28
    void setName( String name );
29
	
30
}
(-)src/org/eclipse/sapphire/samples/map/IMap.java (+37 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.map;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ListProperty;
5
import org.eclipse.sapphire.modeling.ModelElementList;
6
import org.eclipse.sapphire.modeling.ModelElementType;
7
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
8
import org.eclipse.sapphire.modeling.annotations.Type;
9
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
10
import org.eclipse.sapphire.modeling.xml.annotations.XmlRootBinding;
11
12
@GenerateImpl
13
@XmlRootBinding( elementName = "map")
14
15
public interface IMap extends IModelElement
16
{
17
	ModelElementType TYPE = new ModelElementType( IMap.class );
18
	
19
    // *** Destinations ***
20
21
    @Type( base = IDestination.class )
22
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "destination", type = IDestination.class ) )
23
    
24
    ListProperty PROP_DESTINATIONS = new ListProperty( TYPE, "Destinations" );
25
    
26
    ModelElementList<IDestination> getDestinations();
27
	
28
    // *** Routes ***
29
    
30
    @Type( base = IRoute.class )
31
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "route", type = IRoute.class ) )
32
    
33
    ListProperty PROP_ROUTES = new ListProperty( TYPE, "Routes" );
34
    
35
    ModelElementList<IRoute> getRoutes();
36
    
37
}
(-)src/org/eclipse/sapphire/samples/map/IRoute.java (+56 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.map;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ModelElementType;
5
import org.eclipse.sapphire.modeling.ReferenceValue;
6
import org.eclipse.sapphire.modeling.Value;
7
import org.eclipse.sapphire.modeling.ValueProperty;
8
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
9
import org.eclipse.sapphire.modeling.annotations.Label;
10
import org.eclipse.sapphire.modeling.annotations.NonNullValue;
11
import org.eclipse.sapphire.modeling.annotations.Reference;
12
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
13
import org.eclipse.sapphire.samples.map.internal.DestinationReferenceService;
14
15
@GenerateImpl
16
17
public interface IRoute extends IModelElement 
18
{
19
	ModelElementType TYPE = new ModelElementType( IRoute.class );
20
	
21
	// *** FromDestination ***
22
	
23
	@Reference( target = IDestination.class, service = DestinationReferenceService.class )
24
	@XmlBinding( path = "from-destination")
25
	@NonNullValue
26
	@Label(standard = "from destination")
27
28
	ValueProperty PROP_FROM_DESTINATION = new ValueProperty( TYPE, "FromDestination" );
29
30
    ReferenceValue<IDestination> getFromDestination();
31
    void setFromDestination( String name );
32
	
33
	// *** ToDestination ***
34
	
35
	@Reference( target = IDestination.class, service = DestinationReferenceService.class )
36
	@XmlBinding( path = "to-destination")
37
	@NonNullValue
38
	@Label(standard = "to destination")
39
40
	ValueProperty PROP_TO_DESTINATION = new ValueProperty( TYPE, "ToDestination" );
41
42
    ReferenceValue<IDestination> getToDestination();
43
    void setToDestination( String name );
44
    
45
    // *** Distance ***
46
    
47
    @XmlBinding( path = "distance" )
48
    @Label( standard = "distance" )
49
    @NonNullValue
50
51
    ValueProperty PROP_DISTANCE = new ValueProperty( TYPE, "Distance" );
52
53
    Value<String> getDistance();
54
    void setDistance( String distance );
55
    
56
}
(-)src/org/eclipse/sapphire/samples/map/internal/DestinationReferenceService.java (+29 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.map.internal;
2
3
import org.eclipse.sapphire.modeling.ModelElementList;
4
import org.eclipse.sapphire.modeling.ReferenceService;
5
import org.eclipse.sapphire.samples.map.IDestination;
6
import org.eclipse.sapphire.samples.map.IMap;
7
8
public class DestinationReferenceService extends ReferenceService 
9
{
10
11
	@Override
12
	public Object resolve(String reference) 
13
	{
14
		if (reference != null)
15
		{
16
			IMap map = element().nearest(IMap.class);
17
			ModelElementList<IDestination> dests = map.getDestinations();
18
			for (IDestination dest : dests)
19
			{
20
				if (reference.equals(dest.getName().getContent()))
21
				{
22
					return dest;
23
				}
24
			}
25
		}
26
		return null;
27
	}
28
29
}
(-)src/org/eclipse/sapphire/samples/map/ui/MapEditor.java (+94 lines)
Added Link Here
1
package org.eclipse.sapphire.samples.map.ui;
2
3
import org.eclipse.core.runtime.IPath;
4
import org.eclipse.core.runtime.IProgressMonitor;
5
import org.eclipse.core.runtime.Path;
6
import org.eclipse.sapphire.modeling.IModelElement;
7
import org.eclipse.sapphire.modeling.xml.RootXmlResource;
8
import org.eclipse.sapphire.samples.map.IMap;
9
import org.eclipse.sapphire.ui.SapphireEditor;
10
import org.eclipse.sapphire.ui.diagram.editor.SapphireDiagramEditorPart;
11
import org.eclipse.sapphire.ui.diagram.graphiti.editor.SapphireDiagramEditor;
12
import org.eclipse.sapphire.ui.diagram.graphiti.editor.SapphireDiagramEditorInput;
13
import org.eclipse.sapphire.ui.editor.views.masterdetails.MasterDetailsPage;
14
import org.eclipse.sapphire.ui.xml.XmlEditorResourceStore;
15
import org.eclipse.ui.PartInitException;
16
import org.eclipse.ui.part.FileEditorInput;
17
import org.eclipse.wst.sse.ui.StructuredTextEditor;
18
19
public class MapEditor extends SapphireEditor 
20
{
21
	private IMap modelMap;
22
	private StructuredTextEditor mapSourceEditor;
23
	private SapphireDiagramEditorPart mapDiagramPart;
24
	private MasterDetailsPage mapOverviewPage;
25
	
26
    public MapEditor()
27
    {
28
        super( "org.eclipse.sapphire.samples" );
29
    }
30
31
	@Override
32
	protected void createSourcePages() throws PartInitException 
33
	{
34
		this.mapSourceEditor = new StructuredTextEditor();
35
		this.mapSourceEditor.setEditorPart(this);
36
        final FileEditorInput rootEditorInput = (FileEditorInput) getEditorInput();
37
        
38
        int index = addPage( this.mapSourceEditor, rootEditorInput );
39
        setPageText( index, "map.xml" );
40
	}
41
42
	@Override
43
	protected IModelElement createModel() 
44
	{
45
		this.modelMap = IMap.TYPE.instantiate(new RootXmlResource(new XmlEditorResourceStore(this, this.mapSourceEditor)));
46
		return this.modelMap;
47
	}
48
49
	@Override
50
	protected void createDiagramPages() throws PartInitException
51
	{
52
		IPath path = new Path( "org.eclipse.sapphire.samples/sdef/MapEditor.sdef/diagram" );
53
		this.mapDiagramPart = new SapphireDiagramEditorPart(this, this.modelMap, path);
54
		SapphireDiagramEditor diagramEditor = this.mapDiagramPart.getDiagramEditor();
55
		SapphireDiagramEditorInput diagramEditorInput = this.mapDiagramPart.getDiagramEditorInput();
56
		addPage(0, diagramEditor, diagramEditorInput);
57
		setPageText( 0, "Diagram" );
58
		setPageId(this.pages.get(0), "Diagram");
59
	}
60
	
61
	@Override
62
	protected void createFormPages() throws PartInitException 
63
	{
64
		IPath path = new Path( "org.eclipse.sapphire.samples/sdef/MapEditor.sdef/overview" );
65
		this.mapOverviewPage = new MasterDetailsPage(this, this.modelMap, path);
66
        addPage(1, this.mapOverviewPage);
67
        setPageText(1, "Overview");
68
        setPageId(this.pages.get(1), "Overview");		
69
	}
70
71
	public IMap getMap()
72
	{
73
		return this.modelMap;
74
	}
75
	
76
	@Override
77
	public void doSave( final IProgressMonitor monitor )
78
	{
79
		super.doSave(monitor);
80
		SapphireDiagramEditor diagramEditor = this.mapDiagramPart.getDiagramEditor();
81
		diagramEditor.doSave(monitor);
82
	}
83
	
84
    @Override
85
    public void dispose() 
86
    {
87
    	super.dispose();
88
    	if (this.mapDiagramPart != null)
89
    	{
90
    		this.mapDiagramPart.dispose();
91
    	}
92
    }
93
	
94
}
(-)META-INF/MANIFEST.MF (-2 / +12 lines)
Lines 19-25 Link Here
19
 org.eclipse.sapphire.ui.swt.renderer,
19
 org.eclipse.sapphire.ui.swt.renderer,
20
 org.eclipse.sapphire.ui.swt.renderer.actions,
20
 org.eclipse.sapphire.ui.swt.renderer.actions,
21
 org.eclipse.sapphire.ui.util,
21
 org.eclipse.sapphire.ui.util,
22
 org.eclipse.sapphire.ui.xml
22
 org.eclipse.sapphire.ui.xml,
23
 org.eclipse.sapphire.ui.diagram.editor,
24
 org.eclipse.sapphire.ui.diagram.graphiti.editor
23
Require-Bundle: org.eclipse.debug.ui,
25
Require-Bundle: org.eclipse.debug.ui,
24
 org.eclipse.jdt.ui,
26
 org.eclipse.jdt.ui,
25
 org.eclipse.ui.forms;visibility:=reexport,
27
 org.eclipse.ui.forms;visibility:=reexport,
Lines 36-42 Link Here
36
 org.eclipse.ui.workbench,
38
 org.eclipse.ui.workbench,
37
 org.eclipse.help,
39
 org.eclipse.help,
38
 org.eclipse.ui.views,
40
 org.eclipse.ui.views,
39
 org.eclipse.jface.text
41
 org.eclipse.jface.text,
42
 org.apache.ant,
43
 org.eclipse.gef,
44
 org.eclipse.graphiti,
45
 org.eclipse.graphiti.mm,
46
 org.eclipse.graphiti.pattern,
47
 org.eclipse.graphiti.ui,
48
 org.eclipse.emf.transaction,
49
 org.eclipse.ui.views.properties.tabbed
40
Import-Package: com.ibm.icu.text
50
Import-Package: com.ibm.icu.text
41
Bundle-ActivationPolicy: lazy
51
Bundle-ActivationPolicy: lazy
42
Bundle-RequiredExecutionEnvironment: J2SE-1.5
52
Bundle-RequiredExecutionEnvironment: J2SE-1.5
(-)plugin.properties (+8 lines)
Lines 14-16 Link Here
14
jumpCommandDescription = Shows the entity represented by the text value currently in the field.
14
jumpCommandDescription = Shows the entity represented by the text value currently in the field.
15
showInSourceCommandName = Show in Source
15
showInSourceCommandName = Show in Source
16
showInSourceCommandDescription = Shows the location in the source file that corresponds to the selected entity.
16
showInSourceCommandDescription = Shows the location in the source file that corresponds to the selected entity.
17
<<<<<<< plugin.properties
18
builderName = Sapphire UI Builder
19
sapphireDiagramTypeDescription = Sapphire Diagram Type
20
sapphireDiagramTypeName = Sapphire Diagram Type
21
sapphireDiagramTypeProviderDescription = Sapphire Diagram Type Provider
22
sapphireDiagramTypeProviderName = Sapphire Diagram Type Provider
23
=======
24
>>>>>>> 1.3
(-)plugin.xml (-1 / +29 lines)
Lines 17-21 Link Here
17
<plugin>
17
<plugin>
18
18
19
  <extension point="org.eclipse.sapphire.modeling.extension"/>
19
  <extension point="org.eclipse.sapphire.modeling.extension"/>
20
20
  
21
   <extension point="org.eclipse.graphiti.ui.diagramTypes">
22
      <diagramType
23
            description="%sapphireDiagramTypeDescription"
24
            id="org.eclipse.sapphire.ui.SapphireDiagramType"
25
            name="%sapphireDiagramTypeName"
26
            type="sapphireDiagram">
27
      </diagramType>
28
   </extension>
29
   
30
   <extension point="org.eclipse.graphiti.ui.diagramTypeProviders">
31
      <diagramTypeProvider
32
            class="org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramTypeProvider"
33
            description="%sapphireDiagramTypeProviderDescription"
34
            id="org.eclipse.sapphire.ui.sapphireDiagramTypeProvider"
35
            name="%sapphireDiagramTypeProviderName">
36
         <diagramType id="org.eclipse.sapphire.ui.SapphireDiagramType"/>
37
         <imageProvider id="org.eclipse.sapphire.diagram.graphiti.SapphireDiagramImageProvider"/>
38
      </diagramTypeProvider>
39
   </extension>
40
     
41
   <extension
42
         point="org.eclipse.graphiti.ui.imageProviders">
43
      <imageProvider
44
            class="org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramImageProvider"
45
            id="org.eclipse.sapphire.diagram.graphiti.SapphireDiagramImageProvider">
46
      </imageProvider>
47
   </extension>
48
     
21
</plugin>
49
</plugin>
(-)src/org/eclipse/sapphire/ui/SapphireEditor.java (-1 / +10 lines)
Lines 18-23 Link Here
18
import java.net.URI;
18
import java.net.URI;
19
import java.util.Collections;
19
import java.util.Collections;
20
import java.util.HashMap;
20
import java.util.HashMap;
21
import java.util.Iterator;
21
import java.util.Map;
22
import java.util.Map;
22
import java.util.Set;
23
import java.util.Set;
23
24
Lines 285-290 Link Here
285
                this.model = createModel();
286
                this.model = createModel();
286
                adaptModel( this.model );
287
                adaptModel( this.model );
287
                
288
                
289
                createDiagramPages();
290
                
288
                createFormPages();
291
                createFormPages();
289
    
292
    
290
                createFileChangeListener();
293
                createFileChangeListener();
Lines 330-335 Link Here
330
    protected abstract void createSourcePages() throws PartInitException;
333
    protected abstract void createSourcePages() throws PartInitException;
331
    protected abstract void createFormPages() throws PartInitException;
334
    protected abstract void createFormPages() throws PartInitException;
332
    
335
    
336
    // default impl does nothing, subclass may override it to add diagram pages
337
    protected void createDiagramPages() throws PartInitException
338
    {
339
    	
340
    }
341
    
333
    protected final void setPageId( final Object page,
342
    protected final void setPageId( final Object page,
334
                                    final String id )
343
                                    final String id )
335
    {
344
    {
Lines 496-502 Link Here
496
    }
505
    }
497
506
498
    @Override
507
    @Override
499
    public final void dispose() 
508
    public void dispose() 
500
    {
509
    {
501
        super.dispose();
510
        super.dispose();
502
        
511
        
(-)src/org/eclipse/sapphire/ui/def/ISapphireUiDef.java (+10 lines)
Lines 26-31 Link Here
26
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
26
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
27
import org.eclipse.sapphire.modeling.xml.annotations.XmlRootBinding;
27
import org.eclipse.sapphire.modeling.xml.annotations.XmlRootBinding;
28
import org.eclipse.sapphire.ui.def.internal.SapphireUiDefMethods;
28
import org.eclipse.sapphire.ui.def.internal.SapphireUiDefMethods;
29
import org.eclipse.sapphire.ui.diagram.def.IDiagramPageDef;
29
30
30
/**
31
/**
31
 * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
32
 * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
Lines 129-134 Link Here
129
    
130
    
130
    ModelElementList<IEditorPageDef> getEditorPageDefs();
131
    ModelElementList<IEditorPageDef> getEditorPageDefs();
131
    
132
    
133
    // *** DiagramPageDefs ***
134
    
135
    @Type( base = IDiagramPageDef.class )
136
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "diagram-page", type = IDiagramPageDef.class ) )
137
    
138
    ListProperty PROP_DIAGRAM_PAGE_DEFS = new ListProperty( TYPE, "DiagramPageDefs" );
139
    
140
    ModelElementList<IDiagramPageDef> getDiagramPageDefs();
141
    
132
    // *** DialogDefs ***
142
    // *** DialogDefs ***
133
    
143
    
134
    @Type( base = ISapphireDialogDef.class )
144
    @Type( base = ISapphireDialogDef.class )
(-)src/org/eclipse/sapphire/ui/def/SapphireDiagramDefFactory.java (+51 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.def;
2
3
import org.eclipse.sapphire.modeling.BundleResourceStore;
4
import org.eclipse.sapphire.modeling.ResourceStoreException;
5
import org.eclipse.sapphire.modeling.SharedModelsCache;
6
import org.eclipse.sapphire.modeling.xml.RootXmlResource;
7
import org.eclipse.sapphire.modeling.xml.XmlResourceStore;
8
import org.eclipse.sapphire.ui.diagram.def.IDiagramPageDef;
9
import org.eclipse.sapphire.ui.internal.SapphireUiFrameworkPlugin;
10
11
public class SapphireDiagramDefFactory 
12
{
13
	public static IDiagramPageDef load(final String bundleId, final String path)
14
	{
15
        try
16
        {
17
            return load( new XmlResourceStore( new BundleResourceStore( bundleId, path ) ), false );
18
        }
19
        catch( ResourceStoreException e )
20
        {
21
            SapphireUiFrameworkPlugin.log( e );
22
            return null;
23
        }		
24
	}
25
	
26
	public static IDiagramPageDef load( final XmlResourceStore resourceStore,
27
            							final boolean writable )
28
	{
29
		IDiagramPageDef model;
30
31
		if( writable )
32
		{
33
			model = IDiagramPageDef.TYPE.instantiate( new RootXmlResource( resourceStore ) );
34
		}
35
		else
36
		{
37
			final SharedModelsCache.StandardKey key = new SharedModelsCache.StandardKey( resourceStore, IDiagramPageDef.TYPE );
38
			
39
			model = (IDiagramPageDef) SharedModelsCache.retrieve( key );
40
			
41
			if( model == null )
42
			{
43
				model = IDiagramPageDef.TYPE.instantiate( new RootXmlResource( resourceStore ) );
44
				SharedModelsCache.store( key, model );			
45
			}	
46
		}
47
		return model;
48
	}
49
50
}
51
(-)src/org/eclipse/sapphire/ui/diagram/def/ConnectionEndpointType.java (+10 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.def;
2
3
4
public enum ConnectionEndpointType 
5
{
6
	NONE,
7
	ARROW,
8
	CIRCLE,
9
	ELLIPSE;
10
}
(-)src/org/eclipse/sapphire/ui/diagram/def/IDiagramConnectionDef.java (+105 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.def;
2
3
import org.eclipse.sapphire.modeling.ElementProperty;
4
import org.eclipse.sapphire.modeling.ModelElementHandle;
5
import org.eclipse.sapphire.modeling.ModelElementType;
6
import org.eclipse.sapphire.modeling.Value;
7
import org.eclipse.sapphire.modeling.ValueProperty;
8
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
9
import org.eclipse.sapphire.modeling.annotations.Label;
10
import org.eclipse.sapphire.modeling.annotations.Type;
11
import org.eclipse.sapphire.modeling.el.Function;
12
import org.eclipse.sapphire.modeling.localization.Localizable;
13
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
14
import org.eclipse.sapphire.ui.def.ISapphirePartDef;
15
16
@GenerateImpl
17
18
public interface IDiagramConnectionDef 
19
	
20
	extends ISapphirePartDef 
21
	
22
{
23
	ModelElementType TYPE = new ModelElementType( IDiagramConnectionDef.class );
24
	
25
    // *** Id ***
26
    
27
    @Label( standard = "ID" )
28
    @XmlBinding( path = "id" )
29
    
30
    ValueProperty PROP_ID = new ValueProperty( TYPE, "Id" );
31
    
32
    Value<String> getId();
33
    void setId( String id );
34
    
35
    // *** Property ***
36
    
37
    @Label( standard = "property" )
38
    @XmlBinding( path = "property" )
39
    
40
    ValueProperty PROP_PROPERTY = new ValueProperty( TYPE, "Property" );
41
    
42
    Value<String> getProperty();
43
    void setProperty( String property );
44
    
45
    // *** ToolPaletteLabel ***
46
    
47
    @Label( standard = "tool palette label" )
48
    @XmlBinding( path = "tool-palette-label" )
49
    
50
    ValueProperty PROP_TOOL_PALETTE_LABEL = new ValueProperty( TYPE, "ToolPaletteLabel" );
51
    
52
    Value<String> getToolPaletteLabel();
53
    void setToolPaletteLabel( String paletteLabel );
54
    
55
    // *** ToolPaletteDesc ***
56
    
57
    @Label( standard = "tool palette description" )
58
    @XmlBinding( path = "tool-palette-desc" )
59
    
60
    ValueProperty PROP_TOOL_PALETTE_DESC = new ValueProperty( TYPE, "ToolPaletteDesc" );
61
    
62
    Value<String> getToolPaletteDesc();
63
    void setToolPaletteDesc( String paletteDesc );    
64
        
65
    // *** Label ***
66
    
67
    @Type( base = IDiagramLabelDef.class )
68
    @XmlBinding( path = "label" )
69
    
70
    ElementProperty PROP_LABEL = new ElementProperty( TYPE, "Label" );
71
    
72
    ModelElementHandle<IDiagramLabelDef> getLabel();
73
74
    // *** Endpoint1 ***
75
    
76
    @Type( base = IDiagramConnectionEndpointDef.class )
77
    @XmlBinding( path = "endpoint1" )
78
79
    ElementProperty PROP_ENDPOINT_1 = new ElementProperty( TYPE, "Endpoint1" );
80
    
81
    ModelElementHandle<IDiagramConnectionEndpointDef> getEndpoint1();
82
83
    // *** Endpoint2 ***
84
    
85
    @Type( base = IDiagramConnectionEndpointDef.class )
86
    @XmlBinding( path = "endpoint2" )
87
88
    ElementProperty PROP_ENDPOINT_2 = new ElementProperty( TYPE, "Endpoint2" );
89
    
90
    ModelElementHandle<IDiagramConnectionEndpointDef> getEndpoint2();
91
    
92
    // *** InstanceId ***
93
    
94
    @Type( base = Function.class )
95
    @Label( standard = "instance id" )
96
    @Localizable
97
    @XmlBinding( path = "instance-id" )
98
    
99
    ValueProperty PROP_INSTANCE_ID = new ValueProperty( TYPE, "InstanceId" );
100
    
101
    Value<Function> getInstanceId();
102
    void setInstanceId( String value );
103
    void setInstanceId( Function value );
104
            
105
}
(-)src/org/eclipse/sapphire/ui/diagram/def/IDiagramConnectionEndpointDef.java (+58 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.def;
2
3
import org.eclipse.sapphire.modeling.ModelElementType;
4
import org.eclipse.sapphire.modeling.Value;
5
import org.eclipse.sapphire.modeling.ValueProperty;
6
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
7
import org.eclipse.sapphire.modeling.annotations.Label;
8
import org.eclipse.sapphire.modeling.annotations.Type;
9
import org.eclipse.sapphire.modeling.el.Function;
10
import org.eclipse.sapphire.modeling.localization.Localizable;
11
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
12
import org.eclipse.sapphire.ui.def.ISapphirePartDef;
13
14
@GenerateImpl
15
16
public interface IDiagramConnectionEndpointDef 
17
18
	extends ISapphirePartDef 
19
	
20
{
21
	ModelElementType TYPE = new ModelElementType( IDiagramConnectionEndpointDef.class );
22
	
23
    // *** Property ***
24
    
25
    @Label( standard = "property" )
26
    @XmlBinding( path = "property" )
27
    
28
    ValueProperty PROP_PROPERTY = new ValueProperty( TYPE, "Property" );
29
    
30
    Value<String> getProperty();
31
    void setProperty( String property );
32
    
33
    // *** Value ***
34
35
    @Type( base = Function.class )
36
    @Label( standard = "value" )
37
    @Localizable
38
    @XmlBinding( path = "value" )
39
    
40
    ValueProperty PROP_VALUE = new ValueProperty( TYPE, "Value" );
41
    
42
    Value<Function> getValue();
43
    void setValue( String value );
44
    void setValue( Function value );
45
        
46
	// *** Type ***
47
	
48
	@Type( base = ConnectionEndpointType.class )
49
	@XmlBinding( path = "type" )
50
	
51
	ValueProperty PROP_TYPE = new ValueProperty( TYPE, "Type" );
52
	
53
	Value<ConnectionEndpointType> getType();
54
	void setType( String value );
55
	void setType( ConnectionEndpointType value );
56
    
57
	
58
}
(-)src/org/eclipse/sapphire/ui/diagram/def/IDiagramEmbeddedConnectionDef.java (+96 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.def;
2
3
import org.eclipse.sapphire.modeling.ElementProperty;
4
import org.eclipse.sapphire.modeling.ModelElementHandle;
5
import org.eclipse.sapphire.modeling.ModelElementType;
6
import org.eclipse.sapphire.modeling.Value;
7
import org.eclipse.sapphire.modeling.ValueProperty;
8
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
9
import org.eclipse.sapphire.modeling.annotations.Label;
10
import org.eclipse.sapphire.modeling.annotations.Type;
11
import org.eclipse.sapphire.modeling.el.Function;
12
import org.eclipse.sapphire.modeling.localization.Localizable;
13
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
14
import org.eclipse.sapphire.ui.def.ISapphirePartDef;
15
16
@GenerateImpl
17
18
public interface IDiagramEmbeddedConnectionDef 
19
20
	extends ISapphirePartDef
21
	
22
{
23
	ModelElementType TYPE = new ModelElementType( IDiagramEmbeddedConnectionDef.class );
24
	
25
    // *** Id ***
26
    
27
    @Label( standard = "ID" )
28
    @XmlBinding( path = "id" )
29
    
30
    ValueProperty PROP_ID = new ValueProperty( TYPE, "Id" );
31
    
32
    Value<String> getId();
33
    void setId( String id );
34
    
35
    // *** Property ***
36
    
37
    @Label( standard = "property" )
38
    @XmlBinding( path = "property" )
39
    
40
    ValueProperty PROP_PROPERTY = new ValueProperty( TYPE, "Property" );
41
    
42
    Value<String> getProperty();
43
    void setProperty( String property );
44
    
45
    // *** ToolPaletteLabel ***
46
    
47
    @Label( standard = "tool palette label" )
48
    @XmlBinding( path = "tool-palette-label" )
49
    
50
    ValueProperty PROP_TOOL_PALETTE_LABEL = new ValueProperty( TYPE, "ToolPaletteLabel" );
51
    
52
    Value<String> getToolPaletteLabel();
53
    void setToolPaletteLabel( String paletteLabel );
54
    
55
    // *** ToolPaletteDesc ***
56
    
57
    @Label( standard = "tool palette description" )
58
    @XmlBinding( path = "tool-palette-desc" )
59
    
60
    ValueProperty PROP_TOOL_PALETTE_DESC = new ValueProperty( TYPE, "ToolPaletteDesc" );
61
    
62
    Value<String> getToolPaletteDesc();
63
    void setToolPaletteDesc( String paletteDesc );    
64
        
65
    // *** Label ***
66
    
67
    @Type( base = IDiagramLabelDef.class )
68
    @XmlBinding( path = "label" )
69
    
70
    ElementProperty PROP_LABEL = new ElementProperty( TYPE, "Label" );
71
    
72
    ModelElementHandle<IDiagramLabelDef> getLabel();
73
    	    
74
    // *** Endpoint ***
75
    
76
    @Type( base = IDiagramConnectionEndpointDef.class )
77
    @XmlBinding( path = "endpoint" )
78
79
    ElementProperty PROP_ENDPOINT = new ElementProperty( TYPE, "Endpoint" );
80
    
81
    ModelElementHandle<IDiagramConnectionEndpointDef> getEndpoint();
82
83
    // *** InstanceId ***
84
    
85
    @Type( base = Function.class )
86
    @Label( standard = "instance id" )
87
    @Localizable
88
    @XmlBinding( path = "instance-id" )
89
    
90
    ValueProperty PROP_INSTANCE_ID = new ValueProperty( TYPE, "InstanceId" );
91
    
92
    Value<Function> getInstanceId();
93
    void setInstanceId( String value );
94
    void setInstanceId( Function value );
95
96
}
(-)src/org/eclipse/sapphire/ui/diagram/def/IDiagramImageChoice.java (+40 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.def;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ModelElementType;
5
import org.eclipse.sapphire.modeling.Value;
6
import org.eclipse.sapphire.modeling.ValueProperty;
7
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
8
import org.eclipse.sapphire.modeling.annotations.Label;
9
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
10
11
@GenerateImpl
12
13
public interface IDiagramImageChoice 
14
15
	extends IModelElement
16
	
17
{
18
	ModelElementType TYPE = new ModelElementType( IDiagramImageChoice.class );
19
	
20
    // *** ImageId ***
21
    
22
    @Label( standard = "image id" )
23
    @XmlBinding( path = "id" )
24
    
25
    ValueProperty PROP_IMAGE_ID = new ValueProperty( TYPE, "ImageId" );
26
    
27
    Value<String> getImageId();
28
    void setImageId( String Id );
29
30
    // *** ImagePath ***
31
    
32
    @Label( standard = "image path" )
33
    @XmlBinding( path = "path" )
34
    
35
    ValueProperty PROP_IMAGE_PATH = new ValueProperty( TYPE, "ImagePath" );
36
    
37
    Value<String> getImagePath();
38
    void setImagePath( String path );
39
	
40
}
(-)src/org/eclipse/sapphire/ui/diagram/def/IDiagramLabelDef.java (+36 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.def;
2
3
import org.eclipse.sapphire.modeling.ModelElementType;
4
import org.eclipse.sapphire.modeling.Value;
5
import org.eclipse.sapphire.modeling.ValueProperty;
6
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
7
import org.eclipse.sapphire.modeling.annotations.Label;
8
import org.eclipse.sapphire.modeling.annotations.Type;
9
import org.eclipse.sapphire.modeling.el.Function;
10
import org.eclipse.sapphire.modeling.localization.Localizable;
11
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
12
import org.eclipse.sapphire.ui.def.ISapphirePartDef;
13
14
@GenerateImpl
15
16
public interface IDiagramLabelDef 
17
18
	extends ISapphirePartDef
19
	
20
{
21
	ModelElementType TYPE = new ModelElementType( IDiagramLabelDef.class );
22
	
23
    // *** Content ***
24
    
25
    @Type( base = Function.class )
26
    @Label( standard = "content" )
27
    @Localizable
28
    @XmlBinding( path = "content" )
29
    
30
    ValueProperty PROP_CONTENT = new ValueProperty( TYPE, "Content" );
31
    
32
    Value<Function> getContent();
33
    void setContent( String value );
34
    void setContent( Function value );
35
    
36
}
(-)src/org/eclipse/sapphire/ui/diagram/def/IDiagramNodeDef.java (+118 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.def;
2
3
import org.eclipse.sapphire.modeling.ElementProperty;
4
import org.eclipse.sapphire.modeling.ListProperty;
5
import org.eclipse.sapphire.modeling.ModelElementHandle;
6
import org.eclipse.sapphire.modeling.ModelElementList;
7
import org.eclipse.sapphire.modeling.ModelElementType;
8
import org.eclipse.sapphire.modeling.Value;
9
import org.eclipse.sapphire.modeling.ValueProperty;
10
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
11
import org.eclipse.sapphire.modeling.annotations.Label;
12
import org.eclipse.sapphire.modeling.annotations.Type;
13
import org.eclipse.sapphire.modeling.el.Function;
14
import org.eclipse.sapphire.modeling.localization.Localizable;
15
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
16
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
17
import org.eclipse.sapphire.ui.def.ISapphirePartDef;
18
19
@GenerateImpl
20
21
public interface IDiagramNodeDef 
22
23
	extends ISapphirePartDef
24
	
25
{
26
	ModelElementType TYPE = new ModelElementType( IDiagramNodeDef.class );
27
	
28
    // *** Id ***
29
    
30
    @Label( standard = "ID" )
31
    @XmlBinding( path = "id" )
32
    
33
    ValueProperty PROP_ID = new ValueProperty( TYPE, "Id" );
34
    
35
    Value<String> getId();
36
    void setId( String id );
37
    
38
    // *** ToolPaletteLabel ***
39
    
40
    @Label( standard = "tool palette label" )
41
    @XmlBinding( path = "tool-palette-label" )
42
    
43
    ValueProperty PROP_TOOL_PALETTE_LABEL = new ValueProperty( TYPE, "ToolPaletteLabel" );
44
    
45
    Value<String> getToolPaletteLabel();
46
    void setToolPaletteLabel( String paletteLabel );
47
    
48
    // *** ToolPaletteDesc ***
49
    
50
    @Label( standard = "tool palette description" )
51
    @XmlBinding( path = "tool-palette-desc" )
52
    
53
    ValueProperty PROP_TOOL_PALETTE_DESC = new ValueProperty( TYPE, "ToolPaletteDesc" );
54
    
55
    Value<String> getToolPaletteDesc();
56
    void setToolPaletteDesc( String paletteDesc );
57
58
    // *** Property ***
59
    
60
    @Label( standard = "property" )
61
    @XmlBinding( path = "property" )
62
    
63
    ValueProperty PROP_PROPERTY = new ValueProperty( TYPE, "Property" );
64
    
65
    Value<String> getProperty();
66
    void setProperty( String property );
67
    
68
	// *** PossibleImages ***
69
    
70
    @Type( base = IDiagramImageChoice.class )
71
    @XmlListBinding( path = "possibleImages",
72
    				mappings = @XmlListBinding.Mapping( element = "imageChoice", type = IDiagramImageChoice.class ) )
73
                             
74
    ListProperty PROP_POSSIBLE_IMAGES = new ListProperty( TYPE, "PossibleImages" );
75
    
76
    ModelElementList<IDiagramImageChoice> getPossibleImages();
77
    
78
    // *** Image ***
79
    
80
    @Type( base = IDiagramNodeImageDef.class )
81
    @XmlBinding( path = "image" )
82
83
    ElementProperty PROP_IMAGE = new ElementProperty( TYPE, "Image" );
84
    
85
    ModelElementHandle<IDiagramNodeImageDef> getImage();
86
    
87
    // *** Label ***
88
    
89
    @Type( base = IDiagramLabelDef.class )
90
    @XmlBinding( path = "label" )
91
    
92
    ElementProperty PROP_LABEL = new ElementProperty( TYPE, "Label" );
93
    
94
    ModelElementHandle<IDiagramLabelDef> getLabel();
95
    	    
96
    // *** InstanceId ***
97
    
98
    @Type( base = Function.class )
99
    @Label( standard = "instance id" )
100
    @Localizable
101
    @XmlBinding( path = "instance-id" )
102
    
103
    ValueProperty PROP_INSTANCE_ID = new ValueProperty( TYPE, "InstanceId" );
104
    
105
    Value<Function> getInstanceId();
106
    void setInstanceId( String value );
107
    void setInstanceId( Function value );
108
        
109
    // *** EmbeddedConnections ***
110
    
111
    @Type( base = IDiagramEmbeddedConnectionDef.class )
112
    @XmlBinding( path = "connection" )
113
114
    ElementProperty PROP_EMBEDDED_CONNECTIONS = new ElementProperty( TYPE, "EmbeddedConnections" );
115
    
116
    ModelElementHandle<IDiagramEmbeddedConnectionDef> getEmbeddedConnections();
117
    
118
}
(-)src/org/eclipse/sapphire/ui/diagram/def/IDiagramNodeImageDef.java (+36 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.def;
2
3
import org.eclipse.sapphire.modeling.ModelElementType;
4
import org.eclipse.sapphire.modeling.Value;
5
import org.eclipse.sapphire.modeling.ValueProperty;
6
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
7
import org.eclipse.sapphire.modeling.annotations.Label;
8
import org.eclipse.sapphire.modeling.annotations.Type;
9
import org.eclipse.sapphire.modeling.el.Function;
10
import org.eclipse.sapphire.modeling.localization.Localizable;
11
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
12
import org.eclipse.sapphire.ui.def.ISapphirePartDef;
13
14
@GenerateImpl
15
16
public interface IDiagramNodeImageDef 
17
18
	extends ISapphirePartDef 
19
20
{
21
	ModelElementType TYPE = new ModelElementType( IDiagramNodeImageDef.class );
22
23
	// *** Value ***
24
25
    @Type( base = Function.class )
26
    @Label( standard = "value" )
27
    @Localizable
28
    @XmlBinding( path = "value" )
29
    
30
    ValueProperty PROP_VALUE = new ValueProperty( TYPE, "Value" );
31
    
32
    Value<Function> getValue();
33
    void setValue( String value );
34
    void setValue( Function value );	
35
		
36
}
(-)src/org/eclipse/sapphire/ui/diagram/def/IDiagramPageDef.java (+75 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.def;
2
3
import org.eclipse.sapphire.modeling.ListProperty;
4
import org.eclipse.sapphire.modeling.ModelElementList;
5
import org.eclipse.sapphire.modeling.ModelElementType;
6
import org.eclipse.sapphire.modeling.Value;
7
import org.eclipse.sapphire.modeling.ValueProperty;
8
import org.eclipse.sapphire.modeling.annotations.DefaultValue;
9
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
10
import org.eclipse.sapphire.modeling.annotations.Label;
11
import org.eclipse.sapphire.modeling.annotations.Type;
12
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
13
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
14
import org.eclipse.sapphire.ui.def.ISapphirePartDef;
15
16
@GenerateImpl
17
18
public interface IDiagramPageDef 
19
	
20
	extends ISapphirePartDef
21
	
22
{
23
	ModelElementType TYPE = new ModelElementType( IDiagramPageDef.class);
24
	
25
    // *** Id ***
26
    
27
    @Label( standard = "ID" )
28
    @XmlBinding( path = "id" )
29
    
30
    ValueProperty PROP_ID = new ValueProperty( TYPE, "Id" );
31
    
32
    Value<String> getId();
33
    void setId( String id );
34
    
35
    // *** PageName ***
36
    
37
    @Label( standard = "page name" )
38
    @DefaultValue( text = "Diagram" )
39
    @XmlBinding( path = "page-name" )
40
    
41
    ValueProperty PROP_PAGE_NAME = new ValueProperty( TYPE, "PageName" );
42
    
43
    Value<String> getPageName();
44
    void setPageName( String pageName );
45
    
46
    // *** PageHeaderText ***
47
    
48
    @Label( standard = "page header text" )
49
    @DefaultValue( text = "Diagram View" )
50
    @XmlBinding( path = "page-header-text" )
51
    
52
    ValueProperty PROP_PAGE_HEADER_TEXT = new ValueProperty( TYPE, "PageHeaderText" );
53
    
54
    Value<String> getPageHeaderText();
55
    void setPageHeaderText( String pageHeaderText );
56
	
57
	// *** DiagramNodeDefs ***
58
    
59
    @Type( base = IDiagramNodeDef.class )
60
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "node", type = IDiagramNodeDef.class ) )
61
                             
62
    ListProperty PROP_DIAGRAM_NODE_DEFS = new ListProperty( TYPE, "DiagramNodeDefs" );
63
    
64
    ModelElementList<IDiagramNodeDef> getDiagramNodeDefs();
65
    
66
	// *** DiagramConnectionDefs ***
67
    
68
    @Type( base = IDiagramConnectionDef.class )
69
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "connection", type = IDiagramConnectionDef.class ) )
70
                             
71
    ListProperty PROP_DIAGRAM_CONNECTION_DEFS = new ListProperty( TYPE, "DiagramConnectionDefs" );
72
    
73
    ModelElementList<IDiagramConnectionDef> getDiagramConnectionDefs();
74
	
75
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/DiagramConnectionPart.java (+473 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import org.eclipse.emf.transaction.RecordingCommand;
4
import org.eclipse.emf.transaction.TransactionalEditingDomain;
5
import org.eclipse.emf.transaction.util.TransactionUtil;
6
import org.eclipse.graphiti.features.IAddFeature;
7
import org.eclipse.graphiti.features.IFeatureProvider;
8
import org.eclipse.graphiti.features.IRemoveFeature;
9
import org.eclipse.graphiti.features.context.IRemoveContext;
10
import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
11
import org.eclipse.graphiti.features.context.impl.RemoveContext;
12
import org.eclipse.graphiti.features.context.impl.UpdateContext;
13
import org.eclipse.graphiti.mm.pictograms.Connection;
14
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
15
import org.eclipse.graphiti.mm.pictograms.Diagram;
16
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
17
import org.eclipse.sapphire.modeling.IModelElement;
18
import org.eclipse.sapphire.modeling.ModelElementType;
19
import org.eclipse.sapphire.modeling.ModelProperty;
20
import org.eclipse.sapphire.modeling.ModelPropertyChangeEvent;
21
import org.eclipse.sapphire.modeling.ModelPropertyListener;
22
import org.eclipse.sapphire.modeling.ReferenceValue;
23
import org.eclipse.sapphire.modeling.Value;
24
import org.eclipse.sapphire.modeling.ValueProperty;
25
import org.eclipse.sapphire.modeling.el.FunctionResult;
26
import org.eclipse.sapphire.ui.SapphirePart;
27
import org.eclipse.sapphire.ui.SapphireRenderingContext;
28
import org.eclipse.sapphire.ui.diagram.def.IDiagramConnectionDef;
29
import org.eclipse.sapphire.ui.diagram.def.IDiagramConnectionEndpointDef;
30
31
public class DiagramConnectionPart extends SapphirePart 
32
{
33
	protected DiagramConnectionTemplate connectionTemplate;
34
	private IDiagramConnectionDef localDefinition;
35
	protected IModelElement modelElement;
36
	private IDiagramConnectionEndpointDef endpoint1Def;
37
	private IDiagramConnectionEndpointDef endpoint2Def;
38
	private IModelElement endpoint1Model;
39
	private IModelElement endpoint2Model;
40
	protected FunctionResult labelFunctionResult;
41
	protected ValueProperty labelProperty;
42
	protected FunctionResult idFunctionResult;
43
	private FunctionResult endpoint1FunctionResult;
44
	private FunctionResult endpoint2FunctionResult;
45
	protected ModelPropertyListener modelPropertyListener;
46
	
47
	public DiagramConnectionPart() {}
48
	
49
	public DiagramConnectionPart(DiagramConnectionTemplate connectionTemplate)
50
	{
51
		this.connectionTemplate = connectionTemplate;
52
	}
53
	
54
    @Override
55
    protected void init()
56
    {
57
        super.init();
58
        
59
        this.localDefinition = (IDiagramConnectionDef)super.definition;
60
        this.modelElement = getModelElement();
61
        this.labelFunctionResult = initExpression
62
        ( 
63
        	this.modelElement,
64
        	this.localDefinition.getLabel().element().getContent(), 
65
            new Runnable()
66
            {
67
                public void run()
68
                {
69
                	refreshLabel();
70
                }
71
            }
72
        );
73
        
74
        this.labelProperty = FunctionUtil.getFunctionProperty(this.modelElement, 
75
        		this.labelFunctionResult);
76
        
77
        this.idFunctionResult = initExpression
78
        ( 
79
        	this.modelElement,
80
            this.localDefinition.getInstanceId(), 
81
            new Runnable()
82
            {
83
                public void run()
84
                {
85
                }
86
            }
87
        );
88
        
89
        this.endpoint1Def = this.localDefinition.getEndpoint1().element();        
90
        this.endpoint1Model = processEndpoint(this.endpoint1Def);
91
        if (this.endpoint1Model != null)
92
        {
93
	        this.endpoint1FunctionResult = initExpression
94
	        (
95
	        	this.endpoint1Model, 
96
	        	this.endpoint1Def.getValue(), 
97
	            new Runnable()
98
	        	{
99
		            public void run()
100
		            {
101
		            	refreshEndpoint1();
102
		            }
103
	        	}
104
	        );
105
        }
106
        
107
        this.endpoint2Def = this.localDefinition.getEndpoint2().element();
108
        this.endpoint2Model = processEndpoint(this.endpoint2Def);
109
        if (this.endpoint2Model != null)
110
        {
111
	        this.endpoint2FunctionResult = initExpression
112
	        (
113
	        	this.endpoint2Model, 
114
	        	this.endpoint2Def.getValue(), 
115
	            new Runnable()
116
	        	{
117
		            public void run()
118
		            {
119
		            	refreshEndpoint2();
120
		            }
121
	        	}
122
	        );
123
        }        
124
        
125
        // Add model property listener
126
        this.modelPropertyListener = new ModelPropertyListener()
127
        {
128
            @Override
129
            public void handlePropertyChangedEvent( final ModelPropertyChangeEvent event )
130
            {
131
                handleModelPropertyChange( event );
132
            }
133
        };
134
        addModelListener();        
135
    }
136
    
137
    public DiagramConnectionTemplate getDiagramConnectionTemplate()
138
    {
139
    	return this.connectionTemplate;
140
    }
141
    
142
    public IModelElement getLocalModelElement()
143
    {
144
        return this.modelElement;
145
    }    
146
    
147
    public IModelElement getEndpoint1()
148
    {
149
    	return this.endpoint1Model;
150
    }
151
    
152
    public IModelElement getEndpoint2()
153
    {
154
    	return this.endpoint2Model;
155
    }
156
157
    public boolean canEditLabel()
158
    {
159
    	return this.labelProperty != null;
160
    }
161
    
162
    public String getLabel()
163
	{
164
        String label = null;
165
        
166
        if( this.labelFunctionResult != null )
167
        {
168
            label = (String) this.labelFunctionResult.value();
169
        }
170
        
171
        if( label == null )
172
        {
173
            label = "#null#";
174
        }
175
        
176
        return label;
177
	}
178
    
179
    public void setLabel(String newValue)
180
    {
181
		if (this.labelProperty != null)
182
		{
183
			this.modelElement.write(this.labelProperty, newValue);
184
		}    	
185
    }
186
    
187
    public void refreshLabel()
188
    {
189
		final SapphireDiagramEditorPart diagramEditor = (SapphireDiagramEditorPart)getParentPart();
190
		final IFeatureProvider fp = 
191
						diagramEditor.getDiagramEditor().getDiagramTypeProvider().getFeatureProvider();
192
		final PictogramElement pe = getConnection(fp, this);
193
		if (pe != null)
194
		{
195
			UpdateContext context = new UpdateContext(pe);
196
			fp.updateIfPossible(context);
197
		}		
198
    	
199
    }
200
    
201
    public String getInstanceId()
202
	{
203
        String id = null;
204
        
205
        if( this.idFunctionResult != null )
206
        {
207
            id = (String) this.idFunctionResult.value();
208
        }
209
        
210
        if( id == null )
211
        {
212
            id = "#null#";
213
        }
214
        
215
        return id;
216
	}
217
218
    @Override
219
	public void render(SapphireRenderingContext context)
220
	{
221
		throw new UnsupportedOperationException();
222
	}
223
	
224
    @Override
225
    public void dispose()
226
    {
227
        super.dispose();
228
        if (this.labelFunctionResult != null)
229
        {
230
        	this.labelFunctionResult.dispose();
231
        }
232
        if (this.idFunctionResult != null)
233
        {
234
        	this.idFunctionResult.dispose();
235
        }
236
        if (this.endpoint1FunctionResult != null)
237
        {
238
        	this.endpoint1FunctionResult.dispose();
239
        }
240
        if (this.endpoint2FunctionResult != null)
241
        {
242
        	this.endpoint2FunctionResult.dispose();
243
        }
244
    }
245
    
246
	public void refreshEndpoint1()
247
	{
248
		if (this.endpoint1FunctionResult != null)
249
		{
250
			Object value = this.endpoint1FunctionResult.value();
251
			String property = this.endpoint1Def.getProperty().getContent();
252
			setModelProperty(this.modelElement, property, value);
253
		}		
254
	}
255
	
256
	public void refreshEndpoint2()
257
	{
258
		if (this.endpoint2FunctionResult != null)
259
		{
260
			Object value = this.endpoint2FunctionResult.value();
261
			String property = this.endpoint2Def.getProperty().getContent();
262
			setModelProperty(this.modelElement, property, value);
263
		}		
264
	}
265
266
	protected IModelElement processEndpoint(IDiagramConnectionEndpointDef endpointDef)
267
	{
268
		String propertyName = endpointDef.getProperty().getContent();
269
		ModelProperty modelProperty = resolve(this.modelElement, propertyName);
270
        if (!(modelProperty instanceof ValueProperty))
271
        {
272
        	throw new RuntimeException( "Property " + propertyName + " not a ValueProperty");
273
        }
274
        ValueProperty property = (ValueProperty)modelProperty;
275
		Value<?> valObj = this.modelElement.read(property);
276
		if (!(valObj instanceof ReferenceValue))
277
		{
278
			throw new RuntimeException( "Property " + propertyName + " value not a reference");
279
		}
280
		ReferenceValue<?> refVal = (ReferenceValue<?>)valObj;
281
		Object targetObj = refVal.resolve();
282
		return (IModelElement)targetObj;
283
	}
284
	
285
    protected void setModelProperty(final IModelElement modelElement, 
286
			String propertyName, Object value)
287
	{
288
		if (propertyName != null)
289
		{
290
			final ModelElementType type = modelElement.getModelElementType();
291
			final ModelProperty property = type.getProperty( propertyName );
292
			if( property == null )
293
			{
294
				throw new RuntimeException( "Could not find property " + propertyName + " in " + type.getQualifiedName() );
295
			}
296
			if (!(property instanceof ValueProperty))
297
			{
298
				throw new RuntimeException( "Property " + propertyName + " not a ValueProperty");
299
			}
300
		
301
			modelElement.write((ValueProperty)property, value);
302
		}    	
303
	}
304
	
305
    public void addModelListener()
306
    {
307
    	this.modelElement.addListener(this.modelPropertyListener, 
308
    								this.endpoint1Def.getProperty().getContent());
309
    	this.modelElement.addListener(this.modelPropertyListener, 
310
									this.endpoint2Def.getProperty().getContent());
311
    }
312
    
313
    public void removeModelListener()
314
    {
315
    	this.modelElement.removeListener(this.modelPropertyListener, 
316
    								this.endpoint1Def.getProperty().getContent());
317
    	this.modelElement.removeListener(this.modelPropertyListener, 
318
									this.endpoint2Def.getProperty().getContent());
319
    }
320
    
321
    protected void handleModelPropertyChange(final ModelPropertyChangeEvent event)
322
    {
323
    	final ModelProperty property = event.getProperty();
324
    	    	
325
    	if (property.getName().equals(this.endpoint1Def.getProperty().getContent()) || 
326
    			property.getName().equals(this.endpoint2Def.getProperty().getContent()))
327
    	{
328
        	SapphireDiagramEditorPart diagramEditor = (SapphireDiagramEditorPart)getParentPart();
329
    		final IFeatureProvider fp = diagramEditor.getDiagramEditor().getDiagramTypeProvider().getFeatureProvider();
330
    		final Diagram diagram = diagramEditor.getDiagramEditor().getDiagramTypeProvider().getDiagram();
331
    		final TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(diagram);
332
333
    		removeDiagramConnection(fp, ted);
334
    		
335
    		boolean sourceChange = property.getName().equals(this.endpoint1Def.getProperty().getContent()) ? true : false;
336
    		handleEndpointChange(sourceChange);
337
			// add new connection to the diagram
338
    		addNewConnectionIfPossible(fp, ted, diagramEditor);
339
    	}
340
    }    
341
    
342
    private void handleEndpointChange(boolean sourceChange) 
343
    {
344
		if (sourceChange)
345
		{
346
			this.endpoint1Model = processEndpoint(this.endpoint1Def);
347
			if (this.endpoint1FunctionResult != null)
348
			{
349
				this.endpoint1FunctionResult.dispose();
350
				this.endpoint1FunctionResult = null;
351
			}
352
	        if (this.endpoint1Model != null)
353
	        {
354
		        this.endpoint1FunctionResult = initExpression
355
		        (
356
		        	this.endpoint1Model, 
357
		        	this.endpoint1Def.getValue(), 
358
		            new Runnable()
359
		        	{
360
			            public void run()
361
			            {
362
			            	refreshEndpoint1();
363
			            }
364
		        	}
365
		        );
366
	        }			
367
		}
368
		else
369
		{
370
			this.endpoint2Model = processEndpoint(this.endpoint2Def);
371
			if (this.endpoint2FunctionResult != null)
372
			{
373
				this.endpoint2FunctionResult.dispose();
374
				this.endpoint2FunctionResult = null;
375
			}
376
	        if (this.endpoint2Model != null)
377
	        {
378
		        this.endpoint2FunctionResult = initExpression
379
		        (
380
		        	this.endpoint2Model, 
381
		        	this.endpoint2Def.getValue(), 
382
		            new Runnable()
383
		        	{
384
			            public void run()
385
			            {
386
			            	refreshEndpoint2();
387
			            }
388
		        	}
389
		        );
390
	        }			
391
		}
392
    }
393
    
394
    protected void removeDiagramConnection(IFeatureProvider fp, TransactionalEditingDomain ted)
395
    {
396
		// remove the existing connection pe from the diagram
397
		if (this.getEndpoint1() != null && this.getEndpoint2() != null)
398
		{
399
			PictogramElement pe = getConnection(fp, this);
400
			if (pe != null)
401
			{
402
				final IRemoveContext rc = new RemoveContext(pe);
403
				final IRemoveFeature removeFeature = fp.getRemoveFeature(rc);
404
				if (removeFeature != null) 
405
				{
406
					ted.getCommandStack().execute(new RecordingCommand(ted) 
407
					{
408
						protected void doExecute() 
409
						{			    					
410
							removeFeature.remove(rc);
411
						}
412
					});
413
				}
414
			}
415
		}    	
416
    }
417
    
418
    protected void addNewConnectionIfPossible(IFeatureProvider fp, TransactionalEditingDomain ted,
419
    						SapphireDiagramEditorPart diagramEditor)
420
    {
421
		// add new connection to the diagram
422
		if (this.getEndpoint1() != null && this.getEndpoint2() != null)
423
		{
424
			DiagramNodePart srcNodePart = diagramEditor.getDiagramNodePart(this.getEndpoint1());
425
			DiagramNodePart targetNodePart = diagramEditor.getDiagramNodePart(this.getEndpoint2());
426
			ContainerShape srcNode = getContainerShape(fp, srcNodePart);
427
			ContainerShape targetNode = getContainerShape(fp, targetNodePart);
428
			final AddConnectionContext addContext = 
429
					new AddConnectionContext(srcNode.getAnchors().get(0), targetNode.getAnchors().get(0));
430
			addContext.setNewObject(this);
431
			final IAddFeature addFeature = fp.getAddFeature(addContext);
432
			if (addFeature != null) 
433
			{
434
				ted.getCommandStack().execute(new RecordingCommand(ted) 
435
				{
436
					protected void doExecute() 
437
					{			    					
438
						addFeature.add(addContext);
439
					}
440
				});
441
			}			
442
		}     	
443
    }
444
    
445
	protected Connection getConnection(IFeatureProvider fp, Object bo)
446
	{
447
		PictogramElement [] pictograms = fp.getAllPictogramElementsForBusinessObject(bo);
448
		for (PictogramElement pictogram : pictograms)
449
		{
450
			if (pictogram instanceof Connection)
451
			{
452
				return (Connection)pictogram;
453
			}
454
		}
455
		return null;
456
	}
457
    
458
	protected ContainerShape getContainerShape(IFeatureProvider fp, Object bo)
459
	{
460
		ContainerShape containerShape = null;
461
		PictogramElement [] pictograms = fp.getAllPictogramElementsForBusinessObject(bo);
462
		for (PictogramElement pictogram : pictograms)
463
		{
464
			if (pictogram instanceof ContainerShape)
465
			{
466
				containerShape = (ContainerShape)pictogram;
467
				break;
468
			}
469
		}
470
		return containerShape;
471
	}
472
	
473
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/DiagramConnectionTemplate.java (+310 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.List;
6
7
import org.eclipse.emf.transaction.TransactionalEditingDomain;
8
import org.eclipse.emf.transaction.util.TransactionUtil;
9
import org.eclipse.graphiti.features.IFeatureProvider;
10
import org.eclipse.graphiti.mm.pictograms.Diagram;
11
import org.eclipse.sapphire.modeling.IModelElement;
12
import org.eclipse.sapphire.modeling.ListProperty;
13
import org.eclipse.sapphire.modeling.ModelElementList;
14
import org.eclipse.sapphire.modeling.ModelElementType;
15
import org.eclipse.sapphire.modeling.ModelProperty;
16
import org.eclipse.sapphire.modeling.ModelPropertyChangeEvent;
17
import org.eclipse.sapphire.modeling.ModelPropertyListener;
18
import org.eclipse.sapphire.modeling.Value;
19
import org.eclipse.sapphire.modeling.ValueProperty;
20
import org.eclipse.sapphire.modeling.annotations.Reference;
21
import org.eclipse.sapphire.modeling.el.FailSafeFunction;
22
import org.eclipse.sapphire.modeling.el.Function;
23
import org.eclipse.sapphire.modeling.el.FunctionResult;
24
import org.eclipse.sapphire.modeling.el.ModelElementFunctionContext;
25
import org.eclipse.sapphire.modeling.localization.LocalizationService;
26
import org.eclipse.sapphire.ui.diagram.def.IDiagramConnectionDef;
27
import org.eclipse.sapphire.ui.diagram.def.IDiagramConnectionEndpointDef;
28
29
public class DiagramConnectionTemplate 
30
{
31
	protected SapphireDiagramEditorPart diagramEditor;
32
	private IDiagramConnectionDef definition;
33
	protected IModelElement modelElement;
34
	protected String propertyName;
35
	private ListProperty modelProperty;
36
	protected String toolPaletteLabel;
37
	protected String toolPaletteDesc;
38
	protected ModelPropertyListener modelPropertyListener;
39
	
40
	private List<DiagramConnectionPart> diagramConnections;
41
	
42
	public DiagramConnectionTemplate() {}
43
	
44
    public DiagramConnectionTemplate(final SapphireDiagramEditorPart diagramEditor, 
45
    		IDiagramConnectionDef definition, IModelElement modelElement)
46
    {
47
    	this.diagramEditor = diagramEditor;
48
    	this.modelElement = modelElement;
49
    	this.definition = definition;
50
    	
51
        this.toolPaletteLabel = this.definition.getToolPaletteLabel().getContent();
52
        this.toolPaletteDesc = this.definition.getToolPaletteDesc().getContent();
53
        
54
        this.diagramConnections = new ArrayList<DiagramConnectionPart>();
55
        
56
        this.propertyName = this.definition.getProperty().getContent();
57
        this.modelProperty = (ListProperty)resolve(this.modelElement, this.propertyName);
58
        	
59
    	ModelElementList<?> list = this.modelElement.read(this.modelProperty);
60
        for( IModelElement listEntryModelElement : list )
61
        {
62
        	DiagramConnectionPart connection = new DiagramConnectionPart(this);
63
        	connection.init(this.diagramEditor, listEntryModelElement, definition, 
64
        			Collections.<String,String>emptyMap());
65
        	addConnectionPart(null, connection);
66
        }
67
                
68
        // Add model property listener
69
        this.modelPropertyListener = new ModelPropertyListener()
70
        {
71
            @Override
72
            public void handlePropertyChangedEvent( final ModelPropertyChangeEvent event )
73
            {
74
                handleModelPropertyChange( event );
75
            }
76
        };
77
        addModelListener();        
78
    }
79
    
80
    public List<DiagramConnectionPart> getDiagramConnections(IModelElement srcNodeModel)
81
    {
82
    	return this.diagramConnections;
83
    }
84
    
85
    public String getToolPaletteLabel()
86
    {
87
    	return this.toolPaletteLabel;
88
    }
89
    
90
    public String getToolPaletteDesc()
91
    {
92
    	return this.toolPaletteDesc;
93
    }
94
    
95
    public boolean canCreateNewConnection(DiagramNodePart srcNode, DiagramNodePart targetNode)
96
    {
97
    	boolean canCreate = false;
98
    	ModelElementType srcType = srcNode.getModelElement().getModelElementType();
99
    	ModelElementType targetType = targetNode.getModelElement().getModelElementType();
100
    	
101
        ModelElementType type = this.modelProperty.getType();
102
        ModelProperty prop1 = type.getProperty(this.definition.getEndpoint1().element().getProperty().getContent());
103
        if (prop1.getType() == null && prop1.hasAnnotation(Reference.class))
104
        {
105
        	canCreate = prop1.getAnnotation(Reference.class).target().isAssignableFrom(srcType.getModelElementClass());
106
        	if (!canCreate)
107
        		return false;
108
        }
109
        ModelProperty prop2 = type.getProperty(this.definition.getEndpoint2().element().getProperty().getContent());
110
        if (prop2.getType() == null && prop2.hasAnnotation(Reference.class))
111
        {
112
        	canCreate = prop2.getAnnotation(Reference.class).target().isAssignableFrom(targetType.getModelElementClass());
113
        }
114
    	return canCreate;
115
    }
116
    
117
    public void addModelListener()
118
    {
119
    	this.modelElement.addListener(this.modelPropertyListener, this.propertyName);
120
    }
121
    
122
    public void removeModelListener()
123
    {
124
    	this.modelElement.removeListener(this.modelPropertyListener, this.propertyName);
125
    }
126
    
127
    public SapphireDiagramEditorPart getDiagramEditor()
128
    {
129
    	return this.diagramEditor;
130
    }
131
    
132
    public DiagramConnectionPart createNewDiagramConnection(DiagramNodePart srcNode, 
133
    														DiagramNodePart targetNode)
134
    {
135
		ModelElementList<?> list = this.modelElement.read(this.modelProperty);
136
		IModelElement newElement = list.addNewElement();
137
		
138
    	IDiagramConnectionEndpointDef srcAnchorDef = this.definition.getEndpoint1().element();
139
    	String srcProperty = srcAnchorDef.getProperty().getContent();
140
    	Value<Function> srcFunc = srcAnchorDef.getValue();
141
    	FunctionResult srcFuncResult = getNodeReferenceFunction(srcNode, srcFunc);
142
    	if (srcFuncResult != null)
143
    	{
144
	    	setModelProperty(newElement, srcProperty, srcFuncResult.value());
145
	    	srcFuncResult.dispose();
146
    	}
147
    	
148
    	IDiagramConnectionEndpointDef targetAnchorDef = this.definition.getEndpoint2().element();
149
    	String targetProperty = targetAnchorDef.getProperty().getContent();
150
    	Value<Function> targetFunc = targetAnchorDef.getValue();;
151
    	FunctionResult targetFuncResult = getNodeReferenceFunction(targetNode, targetFunc);
152
    	if (targetFuncResult != null)
153
    	{
154
	    	setModelProperty(newElement, targetProperty, targetFuncResult.value());
155
	    	targetFuncResult.dispose();
156
    	}
157
    	
158
    	DiagramConnectionPart newConn = new DiagramConnectionPart(this);
159
    	newConn.init(this.diagramEditor, newElement, this.definition, 
160
    			Collections.<String,String>emptyMap());
161
    	addConnectionPart(null, newConn);
162
    	return newConn;
163
    }
164
    
165
    public DiagramConnectionPart createNewDiagramConnection(IModelElement connElement, IModelElement srcNodeElement)
166
    {
167
    	DiagramConnectionPart connPart = new DiagramConnectionPart(this);
168
    	connPart.init(this.diagramEditor, connElement, this.definition, 
169
    			Collections.<String,String>emptyMap());
170
    	addConnectionPart(null, connPart);
171
    	return connPart;
172
    }
173
    
174
    protected ModelProperty resolve(final IModelElement modelElement, 
175
    		String propertyName)
176
    {
177
    	if (propertyName != null)
178
    	{
179
	        final ModelElementType type = modelElement.getModelElementType();
180
	        final ModelProperty property = type.getProperty( propertyName );
181
	        if( property == null )
182
	        {
183
	            throw new RuntimeException( "Could not find property " + propertyName + " in " + type.getQualifiedName() );
184
	        }
185
	        return property;
186
    	}    
187
        return null;
188
    }
189
190
    protected void setModelProperty(final IModelElement modelElement, 
191
    								String propertyName, Object value)
192
    {
193
    	if (propertyName != null)
194
    	{
195
	        final ModelElementType type = modelElement.getModelElementType();
196
	        final ModelProperty property = type.getProperty( propertyName );
197
	        if( property == null )
198
	        {
199
	            throw new RuntimeException( "Could not find property " + propertyName + " in " + type.getQualifiedName() );
200
	        }
201
	        if (!(property instanceof ValueProperty))
202
	        {
203
	        	throw new RuntimeException( "Property " + propertyName + " not a ValueProperty");
204
	        }
205
	        		
206
	        modelElement.write((ValueProperty)property, value);
207
    	}    	
208
    }
209
    
210
    protected FunctionResult getNodeReferenceFunction(final DiagramNodePart nodePart,
211
    											final Value<Function> function)
212
    {
213
        Function f = null;
214
        FunctionResult fr = null;
215
        
216
        if( function != null )
217
        {
218
            f = function.getContent();
219
        }
220
        
221
        if( f != null )
222
        {
223
            
224
            f = FailSafeFunction.create( f, String.class );
225
            fr = f.evaluate( new ModelElementFunctionContext( nodePart.getLocalModelElement(), this.definition.adapt( LocalizationService.class ) ) );
226
        }
227
        return fr;
228
    }
229
    
230
    protected void handleModelPropertyChange(final ModelPropertyChangeEvent event)
231
    {
232
    	final IModelElement element = event.getModelElement();
233
    	final ModelProperty property = event.getProperty();
234
    	ModelElementList<?> newList = (ModelElementList<?>)element.read(property);
235
    	
236
    	if (newList.size() != getDiagramConnections(element).size())
237
    	{
238
    		List<DiagramConnectionPart> connParts = getDiagramConnections(element);
239
    		List<IModelElement> oldList = new ArrayList<IModelElement>(connParts.size());
240
    		for (DiagramConnectionPart connPart : connParts)
241
    		{
242
    			oldList.add(connPart.getLocalModelElement());
243
    		}
244
    		
245
    		final IFeatureProvider fp = this.diagramEditor.getDiagramEditor().getDiagramTypeProvider().getFeatureProvider();
246
    		final Diagram diagram = this.diagramEditor.getDiagramEditor().getDiagramTypeProvider().getDiagram();
247
			final TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(diagram);
248
    		
249
	    	if (newList.size() > oldList.size())
250
	    	{
251
	    		// new connections are added
252
	    		List<IModelElement> newConns = ListUtil.ListDiff(newList, oldList);
253
	    		for (IModelElement newConn : newConns)
254
	    		{	    			
255
	            	DiagramConnectionPart connPart = createNewDiagramConnection(newConn, element);
256
	            	connPart.addNewConnectionIfPossible(fp, ted, this.diagramEditor);
257
	    		}
258
	    	}
259
	    	else
260
	    	{
261
	    		// connections are deleted
262
	    		List<IModelElement> deletedConns = ListUtil.ListDiff(newList, oldList);
263
	    		for (IModelElement deletedConn : deletedConns)
264
	    		{
265
	    			DiagramConnectionPart connPart = getConnectionPart(element, deletedConn);
266
	    			if (connPart != null)
267
	    			{
268
	    				connPart.removeDiagramConnection(fp, ted);
269
		    			connPart.dispose();
270
		    			removeConnectionPart(element, connPart);
271
	    			}
272
	    		}
273
	    	}
274
    	}
275
    }
276
    
277
    protected void addConnectionPart(IModelElement srcNodeModel, DiagramConnectionPart connPart)
278
    {
279
    	this.diagramConnections.add(connPart);
280
    }
281
    
282
    protected void removeConnectionPart(IModelElement srcNodeModel, DiagramConnectionPart connPart)
283
    {
284
    	this.diagramConnections.remove(connPart);
285
    }
286
    
287
    protected DiagramConnectionPart getConnectionPart(IModelElement srcNodeModel, IModelElement connModel)
288
    {
289
    	List<DiagramConnectionPart> connParts = getDiagramConnections(srcNodeModel);
290
    	for (DiagramConnectionPart connPart : connParts)
291
    	{
292
    		if (connPart.getLocalModelElement().equals(connModel))
293
    		{
294
    			return connPart;
295
    		}
296
    	}
297
    	return null;
298
    }
299
    
300
    public void dispose()
301
    {
302
    	removeModelListener();
303
    	List<DiagramConnectionPart> connParts = getDiagramConnections(null);
304
    	for (DiagramConnectionPart connPart : connParts)
305
    	{
306
    		connPart.dispose();
307
    	}
308
    }
309
        
310
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/DiagramEmbeddedConnectionPart.java (+207 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import org.eclipse.emf.transaction.TransactionalEditingDomain;
4
import org.eclipse.emf.transaction.util.TransactionUtil;
5
import org.eclipse.graphiti.features.IFeatureProvider;
6
import org.eclipse.graphiti.mm.pictograms.Diagram;
7
import org.eclipse.sapphire.modeling.IModelElement;
8
import org.eclipse.sapphire.modeling.ModelProperty;
9
import org.eclipse.sapphire.modeling.ModelPropertyChangeEvent;
10
import org.eclipse.sapphire.modeling.ModelPropertyListener;
11
import org.eclipse.sapphire.modeling.el.FunctionResult;
12
import org.eclipse.sapphire.ui.SapphireRenderingContext;
13
import org.eclipse.sapphire.ui.diagram.def.IDiagramConnectionEndpointDef;
14
import org.eclipse.sapphire.ui.diagram.def.IDiagramEmbeddedConnectionDef;
15
16
public class DiagramEmbeddedConnectionPart extends DiagramConnectionPart 
17
{
18
	private IDiagramEmbeddedConnectionDef localDefinition;
19
	private IModelElement srcNodeModel;
20
	private IModelElement endpointModel;
21
	private FunctionResult endpointFunctionResult;
22
	private IDiagramConnectionEndpointDef endpointDef;
23
	
24
	public DiagramEmbeddedConnectionPart(DiagramEmbeddedConnectionTemplate connTemplate,
25
			IModelElement srcNodeModel)
26
	{
27
		this.connectionTemplate = connTemplate;
28
		this.srcNodeModel = srcNodeModel;
29
	}
30
	
31
    @Override
32
    protected void init()
33
    {        
34
        this.localDefinition = (IDiagramEmbeddedConnectionDef)super.definition;
35
        this.modelElement = super.getModelElement();
36
        this.labelFunctionResult = initExpression
37
        ( 
38
        	this.modelElement,
39
        	this.localDefinition.getLabel().element().getContent(), 
40
            new Runnable()
41
            {
42
                public void run()
43
                {
44
                }
45
            }
46
        );
47
        this.labelProperty = FunctionUtil.getFunctionProperty(this.modelElement, this.labelFunctionResult);
48
        
49
        this.idFunctionResult = initExpression
50
        ( 
51
        	this.modelElement,
52
            this.localDefinition.getInstanceId(), 
53
            new Runnable()
54
            {
55
                public void run()
56
                {
57
                }
58
            }
59
        );        
60
61
        this.endpointDef = this.localDefinition.getEndpoint().element();
62
        this.endpointModel = processEndpoint(this.endpointDef);
63
        if (this.endpointModel != null)
64
        {
65
	        this.endpointFunctionResult = initExpression
66
	        (
67
	        	this.endpointModel, 
68
	        	this.endpointDef.getValue(), 
69
	            new Runnable()
70
	        	{
71
		            public void run()
72
		            {
73
		            	refreshEndpoint2();
74
		            }
75
	        	}
76
	        );
77
        }        
78
        // Add model property listener
79
        this.modelPropertyListener = new ModelPropertyListener()
80
        {
81
            @Override
82
            public void handlePropertyChangedEvent( final ModelPropertyChangeEvent event )
83
            {
84
                handleModelPropertyChange( event );
85
            }
86
        };
87
        addModelListener();        
88
    }
89
    
90
    @Override
91
    public IModelElement getEndpoint1()
92
    {
93
    	return this.srcNodeModel;
94
    }
95
    
96
    @Override
97
    public IModelElement getEndpoint2()
98
    {
99
    	return this.endpointModel;
100
    }
101
102
    @Override
103
	public void refreshEndpoint1()
104
	{
105
	}
106
	
107
    @Override
108
	public void refreshEndpoint2()
109
	{
110
		if (this.endpointFunctionResult != null)
111
		{
112
			Object value = this.endpointFunctionResult.value();
113
			String property = this.endpointDef.getProperty().getContent();
114
			setModelProperty(this.modelElement, property, value);
115
		}		
116
	}
117
        
118
    public DiagramNodePart getSourceNodePart()
119
    {
120
    	SapphireDiagramEditorPart diagramPart = (SapphireDiagramEditorPart)getParentPart();
121
    	return diagramPart.getDiagramNodePart(this.srcNodeModel);
122
    }
123
    
124
	@Override
125
	public void render(SapphireRenderingContext context) 
126
	{
127
		// TODO Auto-generated method stub
128
129
	}
130
131
    @Override
132
    public void dispose()
133
    {
134
    	super.dispose();
135
    	if (this.endpointFunctionResult != null)
136
    	{
137
    		this.endpointFunctionResult.dispose();
138
    	}    	
139
    }
140
    
141
    @Override
142
    public void addModelListener()
143
    {
144
    	if (this.labelProperty != null)
145
    	{
146
	    	this.modelElement.addListener(this.modelPropertyListener, 
147
	    								this.labelProperty.getName());
148
    	}
149
    	this.modelElement.addListener(this.modelPropertyListener, 
150
    								this.endpointDef.getProperty().getContent());
151
    }
152
    
153
    @Override
154
    public void removeModelListener()
155
    {
156
    	if (this.labelProperty != null)
157
    	{
158
	    	this.modelElement.removeListener(this.modelPropertyListener, 
159
	    								this.labelProperty.getName());
160
    	}
161
    	this.modelElement.removeListener(this.modelPropertyListener, 
162
    								this.endpointDef.getProperty().getContent());
163
    }
164
165
    @Override
166
    protected void handleModelPropertyChange(final ModelPropertyChangeEvent event)
167
    {
168
    	final ModelProperty property = event.getProperty();
169
    	if (property.getName().equals(this.endpointDef.getProperty().getContent()))
170
    	{
171
	    	SapphireDiagramEditorPart diagramEditor = (SapphireDiagramEditorPart)getParentPart();
172
			final IFeatureProvider fp = diagramEditor.getDiagramEditor().getDiagramTypeProvider().getFeatureProvider();
173
			final Diagram diagram = diagramEditor.getDiagramEditor().getDiagramTypeProvider().getDiagram();
174
			final TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(diagram);
175
			
176
			removeDiagramConnection(fp, ted);
177
			handleEndpointChange();
178
			addNewConnectionIfPossible(fp, ted, diagramEditor);
179
    	}    			
180
    }    
181
    
182
    private void handleEndpointChange()
183
    {
184
        this.endpointModel = processEndpoint(this.endpointDef);
185
        if (this.endpointFunctionResult != null)
186
        {
187
        	this.endpointFunctionResult.dispose();
188
        	this.endpointFunctionResult = null;
189
        }
190
        if (this.endpointModel != null)
191
        {        	
192
	        this.endpointFunctionResult = initExpression
193
	        (
194
	        	this.endpointModel, 
195
	        	this.endpointDef.getValue(), 
196
	            new Runnable()
197
	        	{
198
		            public void run()
199
		            {
200
		            	refreshEndpoint2();
201
		            }
202
	        	}
203
	        );
204
        }        
205
    }
206
    
207
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/DiagramEmbeddedConnectionTemplate.java (+284 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.HashMap;
6
import java.util.Iterator;
7
import java.util.List;
8
import java.util.Map;
9
10
import org.eclipse.emf.transaction.TransactionalEditingDomain;
11
import org.eclipse.emf.transaction.util.TransactionUtil;
12
import org.eclipse.graphiti.features.IFeatureProvider;
13
import org.eclipse.graphiti.mm.pictograms.Diagram;
14
import org.eclipse.sapphire.modeling.ElementProperty;
15
import org.eclipse.sapphire.modeling.IModelElement;
16
import org.eclipse.sapphire.modeling.ListProperty;
17
import org.eclipse.sapphire.modeling.ModelElementDisposedEvent;
18
import org.eclipse.sapphire.modeling.ModelElementList;
19
import org.eclipse.sapphire.modeling.ModelElementListener;
20
import org.eclipse.sapphire.modeling.ModelElementType;
21
import org.eclipse.sapphire.modeling.ModelProperty;
22
import org.eclipse.sapphire.modeling.ModelPropertyChangeEvent;
23
import org.eclipse.sapphire.modeling.ModelPropertyListener;
24
import org.eclipse.sapphire.modeling.Value;
25
import org.eclipse.sapphire.modeling.annotations.Reference;
26
import org.eclipse.sapphire.modeling.el.Function;
27
import org.eclipse.sapphire.modeling.el.FunctionResult;
28
import org.eclipse.sapphire.ui.diagram.def.IDiagramConnectionEndpointDef;
29
import org.eclipse.sapphire.ui.diagram.def.IDiagramEmbeddedConnectionDef;
30
31
public class DiagramEmbeddedConnectionTemplate extends DiagramConnectionTemplate
32
{
33
	private DiagramNodeTemplate nodeTemplate;
34
	private IDiagramEmbeddedConnectionDef definition;
35
	private Map<IModelElement, List<DiagramConnectionPart>> diagramConnectionMap;
36
	private ModelElementListener modelElementListener;
37
	private ModelElementList<IModelElement> srcNodeList;
38
		
39
    public DiagramEmbeddedConnectionTemplate(final SapphireDiagramEditorPart diagramEditor,
40
    										final DiagramNodeTemplate nodeTemplate, 
41
    										IDiagramEmbeddedConnectionDef definition, 
42
    										IModelElement modelElement)
43
    {
44
    	this.diagramEditor = diagramEditor;
45
    	this.nodeTemplate = nodeTemplate;
46
    	this.modelElement = modelElement;
47
    	this.definition = definition;
48
    	
49
        this.toolPaletteLabel = this.definition.getToolPaletteLabel().getContent();
50
        this.toolPaletteDesc = this.definition.getToolPaletteDesc().getContent();
51
        
52
        this.diagramConnectionMap = new HashMap<IModelElement, List<DiagramConnectionPart>>();
53
        
54
        ListProperty nodeProperty = (ListProperty)this.nodeTemplate.getModelProperty();
55
        this.propertyName = this.definition.getProperty().getContent();
56
        
57
        this.modelPropertyListener = new ModelPropertyListener()
58
        {
59
            @Override
60
            public void handlePropertyChangedEvent( final ModelPropertyChangeEvent event )
61
            {
62
                handleModelPropertyChange( event );
63
            }
64
        };
65
        
66
        this.modelElementListener = new ModelElementListener() 
67
        {
68
        	@Override
69
        	public void handleElementDisposedEvent( final ModelElementDisposedEvent event )
70
        	{
71
        		handleModelElementDispose(event);
72
        	}
73
		};
74
		
75
    	this.srcNodeList = this.modelElement.read(nodeProperty);
76
        for (IModelElement srcNodeModel : this.srcNodeList)
77
        {
78
        	ModelProperty connProp = resolve(srcNodeModel, this.propertyName);
79
        	if (connProp instanceof ListProperty)
80
        	{
81
        		ListProperty connListProperty = (ListProperty)connProp;
82
        		ModelElementList<?> connList = srcNodeModel.read(connListProperty);
83
        		List<DiagramConnectionPart> partList = new ArrayList<DiagramConnectionPart>();
84
        		for (IModelElement endpointModel : connList)
85
        		{
86
        			DiagramEmbeddedConnectionPart connPart = 
87
        				new DiagramEmbeddedConnectionPart(this, srcNodeModel);
88
        			connPart.init(this.diagramEditor, endpointModel, this.definition, 
89
        					Collections.<String,String>emptyMap());
90
        			partList.add(connPart);
91
        		}
92
        		this.diagramConnectionMap.put(srcNodeModel, partList);
93
        		addModelListener(srcNodeModel);
94
        	}
95
        }            	
96
    }
97
        
98
    @Override
99
    public boolean canCreateNewConnection(DiagramNodePart srcNode, DiagramNodePart targetNode)
100
    {    	
101
    	IModelElement srcNodeModel = srcNode.getLocalModelElement();
102
    	
103
    	// check the source node type
104
    	ModelElementType srcNodeType = srcNodeModel.getModelElementType();
105
    	ModelElementType desiredsrcNodeType = this.nodeTemplate.getNodeType();
106
    	
107
    	if (!srcNodeType.equals(desiredsrcNodeType))
108
    	{
109
    		return false;
110
    	}
111
    	
112
    	// check the target node type
113
    	ModelElementType targetType = targetNode.getLocalModelElement().getModelElementType();
114
    	
115
    	ModelProperty connProp = resolve(srcNodeModel, this.propertyName);    	
116
        ModelElementType connType = connProp.getType();
117
        ModelProperty endpointProp = 
118
        	connType.getProperty(this.definition.getEndpoint().element().getProperty().getContent());
119
        if (endpointProp.getType() == null && endpointProp.hasAnnotation(Reference.class))
120
        {
121
        	return endpointProp.getAnnotation(Reference.class).target().isAssignableFrom(targetType.getModelElementClass());
122
        }
123
    	return false;
124
    }
125
        
126
    @Override
127
    public DiagramEmbeddedConnectionPart createNewDiagramConnection(DiagramNodePart srcNode, 
128
			DiagramNodePart targetNode)
129
    {
130
    	IModelElement srcNodeModel = srcNode.getLocalModelElement();
131
    	ModelProperty modelProperty = this.nodeTemplate.getModelProperty();
132
    	boolean found = false;
133
    	if (modelProperty instanceof ListProperty)
134
    	{
135
        	ListProperty listProperty = (ListProperty)modelProperty;
136
        	ModelElementList<?> list = this.modelElement.read(listProperty);
137
            for (IModelElement listEntryModelElement : list)
138
            {
139
            	if (listEntryModelElement.equals(srcNodeModel))
140
            	{
141
            		found = true;
142
            		break;
143
            	}            	
144
            }
145
    	}
146
        else if (modelProperty instanceof ElementProperty)
147
        {
148
        	ElementProperty elementProperty = (ElementProperty)modelProperty;
149
        	if (this.modelElement.read(elementProperty) != null)
150
        	{
151
	        	IModelElement localModelElement = this.modelElement.read(elementProperty).element();
152
	        	if (localModelElement == srcNodeModel)
153
	        	{
154
	        		found = true;
155
	        	}
156
        	}
157
        }
158
    	if (!found)
159
    	{
160
    		throw new RuntimeException( "Cannot locate the source node element");
161
    	}
162
    	
163
    	ModelProperty connProp = resolve(srcNodeModel, this.propertyName);
164
    	IModelElement newEndpoint = null;
165
    	if (connProp instanceof ListProperty)
166
    	{
167
    		ListProperty listProperty = (ListProperty)connProp;
168
    		ModelElementList<?> list = srcNodeModel.read(listProperty);
169
    		newEndpoint = list.addNewElement();    		
170
    	}
171
    	IDiagramConnectionEndpointDef endpointDef = this.definition.getEndpoint().element();
172
    	String endpointProperty = endpointDef.getProperty().getContent();
173
    	Value<Function> endpointFunc = endpointDef.getValue();
174
    	FunctionResult endpointFuncResult = getNodeReferenceFunction(targetNode, endpointFunc);
175
    	if (endpointFuncResult != null)
176
    	{
177
	    	setModelProperty(newEndpoint, endpointProperty, endpointFuncResult.value());
178
	    	endpointFuncResult.dispose();
179
    	}
180
    	
181
		DiagramEmbeddedConnectionPart connPart = 
182
			new DiagramEmbeddedConnectionPart(this, srcNodeModel);
183
		connPart.init(this.diagramEditor, newEndpoint, this.definition, 
184
				Collections.<String,String>emptyMap());               			
185
		addConnectionPart(srcNodeModel, connPart);                		
186
    	
187
    	return connPart;
188
    }
189
    
190
    @Override
191
    public DiagramConnectionPart createNewDiagramConnection(IModelElement connElement, IModelElement srcNodeElement)
192
    {
193
		DiagramEmbeddedConnectionPart connPart = 
194
			new DiagramEmbeddedConnectionPart(this, srcNodeElement);
195
		connPart.init(this.diagramEditor, connElement, this.definition, 
196
				Collections.<String,String>emptyMap());
197
		addConnectionPart(srcNodeElement, connPart);
198
    	return connPart;
199
    }
200
    
201
    public void addModelListener(IModelElement srcNodeModel)
202
    {
203
    	srcNodeModel.addListener(this.modelPropertyListener, this.propertyName);
204
    	srcNodeModel.addListener(this.modelElementListener);
205
    }
206
    
207
    public void removeModelListener(IModelElement srcNodeModel)
208
    {
209
    	srcNodeModel.removeListener(this.modelPropertyListener, this.propertyName);
210
    	srcNodeModel.removeListener(this.modelElementListener);
211
    } 
212
    
213
    @Override
214
    public void removeModelListener()
215
    {
216
    	for (IModelElement srcNodeModel : this.srcNodeList)
217
    	{
218
    		removeModelListener(srcNodeModel);
219
    	}
220
    }
221
    
222
    @Override
223
    public List<DiagramConnectionPart> getDiagramConnections(IModelElement srcNodeModel)
224
    {
225
    	List<DiagramConnectionPart> allConnParts = new ArrayList<DiagramConnectionPart>();
226
    	if (srcNodeModel != null)
227
    	{
228
    		if (this.diagramConnectionMap.get(srcNodeModel) != null)
229
    		{
230
    			allConnParts.addAll(this.diagramConnectionMap.get(srcNodeModel));
231
    		}
232
    	}
233
    	else
234
    	{    		
235
    		// return all the connection parts
236
    		Iterator<IModelElement> it = this.diagramConnectionMap.keySet().iterator();
237
    		while (it.hasNext())
238
    		{
239
    			allConnParts.addAll(this.diagramConnectionMap.get(it.next()));
240
    		}
241
    	}
242
		return allConnParts;
243
    }
244
245
    @Override
246
    protected void addConnectionPart(IModelElement srcNodeModel, DiagramConnectionPart connPart)
247
    {
248
    	List<DiagramConnectionPart> connParts = this.diagramConnectionMap.get(srcNodeModel);
249
    	if (connParts == null)
250
    	{
251
    		connParts = new ArrayList<DiagramConnectionPart>();
252
    		this.diagramConnectionMap.put(srcNodeModel, connParts);
253
    	}
254
    	connParts.add(connPart);
255
    }
256
257
    @Override
258
    protected void removeConnectionPart(IModelElement srcNodeModel, DiagramConnectionPart connPart)
259
    {
260
    	List<DiagramConnectionPart> connParts = this.diagramConnectionMap.get(srcNodeModel);
261
    	if (connParts != null)
262
    	{
263
    		connParts.remove(connPart);
264
    	}
265
    }
266
    
267
    private void handleModelElementDispose(final ModelElementDisposedEvent event)
268
    {
269
    	IModelElement element = event.getModelElement();
270
    	List<DiagramConnectionPart> connParts = getDiagramConnections(element);
271
		final IFeatureProvider fp = this.diagramEditor.getDiagramEditor().getDiagramTypeProvider().getFeatureProvider();
272
		final Diagram diagram = this.diagramEditor.getDiagramEditor().getDiagramTypeProvider().getDiagram();
273
		final TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(diagram);
274
    	
275
    	for (DiagramConnectionPart connPart : connParts)
276
    	{
277
			connPart.removeDiagramConnection(fp, ted);
278
			connPart.dispose();
279
    	}
280
    	connParts.clear();
281
    	removeModelListener(element);
282
    } 
283
    
284
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/DiagramGeometryWrapper.java (+410 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import java.util.ArrayList;
4
import java.util.HashMap;
5
import java.util.Iterator;
6
import java.util.List;
7
8
import org.eclipse.core.resources.IFile;
9
import org.eclipse.sapphire.modeling.ModelElementList;
10
import org.eclipse.sapphire.modeling.ResourceStoreException;
11
import org.eclipse.sapphire.modeling.WorkspaceFileResourceStore;
12
import org.eclipse.sapphire.modeling.xml.RootXmlResource;
13
import org.eclipse.sapphire.modeling.xml.XmlResourceStore;
14
import org.eclipse.sapphire.ui.diagram.geometry.IBendPoint;
15
import org.eclipse.sapphire.ui.diagram.geometry.IDiagramConnectionGeometry;
16
import org.eclipse.sapphire.ui.diagram.geometry.IDiagramGeometry;
17
import org.eclipse.sapphire.ui.diagram.geometry.IDiagramNodeGeometry;
18
19
public class DiagramGeometryWrapper 
20
{
21
	private IFile file;
22
	private IDiagramGeometry geometryModel;
23
	private SapphireDiagramEditorPart diagramPart;
24
	
25
	private HashMap<DiagramNodePart, Bounds> nodeGeometries;
26
	private HashMap<DiagramConnectionPart, List<Point>> connectionBendpoints;
27
	private HashMap<DiagramNodePart, HashMap<DiagramConnectionPart, List<Point>>> embeddedConnectionBendpoints;
28
	
29
	public DiagramGeometryWrapper(IFile file, SapphireDiagramEditorPart diagramPart)
30
		throws ResourceStoreException
31
	{
32
		this.file = file;
33
		this.diagramPart = diagramPart;
34
		this.nodeGeometries = new HashMap<DiagramNodePart, Bounds>();
35
		this.connectionBendpoints = new HashMap<DiagramConnectionPart, List<Point>>();
36
		this.embeddedConnectionBendpoints = 
37
					new HashMap<DiagramNodePart, HashMap<DiagramConnectionPart, List<Point>>>();
38
		read();
39
	}
40
	
41
	public void addNode(DiagramNodePart nodePart, int x, int y, int w, int h)
42
	{
43
		Bounds bounds = new Bounds(x, y, w, h);
44
		this.nodeGeometries.put(nodePart, bounds);
45
	}
46
	
47
	public void removeNode(DiagramNodePart nodePart)
48
	{
49
		this.nodeGeometries.remove(nodePart);
50
	}
51
	
52
	public void updateNode(DiagramNodePart nodePart, int x, int y)
53
	{
54
		Bounds bounds = this.nodeGeometries.get(nodePart);
55
		if (bounds != null)
56
		{
57
			bounds.setX(x);
58
			bounds.setY(y);
59
		}
60
	}
61
62
	public void updateNode(DiagramNodePart nodePart, int x, int y, int w, int h)
63
	{
64
		Bounds bounds = this.nodeGeometries.get(nodePart);
65
		if (bounds != null)
66
		{
67
			bounds.setX(x);
68
			bounds.setY(y);
69
			bounds.setHeight(h);
70
			bounds.setWidth(w);
71
		}
72
	}
73
	
74
	public Bounds getNode(DiagramNodePart nodePart)
75
	{
76
		return this.nodeGeometries.get(nodePart);
77
	}
78
		
79
	public void addConnectionBendpoint(DiagramConnectionPart connPart, int index, int x, int y)
80
	{
81
		HashMap<DiagramConnectionPart, List<Point>> connBendpointsMap = 
82
			getConnectionBenpointsMap(connPart, true);
83
		List<Point> bendpoints = connBendpointsMap.get(connPart);
84
		if (bendpoints == null)
85
		{
86
			bendpoints = new ArrayList<Point>();
87
			connBendpointsMap.put(connPart, bendpoints);
88
		}
89
		Point newPt = new Point(x, y);
90
		bendpoints.add(index, newPt);
91
	}
92
	
93
	public void removeConnectionBendpoint(DiagramConnectionPart connPart, int index)
94
	{
95
		HashMap<DiagramConnectionPart, List<Point>> connBendpointsMap = 
96
			getConnectionBenpointsMap(connPart, false);
97
		if (connBendpointsMap == null)
98
		{
99
			throw new RuntimeException("Could not locate connection benpoints map for the embedded connection");
100
		}
101
		List<Point> bendpoints = connBendpointsMap.get(connPart);
102
		if (bendpoints != null)
103
		{
104
			bendpoints.remove(index);
105
		}
106
	}
107
	
108
	public boolean updateConnectionBendpoint(DiagramConnectionPart connPart, int index, int x, int y)
109
	{
110
		HashMap<DiagramConnectionPart, List<Point>> connBendpointsMap = 
111
			getConnectionBenpointsMap(connPart, false);
112
		if (connBendpointsMap == null)
113
		{
114
			throw new RuntimeException("Could not locate connection benpoints map for the embedded connection");
115
		}
116
		List<Point> bendpoints = connBendpointsMap.get(connPart);
117
		if (bendpoints != null && index < bendpoints.size())
118
		{
119
			bendpoints.set(index, new Point(x, y));
120
			return true;
121
		}
122
		return false;
123
	}
124
	
125
126
	public List<Point> getConnectionBendpoints(DiagramConnectionPart connPart)
127
	{
128
		HashMap<DiagramConnectionPart, List<Point>> connBendpointsMap = 
129
			getConnectionBenpointsMap(connPart, false);		
130
		if (connBendpointsMap != null)
131
		{
132
			return connBendpointsMap.get(connPart);
133
		}
134
		return null;
135
	}
136
		
137
	public void removeConnectionBendpoints(DiagramConnectionPart connPart)
138
	{
139
		HashMap<DiagramConnectionPart, List<Point>> connBendpointsMap = 
140
			getConnectionBenpointsMap(connPart, false);		
141
		if (connBendpointsMap != null)
142
		{
143
			connBendpointsMap.remove(connPart);
144
		}		
145
	}
146
	
147
	public void read() throws ResourceStoreException
148
	{
149
		final XmlResourceStore resourceStore = new XmlResourceStore( new WorkspaceFileResourceStore(this.file ));
150
		this.geometryModel = IDiagramGeometry.TYPE.instantiate(new RootXmlResource( resourceStore ));
151
152
		ModelElementList<IDiagramNodeGeometry> nodes = this.geometryModel.getDiagramNodeGeometries();
153
		for (IDiagramNodeGeometry node : nodes)
154
		{
155
			String id = node.getNodeId().getContent();
156
			DiagramNodePart nodePart = getNodePart(id);
157
			if (nodePart != null)
158
			{
159
				int x = node.getX().getContent() != null ? node.getX().getContent() : -1;
160
				int y = node.getY().getContent() != null ? node.getY().getContent() : -1;
161
				int width = node.getWidth().getContent() != null ? node.getWidth().getContent() : -1;
162
				int height = node.getHeight().getContent() != null ? node.getHeight().getContent() : -1;
163
				this.addNode(nodePart, x, y, width, height);
164
				
165
				ModelElementList<IDiagramConnectionGeometry> connList = node.getEmbeddedConnectionGeometries();
166
				for (IDiagramConnectionGeometry connBend : connList)
167
				{
168
					String connId = connBend.getConnectionId().getContent();
169
					DiagramConnectionPart connPart = getConnectionPart(nodePart, connId);
170
					if (connPart != null)
171
					{
172
						ModelElementList<IBendPoint> bps = connBend.getConnectionBendpoints();
173
						int index = 0;
174
						for (IBendPoint pt : bps)
175
						{
176
							this.addConnectionBendpoint(connPart, index++, pt.getX().getContent(), pt.getY().getContent());
177
						}
178
					}			
179
				}
180
				
181
			}
182
		}
183
		
184
		ModelElementList<IDiagramConnectionGeometry> connList = this.geometryModel.getDiagramConnectionGeometries();
185
		for (IDiagramConnectionGeometry connBend : connList)
186
		{
187
			String connId = connBend.getConnectionId().getContent();
188
			DiagramConnectionPart connPart = getConnectionPart(connId);
189
			if (connPart != null)
190
			{
191
				ModelElementList<IBendPoint> bps = connBend.getConnectionBendpoints();
192
				int index = 0;
193
				for (IBendPoint pt : bps)
194
				{
195
					this.addConnectionBendpoint(connPart, index++, pt.getX().getContent(), pt.getY().getContent());
196
				}
197
			}			
198
		}
199
	}
200
	
201
	public void write() throws ResourceStoreException
202
	{
203
		this.geometryModel.getDiagramNodeGeometries().clear();
204
		Iterator<DiagramNodePart> it = this.nodeGeometries.keySet().iterator();
205
		while (it.hasNext())
206
		{
207
			DiagramNodePart nodePart = it.next();
208
			Bounds bounds = this.nodeGeometries.get(nodePart);
209
			String id = nodePart.getInstanceId();
210
			
211
			if (bounds != null && id != null)
212
			{
213
				IDiagramNodeGeometry diagramNode = this.geometryModel.getDiagramNodeGeometries().addNewElement();
214
				diagramNode.setNodeId(id);
215
				diagramNode.setX(bounds.getX());
216
				diagramNode.setY(bounds.getY());
217
				diagramNode.setWidth(bounds.getWidth());
218
				diagramNode.setHeight(bounds.getHeight());
219
				
220
				// save the embedded connection bendpoints
221
				HashMap<DiagramConnectionPart, List<Point>> embeddedConnBendpointsMap = 
222
					this.embeddedConnectionBendpoints.get(nodePart);
223
				if (embeddedConnBendpointsMap != null)
224
				{
225
					diagramNode.getEmbeddedConnectionGeometries().clear();
226
					addConnectionBenpointsToModel(embeddedConnBendpointsMap, 
227
							diagramNode.getEmbeddedConnectionGeometries());					
228
				}				
229
			}			
230
		}
231
		
232
		this.geometryModel.getDiagramConnectionGeometries().clear();
233
		addConnectionBenpointsToModel(this.connectionBendpoints, 
234
				this.geometryModel.getDiagramConnectionGeometries());
235
		this.geometryModel.resource().save();
236
	}
237
238
	private DiagramNodePart getNodePart(String nodeId)
239
	{
240
		for (DiagramNodeTemplate nodeTemplate : this.diagramPart.getNodeTemplates())
241
		{
242
			for (DiagramNodePart nodePart : nodeTemplate.getDiagramNodes())
243
			{
244
				String nodeId2 = nodePart.getInstanceId();
245
				if (nodeId != null && nodeId2 != null && nodeId.equals(nodeId2))
246
				{
247
					return nodePart;
248
				}
249
			}
250
		}
251
		return null;
252
	}
253
	
254
	private DiagramConnectionPart getConnectionPart(String connId)
255
	{
256
		for (DiagramConnectionTemplate connTemplate : this.diagramPart.getConnectionTemplates())
257
		{
258
			for (DiagramConnectionPart connPart : connTemplate.getDiagramConnections(null))
259
			{
260
				String connId2 = connPart.getInstanceId();
261
				if (connId != null && connId2 != null && connId.equals(connId2))
262
				{
263
					return connPart;
264
				}
265
			}
266
		}
267
		return null;
268
	}
269
270
	private DiagramConnectionPart getConnectionPart(DiagramNodePart nodePart, String connId)
271
	{
272
		DiagramNodeTemplate nodeTemplate = nodePart.getDiagramNodeTemplate();
273
		DiagramEmbeddedConnectionTemplate connTemplate = 
274
			nodeTemplate.getEmbeddedConnectionTemplate();
275
		if (connTemplate != null)
276
		{
277
			List<DiagramConnectionPart> connParts = connTemplate.getDiagramConnections(nodePart.getLocalModelElement());
278
			for (DiagramConnectionPart connPart : connParts)
279
			{
280
				String connId2 = connPart.getInstanceId();
281
				if (connId != null && connId2 != null && connId.equals(connId2))
282
				{
283
					return connPart;
284
				}				
285
			}
286
		}
287
		return null;
288
	}
289
290
	private HashMap<DiagramConnectionPart, List<Point>> getConnectionBenpointsMap(DiagramConnectionPart connPart, boolean create)
291
	{
292
		HashMap<DiagramConnectionPart, List<Point>> connBendpointsMap = null;
293
		if (connPart instanceof DiagramEmbeddedConnectionPart)
294
		{
295
			DiagramNodePart srcNodePart = ((DiagramEmbeddedConnectionPart)connPart).getSourceNodePart();
296
			if (srcNodePart == null)
297
			{
298
				throw new RuntimeException("Could not locate the source node for the embedded connection");
299
			}
300
			connBendpointsMap = this.embeddedConnectionBendpoints.get(srcNodePart);
301
			if (connBendpointsMap == null)
302
			{
303
				if (create)
304
				{
305
					connBendpointsMap = new HashMap<DiagramConnectionPart, List<Point>>();
306
					this.embeddedConnectionBendpoints.put(srcNodePart, connBendpointsMap);
307
				}
308
			}
309
		}
310
		else
311
		{
312
			connBendpointsMap = this.connectionBendpoints;
313
		}
314
		return connBendpointsMap;
315
	}
316
	
317
	private void addConnectionBenpointsToModel(HashMap<DiagramConnectionPart, List<Point>> connBendpointsMap, 
318
			ModelElementList<IDiagramConnectionGeometry> connGeometries)
319
	{
320
		Iterator<DiagramConnectionPart> connIt = connBendpointsMap.keySet().iterator();
321
		while (connIt.hasNext())
322
		{
323
			DiagramConnectionPart connPart = connIt.next();
324
			List<Point> bps = connBendpointsMap.get(connPart);
325
			String id = connPart.getInstanceId();
326
			
327
			if (bps != null && id != null)
328
			{
329
				IDiagramConnectionGeometry conn = connGeometries.addNewElement();
330
				conn.setConnectionId(id);
331
				for (Point pt : bps)
332
				{
333
					IBendPoint pt2 = conn.getConnectionBendpoints().addNewElement();
334
					pt2.setX(pt.x);
335
					pt2.setY(pt.y);
336
				}
337
			}
338
		}
339
		
340
	}
341
	
342
	// -------------------------------------------------------------------
343
	// Inner classes
344
	// -------------------------------------------------------------------
345
	
346
	public static class Point
347
	{
348
		private int x;
349
		private int y;
350
		
351
		public Point(int x, int y)
352
		{
353
			this.x = x;
354
			this.y = y;
355
		}
356
		
357
		public int getX() 
358
		{ 
359
			return this.x; 
360
		}
361
		
362
		public void setX(int x) 
363
		{
364
			this.x = x;
365
		}
366
		
367
		public int getY()
368
		{
369
			return this.y;
370
		}
371
		
372
		public void setY(int y)
373
		{
374
			this.y = y;
375
		}
376
	}
377
	
378
	public static final class Bounds extends Point
379
	{
380
		private int width;
381
		private int height;
382
		
383
		public Bounds(int x, int y, int width, int height)
384
		{
385
			super(x, y);
386
			this.width = width;
387
			this.height = height;
388
		}
389
		
390
		public int getWidth()
391
		{
392
			return this.width;
393
		}
394
		
395
		public void setWidth(int w)
396
		{
397
			this.width = w;
398
		}
399
		
400
		public int getHeight()
401
		{
402
			return this.height;
403
		}
404
		
405
		public void setHeight(int h)
406
		{
407
			this.height = h;
408
		}
409
	}
410
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/DiagramNodePart.java (+193 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.impl.UpdateContext;
5
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
6
import org.eclipse.sapphire.modeling.IModelElement;
7
import org.eclipse.sapphire.modeling.ValueProperty;
8
import org.eclipse.sapphire.modeling.el.FunctionResult;
9
import org.eclipse.sapphire.ui.SapphirePart;
10
import org.eclipse.sapphire.ui.SapphireRenderingContext;
11
import org.eclipse.sapphire.ui.diagram.def.IDiagramNodeDef;
12
13
public class DiagramNodePart extends SapphirePart 
14
{
15
	private DiagramNodeTemplate nodeTemplate;
16
	private IDiagramNodeDef definition;
17
	private IModelElement modelElement;
18
	private FunctionResult labelFunctionResult;
19
	private FunctionResult idFunctionResult;
20
	private FunctionResult imageFunctionResult;
21
	private ValueProperty labelProperty;
22
	
23
	public DiagramNodePart(DiagramNodeTemplate nodeTemplate)
24
	{
25
		this.nodeTemplate = nodeTemplate;
26
	}
27
	
28
    @Override
29
    protected void init()
30
    {
31
        super.init();
32
        
33
        this.definition = (IDiagramNodeDef)super.definition;
34
        this.modelElement = getModelElement();
35
        this.labelFunctionResult = initExpression
36
        ( 
37
        	this.modelElement,
38
            this.definition.getLabel().element().getContent(), 
39
            new Runnable()
40
            {
41
                public void run()
42
                {
43
                	refreshLabel();
44
                }
45
            }
46
        );
47
        this.labelProperty = FunctionUtil.getFunctionProperty(this.modelElement, this.labelFunctionResult);
48
        
49
        this.idFunctionResult = initExpression
50
        ( 
51
        	this.modelElement,
52
            this.definition.getInstanceId(), 
53
            new Runnable()
54
            {
55
                public void run()
56
                {
57
                }
58
            }
59
        );
60
        
61
        if (this.definition.getImage().element() != null)
62
        {
63
	        this.imageFunctionResult = initExpression
64
	        ( 
65
	        	this.modelElement,
66
	            this.definition.getImage().element().getValue(), 
67
	            new Runnable()
68
	            {
69
	                public void run()
70
	                {
71
	                	refreshImage();
72
	                }
73
	            }
74
	        );
75
        }
76
    }
77
    
78
    public DiagramNodeTemplate getDiagramNodeTemplate()
79
    {
80
    	return this.nodeTemplate;
81
    }
82
    
83
    public IModelElement getLocalModelElement()
84
    {
85
        return this.modelElement;
86
    }    
87
        
88
	@Override
89
	public void render(SapphireRenderingContext context)
90
	{
91
		throw new UnsupportedOperationException();
92
	}
93
94
	@Override
95
	public void dispose()
96
	{
97
		super.dispose();
98
		if (this.labelFunctionResult != null)
99
		{
100
			this.labelFunctionResult.dispose();
101
		}
102
		
103
		if (this.idFunctionResult != null)
104
		{
105
			this.idFunctionResult.dispose();
106
		}
107
	}
108
	
109
	public String getLabel()
110
	{
111
        String label = null;
112
        
113
        if( this.labelFunctionResult != null )
114
        {
115
            label = (String) this.labelFunctionResult.value();
116
        }
117
        
118
        if( label == null )
119
        {
120
            label = "#null#";
121
        }
122
        
123
        return label;
124
	}
125
126
	public void setLabel(String newValue)
127
	{
128
		if (this.labelProperty != null)
129
		{
130
			this.modelElement.write(this.labelProperty, newValue);
131
		}
132
	}
133
	
134
	public void refreshLabel()
135
	{
136
		updateNodePE();
137
	}
138
	
139
	public void refreshImage()
140
	{
141
		updateNodePE();
142
	}
143
	
144
	public boolean canEditLabel()
145
	{
146
		return this.labelProperty != null;
147
	}
148
	
149
	public String getInstanceId()
150
	{
151
        String id = null;
152
        
153
        if( this.idFunctionResult != null )
154
        {
155
            id = (String) this.idFunctionResult.value();
156
        }
157
        
158
        if( id == null )
159
        {
160
            id = "#null#";
161
        }
162
        
163
        return id;		
164
	}
165
	
166
	public boolean canResizeShape()
167
	{
168
		return this.definition.getHint("resizable", true);
169
	}
170
	
171
	public String getImageId()
172
	{
173
        if( this.imageFunctionResult != null )
174
        {
175
            String idStr = (String) this.imageFunctionResult.value();
176
            return idStr;
177
        }
178
        return null;		
179
	}
180
		
181
	private void updateNodePE()
182
	{
183
		final SapphireDiagramEditorPart diagramEditor = (SapphireDiagramEditorPart)getParentPart();
184
		final IFeatureProvider fp = 
185
						diagramEditor.getDiagramEditor().getDiagramTypeProvider().getFeatureProvider();
186
		final PictogramElement pe = getDiagramNodeTemplate().getContainerShape(fp, this);
187
		if (pe != null)
188
		{
189
			UpdateContext context = new UpdateContext(pe);
190
			fp.updateIfPossible(context);
191
		}
192
	}
193
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/DiagramNodeTemplate.java (+286 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.List;
6
7
import org.eclipse.emf.transaction.RecordingCommand;
8
import org.eclipse.emf.transaction.TransactionalEditingDomain;
9
import org.eclipse.emf.transaction.util.TransactionUtil;
10
import org.eclipse.graphiti.features.IFeatureProvider;
11
import org.eclipse.graphiti.features.IRemoveFeature;
12
import org.eclipse.graphiti.features.context.IRemoveContext;
13
import org.eclipse.graphiti.features.context.impl.AddContext;
14
import org.eclipse.graphiti.features.context.impl.RemoveContext;
15
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
16
import org.eclipse.graphiti.mm.pictograms.Diagram;
17
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
18
import org.eclipse.sapphire.modeling.IModelElement;
19
import org.eclipse.sapphire.modeling.ListProperty;
20
import org.eclipse.sapphire.modeling.ModelElementList;
21
import org.eclipse.sapphire.modeling.ModelElementType;
22
import org.eclipse.sapphire.modeling.ModelProperty;
23
import org.eclipse.sapphire.modeling.ModelPropertyChangeEvent;
24
import org.eclipse.sapphire.modeling.ModelPropertyListener;
25
import org.eclipse.sapphire.ui.diagram.def.IDiagramEmbeddedConnectionDef;
26
import org.eclipse.sapphire.ui.diagram.def.IDiagramNodeDef;
27
28
public class DiagramNodeTemplate 
29
{
30
	private SapphireDiagramEditorPart diagramEditor;
31
	private IDiagramNodeDef definition;
32
	private IModelElement modelElement;	
33
	private String propertyName;
34
	private ListProperty modelProperty;
35
	private String toolPaletteLabel;
36
	private String toolPaletteDesc;
37
	private DiagramEmbeddedConnectionTemplate embeddedConnTemplate;
38
	private ModelPropertyListener modelPropertyListener;
39
	
40
	private List<DiagramNodePart> diagramNodes;
41
	    
42
    public DiagramNodeTemplate(final SapphireDiagramEditorPart diagramEditor, IDiagramNodeDef definition, IModelElement modelElement)
43
    {
44
    	this.diagramEditor = diagramEditor;
45
    	this.modelElement = modelElement;
46
    	this.definition = definition;
47
    	
48
        this.toolPaletteLabel = this.definition.getToolPaletteLabel().getContent();
49
        this.toolPaletteDesc = this.definition.getToolPaletteDesc().getContent();
50
        
51
        this.diagramNodes = new ArrayList<DiagramNodePart>();
52
        
53
        this.propertyName = this.definition.getProperty().getContent();
54
        this.modelProperty = (ListProperty)resolve(this.modelElement, this.propertyName);
55
    	ModelElementList<?> list = this.modelElement.read(this.modelProperty);
56
        for( IModelElement listEntryModelElement : list )
57
        {
58
        	DiagramNodePart node = new DiagramNodePart(this);
59
        	node.init(this.diagramEditor, listEntryModelElement, definition, 
60
        			Collections.<String,String>emptyMap());
61
        	this.diagramNodes.add(node);
62
        }
63
        
64
        // handle embedded connections
65
        if (this.definition.getEmbeddedConnections().element() != null)
66
        {
67
        	IDiagramEmbeddedConnectionDef embeddedConnDef = 
68
        				this.definition.getEmbeddedConnections().element();
69
        	this.embeddedConnTemplate = new DiagramEmbeddedConnectionTemplate(
70
        									this.diagramEditor,
71
        									this, 
72
        									embeddedConnDef, 
73
        									this.modelElement);
74
        }
75
        
76
        // Add model property listener
77
        this.modelPropertyListener = new ModelPropertyListener()
78
        {
79
            @Override
80
            public void handlePropertyChangedEvent( final ModelPropertyChangeEvent event )
81
            {
82
                handleModelPropertyChange( event );
83
            }
84
        };
85
        addModelListener();        
86
    }
87
    
88
    public IDiagramNodeDef getDefinition()
89
    {
90
    	return this.definition;
91
    }
92
    
93
    public List<DiagramNodePart> getDiagramNodes()
94
    {
95
    	return this.diagramNodes;
96
    }
97
    
98
    public String getToolPaletteLabel()
99
    {
100
    	return this.toolPaletteLabel;
101
    }
102
    
103
    public String getToolPaletteDesc()
104
    {
105
    	return this.toolPaletteDesc;
106
    }
107
    
108
    public DiagramNodePart createNewDiagramNode()
109
    {
110
    	IModelElement newElement = null;
111
		ModelElementList<?> list = this.modelElement.read(this.modelProperty);
112
		newElement = list.addNewElement();
113
    	DiagramNodePart newNode = createNodePart(newElement);
114
    	return newNode;
115
    }
116
    
117
    public ModelProperty getModelProperty()
118
    {
119
    	return this.modelProperty;
120
    }
121
    
122
    public ModelElementType getNodeType()
123
    {
124
    	return this.modelProperty.getType();
125
    }
126
    
127
    public DiagramEmbeddedConnectionTemplate getEmbeddedConnectionTemplate()
128
    {
129
    	return this.embeddedConnTemplate;
130
    }
131
    
132
    public void addModelListener()
133
    {
134
    	this.modelElement.addListener(this.modelPropertyListener, this.propertyName);
135
    }
136
    
137
    public void removeModelLister()
138
    {
139
    	this.modelElement.removeListener(this.modelPropertyListener, this.propertyName);
140
    }
141
    
142
    private ModelProperty resolve(final IModelElement modelElement, 
143
    		String propertyName)
144
    {
145
    	if (propertyName != null)
146
    	{
147
	        final ModelElementType type = modelElement.getModelElementType();
148
	        final ModelProperty property = type.getProperty( propertyName );
149
	        
150
	        if( property == null )
151
	        {
152
	            throw new RuntimeException( "Could not find property " + propertyName + " in " + type.getQualifiedName() );
153
	        }
154
	        return property;
155
    	}    
156
        return null;
157
    }
158
    
159
    private void handleModelPropertyChange(final ModelPropertyChangeEvent event)
160
    {
161
    	final IModelElement element = event.getModelElement();
162
    	final ModelProperty property = event.getProperty();
163
    	ModelElementList<?> newList = (ModelElementList<?>)element.read(property);
164
    	if (newList.size() != getDiagramNodes().size())
165
    	{
166
    		List<DiagramNodePart> nodeParts = getDiagramNodes();
167
    		List<IModelElement> oldList = new ArrayList<IModelElement>(nodeParts.size());
168
    		for (DiagramNodePart nodePart : nodeParts)
169
    		{
170
    			oldList.add(nodePart.getLocalModelElement());
171
    		}
172
    		
173
    		final IFeatureProvider fp = this.diagramEditor.getDiagramEditor().getDiagramTypeProvider().getFeatureProvider();
174
    		final Diagram diagram = this.diagramEditor.getDiagramEditor().getDiagramTypeProvider().getDiagram();
175
			final TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(diagram);
176
    		
177
	    	if (newList.size() > oldList.size())
178
	    	{
179
	    		// new nodes are added outside of the diagram editor
180
	    		List<IModelElement> newNodes = ListUtil.ListDiff(newList, oldList);
181
	    		for (IModelElement newNode : newNodes)
182
	    		{
183
	    			// If new model element is added through palette, we don't need to 
184
	    			// add its graphical representation to the diagram since the create
185
	    			// feature takes care of that. If the new model element is added through
186
	    			// other means (form editor or source editor, we need to add the PE to the
187
	    			// diagram
188
	    			DiagramNodePart nodePart = getNodePart(newNode);
189
	    			if (nodePart == null)
190
	    			{
191
	    		    	nodePart = createNodePart(newNode);
192
						AddContext ctx = new AddContext();
193
						ctx.setNewObject(nodePart);
194
						ctx.setTargetContainer(diagram);
195
		    			fp.addIfPossible(ctx);
196
	    			}
197
	    		}
198
	    	}
199
	    	else if (newList.size() < oldList.size())
200
	    	{
201
	    		// nodes are deleted
202
	    		List<IModelElement> deletedNodes = ListUtil.ListDiff(newList, oldList);
203
	    		for (IModelElement deletedNode : deletedNodes)
204
	    		{
205
	    			DiagramNodePart nodePart = getNodePart(deletedNode);
206
	    			if (nodePart != null)
207
	    			{
208
	    				PictogramElement pe = getContainerShape(fp, nodePart);
209
	    				final IRemoveContext rc = new RemoveContext(pe);
210
	    				final IRemoveFeature removeFeature = fp.getRemoveFeature(rc);
211
	    				if (removeFeature != null) 
212
	    				{
213
	    					ted.getCommandStack().execute(new RecordingCommand(ted) 
214
	    					{
215
	    						protected void doExecute() 
216
	    						{			    					
217
	    							removeFeature.remove(rc);
218
	    						}
219
	    					});
220
	    					nodePart.dispose();
221
	    					this.diagramNodes.remove(nodePart);
222
	    				}	    				
223
	    			}
224
	    		}
225
	    	}
226
    	}
227
    }
228
    
229
    private DiagramNodePart getNodePart(IModelElement element)
230
    {
231
    	List<DiagramNodePart> nodeParts = getDiagramNodes();
232
    	for (DiagramNodePart nodePart : nodeParts)
233
    	{
234
    		if (nodePart.getLocalModelElement().equals(element))
235
    		{
236
    			return nodePart;
237
    		}
238
    	}
239
    	return null;
240
    }
241
    
242
    private DiagramNodePart createNodePart(IModelElement element)
243
    {
244
    	DiagramNodePart newNode = new DiagramNodePart(this);
245
    	newNode.init(this.diagramEditor, element, this.definition, 
246
    			Collections.<String,String>emptyMap());
247
    	if (this.embeddedConnTemplate != null)
248
    	{
249
    		this.embeddedConnTemplate.addModelListener(element);
250
    	}
251
    	this.diagramNodes.add(newNode);
252
    	return newNode;    	
253
    }
254
    
255
	public ContainerShape getContainerShape(IFeatureProvider fp, Object bo)
256
	{
257
		ContainerShape containerShape = null;
258
		PictogramElement [] pictograms = fp.getAllPictogramElementsForBusinessObject(bo);
259
		for (PictogramElement pictogram : pictograms)
260
		{
261
			if (pictogram instanceof ContainerShape)
262
			{
263
				containerShape = (ContainerShape)pictogram;
264
				break;
265
			}
266
		}
267
		return containerShape;
268
	}
269
	
270
	void dispose()
271
	{
272
		removeModelLister();
273
		
274
		List<DiagramNodePart> nodeParts = getDiagramNodes();
275
		for (DiagramNodePart nodePart : nodeParts)
276
		{
277
			nodePart.dispose();
278
		}
279
		
280
		if (this.embeddedConnTemplate != null)
281
		{
282
			this.embeddedConnTemplate.dispose();
283
		}
284
	}
285
    
286
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/FunctionUtil.java (+44 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import java.util.List;
4
5
import org.eclipse.sapphire.modeling.IModelElement;
6
import org.eclipse.sapphire.modeling.ModelElementType;
7
import org.eclipse.sapphire.modeling.ModelProperty;
8
import org.eclipse.sapphire.modeling.ValueProperty;
9
import org.eclipse.sapphire.modeling.el.FunctionResult;
10
import org.eclipse.sapphire.modeling.el.RootPropertyAccessFunction;
11
12
public class FunctionUtil 
13
{
14
    public static ValueProperty getFunctionProperty(IModelElement modelElement, FunctionResult functionResult)
15
    {
16
    	if (functionResult.function() instanceof RootPropertyAccessFunction)
17
    	{
18
    		if (functionResult.operand(0).value() instanceof String)
19
    		{
20
    			String propName = (String)functionResult.operand(0).value();
21
    	        final ModelElementType type = modelElement.getModelElementType();
22
    	        final ModelProperty property = type.getProperty(propName);
23
    			if (property instanceof ValueProperty)
24
    			{
25
    				return (ValueProperty)property;
26
    			}
27
    		}
28
    	}
29
    	else 
30
    	{
31
    		List<FunctionResult> subFuncs = functionResult.operands();
32
    		for (FunctionResult subFunc : subFuncs)
33
    		{
34
    			ValueProperty property = getFunctionProperty(modelElement, subFunc);
35
    			if (property != null)
36
    			{
37
    				return property;
38
    			}
39
    		}
40
    	}
41
    	return null;
42
    }
43
44
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/ListUtil.java (+37 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
6
import org.eclipse.sapphire.modeling.IModelElement;
7
8
public class ListUtil 
9
{
10
	public static List<IModelElement> ListDiff(List<? extends IModelElement> list1, 
11
			List<? extends IModelElement> list2)
12
	{
13
		List<IModelElement> retList = new ArrayList<IModelElement>();
14
		if (list1.size() > list2.size())
15
		{
16
			for (IModelElement element : list1)
17
			{
18
				if (!list2.contains(element))
19
				{
20
					retList.add(element);
21
				}
22
			}
23
		}
24
		else if (list2.size() > list1.size())
25
		{			
26
			for (IModelElement element : list2)
27
			{
28
				if (!list1.contains(element))
29
				{
30
					retList.add(element);
31
				}
32
			}
33
		}
34
		return retList;
35
	}
36
	
37
}
(-)src/org/eclipse/sapphire/ui/diagram/editor/SapphireDiagramEditorPart.java (+236 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.editor;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
import java.util.Set;
6
7
import org.eclipse.core.resources.IFile;
8
import org.eclipse.core.runtime.IPath;
9
import org.eclipse.core.runtime.IStatus;
10
import org.eclipse.help.IContext;
11
import org.eclipse.sapphire.modeling.IModelElement;
12
import org.eclipse.sapphire.modeling.ModelElementList;
13
import org.eclipse.sapphire.ui.ISapphirePart;
14
import org.eclipse.sapphire.ui.SapphireAction;
15
import org.eclipse.sapphire.ui.SapphireActionGroup;
16
import org.eclipse.sapphire.ui.SapphireEditor;
17
import org.eclipse.sapphire.ui.SapphireImageCache;
18
import org.eclipse.sapphire.ui.SapphirePartListener;
19
import org.eclipse.sapphire.ui.def.ISapphirePartDef;
20
import org.eclipse.sapphire.ui.def.ISapphireUiDef;
21
import org.eclipse.sapphire.ui.def.SapphireUiDefFactory;
22
import org.eclipse.sapphire.ui.diagram.def.IDiagramConnectionDef;
23
import org.eclipse.sapphire.ui.diagram.def.IDiagramNodeDef;
24
import org.eclipse.sapphire.ui.diagram.def.IDiagramPageDef;
25
import org.eclipse.sapphire.ui.diagram.graphiti.editor.SapphireDiagramEditor;
26
import org.eclipse.sapphire.ui.diagram.graphiti.editor.SapphireDiagramEditorFactory;
27
import org.eclipse.sapphire.ui.diagram.graphiti.editor.SapphireDiagramEditorInput;
28
import org.eclipse.sapphire.ui.internal.SapphireUiFrameworkPlugin;
29
30
public class SapphireDiagramEditorPart
31
	implements ISapphirePart
32
{
33
    private final SapphireEditor editor;
34
    private final IModelElement rootModelElement;
35
    private IDiagramPageDef diagramPageDef = null;
36
    private DiagramGeometryWrapper diagramGeometry;
37
    private List<DiagramNodeTemplate> nodeTemplates;
38
    private List<DiagramConnectionTemplate> connectionTemplates;
39
    private SapphireDiagramEditorInput diagramInput;
40
    private SapphireDiagramEditor diagramEditor;
41
	
42
	public SapphireDiagramEditorPart(final SapphireEditor editor,
43
								final IModelElement rootModelElement,
44
								final IPath pageDefinitionLocation )
45
	{
46
		this(editor, rootModelElement, pageDefinitionLocation, null);
47
	}
48
49
	public SapphireDiagramEditorPart(final SapphireEditor editor,
50
								final IModelElement rootModelElement,
51
								final IPath pageDefinitionLocation,
52
								String pageName )
53
	{
54
		this.editor = editor;
55
		this.rootModelElement = rootModelElement;
56
57
        final String bundleId = pageDefinitionLocation.segment( 0 );
58
        final String pageId = pageDefinitionLocation.lastSegment();
59
        final String relPath = pageDefinitionLocation.removeFirstSegments( 1 ).removeLastSegments( 1 ).toPortableString();
60
        
61
        final ISapphireUiDef def = SapphireUiDefFactory.load( bundleId, relPath );
62
        
63
        for( IDiagramPageDef pg : def.getDiagramPageDefs() )
64
        {
65
            if( pageId.equals( pg.getId().getText() ) )
66
            {
67
                this.diagramPageDef = pg;
68
                break;
69
            }
70
        }
71
                
72
        this.nodeTemplates = new ArrayList<DiagramNodeTemplate>();
73
        ModelElementList<IDiagramNodeDef> nodeDefs = this.diagramPageDef.getDiagramNodeDefs();
74
        
75
        for (IDiagramNodeDef nodeDef : nodeDefs)
76
        {
77
        	DiagramNodeTemplate nodeTemplate = new DiagramNodeTemplate(this, nodeDef, this.rootModelElement);
78
        	this.nodeTemplates.add(nodeTemplate);
79
        }
80
        
81
        this.connectionTemplates = new ArrayList<DiagramConnectionTemplate>();
82
        ModelElementList<IDiagramConnectionDef> connectionDefs = this.diagramPageDef.getDiagramConnectionDefs();
83
        for (IDiagramConnectionDef connectionDef : connectionDefs)
84
        {
85
        	DiagramConnectionTemplate connectionTemplate = new DiagramConnectionTemplate(this, connectionDef, this.rootModelElement);
86
        	this.connectionTemplates.add(connectionTemplate);
87
        }       
88
        
89
        initializeDiagramEditor();
90
	}
91
92
	private void initializeDiagramEditor()
93
	{
94
        try
95
        {
96
        	this.diagramInput = SapphireDiagramEditorFactory.createEditorInput(this.editor.getEditorInput());
97
        	IFile npFile = this.diagramInput.getNodePositionFile();
98
        	this.diagramGeometry = new DiagramGeometryWrapper(npFile, this);
99
        }
100
        catch( Exception e )
101
        {
102
            SapphireUiFrameworkPlugin.log( e );
103
        }
104
    	this.diagramEditor = new SapphireDiagramEditor(this);
105
	}
106
	
107
	public SapphireDiagramEditorInput getDiagramEditorInput()
108
	{
109
		return this.diagramInput;
110
	}
111
	
112
	public SapphireDiagramEditor getDiagramEditor()
113
	{
114
		return this.diagramEditor;
115
	}
116
	
117
	public List<DiagramNodeTemplate> getNodeTemplates()
118
	{
119
		return this.nodeTemplates;
120
	}
121
	
122
	public List<DiagramConnectionTemplate> getConnectionTemplates()
123
	{
124
		return this.connectionTemplates;
125
	}
126
	
127
	public DiagramGeometryWrapper getDiagramGeometry()
128
	{
129
		return this.diagramGeometry;
130
	}
131
	
132
	public ISapphirePart getParentPart() 
133
	{	
134
		return this.editor;
135
	}
136
137
	public <T> T getNearestPart(Class<T> partType) {
138
		// TODO Auto-generated method stub
139
		return null;
140
	}
141
142
	public IModelElement getModelElement() 
143
	{	
144
		return this.rootModelElement;
145
	}
146
	
147
	public DiagramNodePart getDiagramNodePart(IModelElement nodeElement)
148
	{
149
		if (nodeElement == null)
150
			return null;
151
		
152
		List<DiagramNodeTemplate> nodeTemplates = this.getNodeTemplates();
153
		for (DiagramNodeTemplate nodeTemplate : nodeTemplates)
154
		{
155
			if (nodeTemplate.getNodeType().equals(nodeElement.getModelElementType()))
156
			{
157
				List<DiagramNodePart> nodeParts = nodeTemplate.getDiagramNodes();
158
				for (DiagramNodePart nodePart : nodeParts)
159
				{
160
					if (nodePart.getLocalModelElement().equals(nodeElement))
161
					{
162
						return nodePart;
163
					}
164
				}
165
			}
166
		}
167
		return null;
168
	}
169
	
170
	public IStatus getValidationState() {
171
		// TODO Auto-generated method stub
172
		return null;
173
	}
174
175
	public IContext getDocumentationContext() {
176
		// TODO Auto-generated method stub
177
		return null;
178
	}
179
180
	public SapphireImageCache getImageCache() {
181
		// TODO Auto-generated method stub
182
		return null;
183
	}
184
185
	public void addListener(SapphirePartListener listener) {
186
		// TODO Auto-generated method stub
187
		
188
	}
189
190
	public void removeListener(SapphirePartListener listener) {
191
		// TODO Auto-generated method stub
192
		
193
	}
194
195
	public void dispose() 
196
	{
197
		for (DiagramNodeTemplate nodeTemplate : this.nodeTemplates)
198
		{
199
			nodeTemplate.dispose();
200
		}
201
		for (DiagramConnectionTemplate connTemplate : this.connectionTemplates)
202
		{
203
			connTemplate.dispose();
204
		}
205
	}
206
207
	public ISapphirePartDef getDefinition() 
208
	{	
209
		return this.diagramPageDef;
210
	}
211
212
	public Set<String> getActionContexts() {
213
		// TODO Auto-generated method stub
214
		return null;
215
	}
216
217
	public String getMainActionContext() {
218
		// TODO Auto-generated method stub
219
		return null;
220
	}
221
222
	public SapphireActionGroup getActions() {
223
		// TODO Auto-generated method stub
224
		return null;
225
	}
226
227
	public SapphireActionGroup getActions(String context) {
228
		// TODO Auto-generated method stub
229
		return null;
230
	}
231
232
	public SapphireAction getAction(String id) {
233
		// TODO Auto-generated method stub
234
		return null;
235
	}
236
}
(-)src/org/eclipse/sapphire/ui/diagram/geometry/IBendPoint.java (+40 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.geometry;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ModelElementType;
5
import org.eclipse.sapphire.modeling.Value;
6
import org.eclipse.sapphire.modeling.ValueProperty;
7
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
8
import org.eclipse.sapphire.modeling.annotations.Type;
9
import org.eclipse.sapphire.modeling.xml.annotations.CustomXmlValueBinding;
10
import org.eclipse.sapphire.ui.diagram.geometry.internal.GeometryAttributeBinding;
11
12
@GenerateImpl
13
14
public interface IBendPoint extends IModelElement 
15
{
16
	ModelElementType TYPE = new ModelElementType( IBendPoint.class );
17
	
18
    // *** X ***
19
    
20
    @Type( base = Integer.class )
21
    @CustomXmlValueBinding( impl = GeometryAttributeBinding.class, params = {"x"})
22
    
23
    ValueProperty PROP_X = new ValueProperty( TYPE, "X");
24
    
25
    Value<Integer> getX();
26
    void setX(Integer value);
27
	void setX(String value);
28
29
    // *** Y ***
30
    
31
    @Type( base = Integer.class )
32
    @CustomXmlValueBinding( impl = GeometryAttributeBinding.class, params = {"y"})
33
34
    ValueProperty PROP_Y = new ValueProperty( TYPE, "Y");
35
    
36
    Value<Integer> getY();
37
    void setY(Integer value);
38
	void setY(String value);
39
	
40
}
(-)src/org/eclipse/sapphire/ui/diagram/geometry/IDiagramConnectionGeometry.java (+41 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.geometry;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ListProperty;
5
import org.eclipse.sapphire.modeling.ModelElementList;
6
import org.eclipse.sapphire.modeling.ModelElementType;
7
import org.eclipse.sapphire.modeling.Value;
8
import org.eclipse.sapphire.modeling.ValueProperty;
9
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
10
import org.eclipse.sapphire.modeling.annotations.NonNullValue;
11
import org.eclipse.sapphire.modeling.annotations.Type;
12
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
13
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
14
15
@GenerateImpl
16
17
public interface IDiagramConnectionGeometry extends IModelElement 
18
{
19
	ModelElementType TYPE = new ModelElementType( IDiagramConnectionGeometry.class );
20
	
21
	// *** ConnectionId ***
22
	
23
	@XmlBinding( path = "id")
24
	@NonNullValue
25
26
	ValueProperty PROP_CONNECTION_ID = new ValueProperty( TYPE, "ConnectionId" );
27
28
    Value<String> getConnectionId();
29
    void setConnectionId( String name );
30
31
    // *** ConnectionBendpoints***
32
33
    @Type( base = IBendPoint.class )
34
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "bendpoint", type = IBendPoint.class ) )
35
    
36
    ListProperty PROP_CONNECTION_BENDPOINTS = new ListProperty( TYPE, "ConnectionBendPoints" );
37
    
38
    ModelElementList<IBendPoint> getConnectionBendpoints();
39
    
40
    
41
}
(-)src/org/eclipse/sapphire/ui/diagram/geometry/IDiagramGeometry.java (+39 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.geometry;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ListProperty;
5
import org.eclipse.sapphire.modeling.ModelElementList;
6
import org.eclipse.sapphire.modeling.ModelElementType;
7
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
8
import org.eclipse.sapphire.modeling.annotations.Type;
9
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
10
import org.eclipse.sapphire.modeling.xml.annotations.XmlRootBinding;
11
12
@GenerateImpl
13
@XmlRootBinding( elementName = "diagram-geometry" )
14
15
public interface IDiagramGeometry extends IModelElement 
16
{
17
	ModelElementType TYPE = new ModelElementType( IDiagramGeometry.class );
18
	
19
    // *** DiagramNodeGeometries ***
20
21
    @Type( base = IDiagramNodeGeometry.class )
22
    
23
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "node", type = IDiagramNodeGeometry.class ) )
24
    
25
    ListProperty PROP_DIAGRAM_NODE_GEOMETRIES = new ListProperty( TYPE, "DiagramNodeGeometries" );
26
    
27
    ModelElementList<IDiagramNodeGeometry> getDiagramNodeGeometries();
28
	
29
    // *** DiagramConnectionGeometries ***
30
31
    @Type( base = IDiagramConnectionGeometry.class )
32
    
33
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "connection", type = IDiagramConnectionGeometry.class ) )
34
    
35
    ListProperty PROP_DIAGRAM_CONNECTION_GEOMETRIES = new ListProperty( TYPE, "DiagramConnectionGeometries" );
36
    
37
    ModelElementList<IDiagramConnectionGeometry> getDiagramConnectionGeometries();
38
39
}
(-)src/org/eclipse/sapphire/ui/diagram/geometry/IDiagramNodeGeometry.java (+87 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.geometry;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ListProperty;
5
import org.eclipse.sapphire.modeling.ModelElementList;
6
import org.eclipse.sapphire.modeling.ModelElementType;
7
import org.eclipse.sapphire.modeling.Value;
8
import org.eclipse.sapphire.modeling.ValueProperty;
9
import org.eclipse.sapphire.modeling.annotations.GenerateImpl;
10
import org.eclipse.sapphire.modeling.annotations.NonNullValue;
11
import org.eclipse.sapphire.modeling.annotations.Type;
12
import org.eclipse.sapphire.modeling.xml.annotations.CustomXmlValueBinding;
13
import org.eclipse.sapphire.modeling.xml.annotations.XmlBinding;
14
import org.eclipse.sapphire.modeling.xml.annotations.XmlListBinding;
15
import org.eclipse.sapphire.ui.diagram.geometry.internal.GeometryAttributeBinding;
16
17
@GenerateImpl
18
19
public interface IDiagramNodeGeometry extends IModelElement
20
{
21
	ModelElementType TYPE = new ModelElementType( IDiagramNodeGeometry.class );
22
	
23
	// *** NodeId ***
24
	
25
	@XmlBinding( path = "id")
26
	@NonNullValue
27
28
	ValueProperty PROP_NODE_ID = new ValueProperty( TYPE, "NodeId" );
29
30
    Value<String> getNodeId();
31
    void setNodeId( String name );
32
33
    // *** X ***
34
    
35
    @Type( base = Integer.class )
36
    @CustomXmlValueBinding( impl = GeometryAttributeBinding.class, params = {"gemometry", "x"})
37
    
38
    ValueProperty PROP_X = new ValueProperty( TYPE, "X");
39
    
40
    Value<Integer> getX();
41
    void setX(Integer value);
42
	void setX(String value);
43
44
    // *** Y ***
45
    
46
    @Type( base = Integer.class )
47
    @CustomXmlValueBinding( impl = GeometryAttributeBinding.class, params = {"gemometry", "y"})
48
49
    ValueProperty PROP_Y = new ValueProperty( TYPE, "Y");
50
    
51
    Value<Integer> getY();
52
    void setY(Integer value);
53
	void setY(String value);
54
    
55
    // *** Width ***
56
    
57
    @Type( base = Integer.class )
58
    @CustomXmlValueBinding( impl = GeometryAttributeBinding.class, params = {"gemometry", "width"})
59
    
60
    ValueProperty PROP_WIDTH = new ValueProperty( TYPE, "Width");
61
    
62
    Value<Integer> getWidth();
63
    void setWidth(Integer value);
64
	void setWidth(String value);
65
	
66
    // *** Height ***
67
    
68
    @Type( base = Integer.class )
69
    @CustomXmlValueBinding( impl = GeometryAttributeBinding.class, params = {"gemometry", "height"})
70
    
71
    ValueProperty PROP_HEIGHT = new ValueProperty( TYPE, "Height");
72
    
73
    Value<Integer> getHeight();
74
    void setHeight(Integer value);
75
	void setHeight(String value);
76
	
77
    // *** EmbeddedConnectionGeometries ***
78
79
    @Type( base = IDiagramConnectionGeometry.class )
80
    
81
    @XmlListBinding( mappings = @XmlListBinding.Mapping( element = "connection", type = IDiagramConnectionGeometry.class ) )
82
    
83
    ListProperty PROP_EMBEDDED_CONNECTION_GEOMETRIES = new ListProperty( TYPE, "EmbeddedConnectionGeometries" );
84
    
85
    ModelElementList<IDiagramConnectionGeometry> getEmbeddedConnectionGeometries();	
86
	
87
}
(-)src/org/eclipse/sapphire/ui/diagram/geometry/internal/GeometryAttributeBinding.java (+68 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.geometry.internal;
2
3
import org.eclipse.sapphire.modeling.IModelElement;
4
import org.eclipse.sapphire.modeling.ModelProperty;
5
import org.eclipse.sapphire.modeling.xml.XmlElement;
6
import org.eclipse.sapphire.modeling.xml.XmlValueBindingImpl;
7
8
public class GeometryAttributeBinding extends XmlValueBindingImpl
9
{
10
	private String modelPath = null;
11
	private String attrName = null;
12
	
13
	@Override
14
    public void init( final IModelElement element,
15
            final ModelProperty property,
16
            final String[] params )
17
	{
18
		super.init(element, property, params);
19
		if (params != null)
20
		{
21
			if (params.length > 1)
22
			{
23
				this.modelPath = params[0];
24
				this.attrName = params[1];
25
			}
26
			else if (params.length > 0) 
27
			{
28
				this.attrName = params[0];
29
			}
30
		}
31
	}
32
33
	@Override
34
	public String read() 
35
	{
36
		String attrVal = null;
37
		if (this.attrName != null)
38
		{
39
			XmlElement geometryEl = xml(false);
40
			if (geometryEl != null)
41
			{
42
				if (this.modelPath != null)
43
				{
44
					geometryEl = geometryEl.getChildElement(this.modelPath, false);
45
				}
46
				if (geometryEl != null)
47
				{
48
					attrVal = ( geometryEl.getAttributeText(this.attrName) );
49
				}
50
			}
51
		}
52
		return attrVal;
53
	}
54
55
	@Override
56
	public void write(String value) 
57
	{
58
		if (this.attrName != null)
59
		{
60
			XmlElement geometryEl = xml(true);
61
			if (this.modelPath != null)
62
			{
63
				geometryEl = geometryEl.getChildElement(this.modelPath, true);
64
			}
65
			geometryEl.setAttributeText( this.attrName, value, true );
66
		}		
67
	}
68
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/GraphitiFileService.java (+172 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti;
2
3
import java.io.IOException;
4
import java.io.PrintWriter;
5
import java.io.StringWriter;
6
import java.util.Collections;
7
import java.util.HashMap;
8
import java.util.HashSet;
9
import java.util.Map;
10
import java.util.Map.Entry;
11
import java.util.Set;
12
13
import org.eclipse.core.resources.IFile;
14
import org.eclipse.core.resources.IWorkspaceRunnable;
15
import org.eclipse.core.resources.ResourcesPlugin;
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.core.runtime.Path;
19
import org.eclipse.emf.common.command.CommandStack;
20
import org.eclipse.emf.common.util.EList;
21
import org.eclipse.emf.common.util.URI;
22
import org.eclipse.emf.common.util.WrappedException;
23
import org.eclipse.emf.ecore.resource.Resource;
24
import org.eclipse.emf.ecore.resource.ResourceSet;
25
import org.eclipse.emf.transaction.RecordingCommand;
26
import org.eclipse.emf.transaction.Transaction;
27
import org.eclipse.emf.transaction.TransactionalEditingDomain;
28
import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;
29
import org.eclipse.graphiti.mm.pictograms.Diagram;
30
import org.eclipse.graphiti.ui.editor.DiagramEditorFactory;
31
32
public class GraphitiFileService 
33
{
34
	public static TransactionalEditingDomain createEmfFileForDiagram(URI diagramResourceUri, final Diagram diagram) {
35
36
		// Create a resource set and EditingDomain
37
		final TransactionalEditingDomain editingDomain = DiagramEditorFactory.createResourceSetAndEditingDomain();
38
		final ResourceSet resourceSet = editingDomain.getResourceSet();
39
		// Create a resource for this file.
40
		final Resource resource = resourceSet.createResource(diagramResourceUri);
41
		final CommandStack commandStack = editingDomain.getCommandStack();
42
		commandStack.execute(new RecordingCommand(editingDomain) {
43
44
			@Override
45
			protected void doExecute() {
46
				resource.setTrackingModification(true);
47
				resource.getContents().add(diagram);
48
49
			}
50
		});
51
52
		save(editingDomain, Collections.<Resource, Map<?, ?>> emptyMap());
53
		return editingDomain;
54
	}
55
56
	private static void save(TransactionalEditingDomain editingDomain, Map<Resource, Map<?, ?>> options) {
57
		saveInWorkspaceRunnable(editingDomain, options);
58
	}
59
60
	private static void saveInWorkspaceRunnable(final TransactionalEditingDomain editingDomain, final Map<Resource, Map<?, ?>> options) {
61
62
		final Map<URI, Throwable> failedSaves = new HashMap<URI, Throwable>();
63
		final IWorkspaceRunnable wsRunnable = new IWorkspaceRunnable() {			
64
			public void run(final IProgressMonitor monitor) throws CoreException {
65
66
				final Runnable runnable = new Runnable() {
67
					
68
					public void run() {
69
						Transaction parentTx;
70
						if (editingDomain != null
71
								&& (parentTx = ((TransactionalEditingDomainImpl) editingDomain).getActiveTransaction()) != null) {
72
							do {
73
								if (!parentTx.isReadOnly()) {
74
									throw new IllegalStateException(
75
											"FileService.save() called from within a command (likely produces a deadlock)");
76
								}
77
							} while ((parentTx = ((TransactionalEditingDomainImpl) editingDomain).getActiveTransaction().getParent()) != null);
78
						}
79
80
						final EList<Resource> resources = editingDomain.getResourceSet().getResources();
81
						// Copy list to an array to prevent
82
						// ConcurrentModificationExceptions
83
						// during the saving of the dirty resources
84
						Resource[] resourcesArray = new Resource[resources.size()];
85
						resourcesArray = resources.toArray(resourcesArray);
86
						final Set<Resource> savedResources = new HashSet<Resource>();
87
						for (int i = 0; i < resourcesArray.length; i++) {
88
							// In case resource modification tracking is
89
							// switched on, we can check if a resource
90
							// has been modified, so that we only need to same
91
							// really changed resources; otherwise
92
							// we need to save all resources in the set
93
							final Resource resource = resourcesArray[i];
94
							if (resource.isModified()) {
95
								try {
96
									resource.save(options.get(resource));
97
									savedResources.add(resource);
98
								} catch (final Throwable t) {
99
									failedSaves.put(resource.getURI(), t);
100
								}
101
							}
102
						}
103
					}
104
				};
105
106
				try {
107
					editingDomain.runExclusive(runnable);
108
				} catch (final InterruptedException e) {
109
					throw new RuntimeException(e);
110
				}
111
				editingDomain.getCommandStack().flush();
112
			}
113
		};
114
		try {
115
			ResourcesPlugin.getWorkspace().run(wsRunnable, null);
116
			if (!failedSaves.isEmpty()) {
117
				throw new WrappedException(createMessage(failedSaves), new RuntimeException());
118
			}
119
		} catch (final CoreException e) {
120
			final Throwable cause = e.getStatus().getException();
121
			if (cause instanceof RuntimeException) {
122
				throw (RuntimeException) cause;
123
			}
124
			throw new RuntimeException(e);
125
		}
126
	}
127
128
	private static String createMessage(Map<URI, Throwable> failedSaves) {
129
		final StringBuilder buf = new StringBuilder("The following resources could not be saved:");
130
		for (final Entry<URI, Throwable> entry : failedSaves.entrySet()) {
131
			buf.append("\nURI: ").append(entry.getKey().toString()).append(", cause: \n").append(getExceptionAsString(entry.getValue()));
132
		}
133
		return buf.toString();
134
	}
135
136
	private static String getExceptionAsString(Throwable t) {
137
		final StringWriter stringWriter = new StringWriter();
138
		final PrintWriter printWriter = new PrintWriter(stringWriter);
139
		t.printStackTrace(printWriter);
140
		final String result = stringWriter.toString();
141
		try {
142
			stringWriter.close();
143
		} catch (final IOException e) {
144
			// $JL-EXC$ ignore
145
		}
146
		printWriter.close();
147
		return result;
148
	}
149
	
150
	public static IFile EmfResourceToIFile(Resource resource)
151
	{
152
		IFile ifile = null;
153
		
154
		URI uri = resource.getURI();
155
	    uri = resource.getResourceSet().getURIConverter().normalize(uri);
156
	    
157
	    String scheme = uri.scheme();
158
	    if ("platform".equals(scheme) && uri.segmentCount() > 1 &&
159
	    		"resource".equals(uri.segment(0)))
160
	    {
161
	    	StringBuffer platformResourcePath = new StringBuffer();
162
	    	for (int j = 1, size = uri.segmentCount(); j < size; ++j)
163
	    	{
164
	    		platformResourcePath.append('/');
165
	    		platformResourcePath.append(uri.segment(j));
166
	    	}
167
	    	return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformResourcePath.toString()));
168
	    }
169
		return ifile;
170
	}
171
172
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/editor/SapphireDiagramEditor.java (+264 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.editor;
2
3
import java.util.Collection;
4
import java.util.HashSet;
5
import java.util.Iterator;
6
import java.util.List;
7
8
import org.eclipse.core.runtime.IProgressMonitor;
9
import org.eclipse.emf.transaction.RecordingCommand;
10
import org.eclipse.emf.transaction.TransactionalEditingDomain;
11
import org.eclipse.emf.transaction.util.TransactionUtil;
12
import org.eclipse.graphiti.features.IAddFeature;
13
import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
14
import org.eclipse.graphiti.features.context.impl.AddContext;
15
import org.eclipse.graphiti.mm.algorithms.styles.Point;
16
import org.eclipse.graphiti.mm.pictograms.Anchor;
17
import org.eclipse.graphiti.mm.pictograms.Connection;
18
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
19
import org.eclipse.graphiti.mm.pictograms.Diagram;
20
import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
21
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
22
import org.eclipse.graphiti.mm.pictograms.Shape;
23
import org.eclipse.graphiti.services.Graphiti;
24
import org.eclipse.graphiti.ui.editor.DiagramEditor;
25
import org.eclipse.jface.viewers.ISelection;
26
import org.eclipse.sapphire.modeling.IModelElement;
27
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
28
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionTemplate;
29
import org.eclipse.sapphire.ui.diagram.editor.DiagramEmbeddedConnectionTemplate;
30
import org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper;
31
import org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper.Bounds;
32
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
33
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodeTemplate;
34
import org.eclipse.sapphire.ui.diagram.editor.SapphireDiagramEditorPart;
35
import org.eclipse.sapphire.ui.internal.SapphireUiFrameworkPlugin;
36
import org.eclipse.ui.IEditorPart;
37
import org.eclipse.ui.IWorkbenchPart;
38
import org.eclipse.ui.part.MultiPageEditorPart;
39
40
@SuppressWarnings("restriction")
41
public class SapphireDiagramEditor extends DiagramEditor 
42
{
43
	private SapphireDiagramEditorPart diagramPart;
44
	
45
	public SapphireDiagramEditor(SapphireDiagramEditorPart diagramPart)
46
	{
47
		this.diagramPart = diagramPart;
48
	}
49
	
50
	public SapphireDiagramEditorPart getDiagramEditorPart()
51
	{
52
		return this.diagramPart;
53
	}
54
	
55
	@Override
56
	public void selectionChanged(IWorkbenchPart part, ISelection selection) 
57
	{
58
		boolean editorIsActive = getSite().getPage().isPartVisible(this);
59
		if (editorIsActive)
60
		{
61
			super.selectionChanged(part, selection);
62
		}
63
		else 
64
		{
65
			// Check if we are a page of the active multipage editor
66
			IEditorPart activeEditor = getSite().getPage().getActiveEditor();
67
			if (getSite().getPage().isPartVisible(activeEditor) && 
68
					activeEditor instanceof MultiPageEditorPart)
69
			{
70
				MultiPageEditorPart me = (MultiPageEditorPart)activeEditor;
71
				if (me.getActivePage() == 0)
72
				{
73
					updateActions(getSelectionActions());
74
				}
75
			}
76
		}
77
	}
78
	
79
	@Override
80
	public void doSave(final IProgressMonitor monitor )
81
	{
82
		super.doSave(monitor);
83
		try
84
		{
85
			this.diagramPart.getDiagramGeometry().write();
86
		}
87
        catch( Exception e )
88
        {
89
            SapphireUiFrameworkPlugin.log( e );
90
        }		
91
	}
92
	
93
	public void syncDiagramWithModel()
94
	{
95
		final Diagram diagram = getDiagramTypeProvider().getDiagram();
96
		
97
		TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(diagram);
98
		ted.getCommandStack().execute(new RecordingCommand(ted) 
99
		{
100
			protected void doExecute() 
101
			{		
102
				removeConnections(diagram);
103
				removeNodes(diagram);
104
				
105
				reconstructNodes(diagram);
106
				reconstructConnections(diagram);
107
			}
108
		});
109
	}
110
	
111
	private void removeConnections(final Diagram diagram) 
112
	{
113
		List<Connection> cons = diagram.getConnections();
114
		Iterator<Connection> consIt = cons.iterator();
115
		// don't cause ConcurrentModificationException
116
		Collection<Connection> allCons = new HashSet<Connection>();
117
		while (consIt.hasNext()) 
118
		{
119
			Connection con = consIt.next();
120
			allCons.add(con);
121
		}
122
		consIt = allCons.iterator();
123
		while (consIt.hasNext()) 
124
		{
125
			Connection con = consIt.next();			
126
			Graphiti.getPeService().deletePictogramElement(con);
127
		}		
128
	}
129
	
130
	private void removeNodes(final Diagram diagram)
131
	{
132
		List<Shape> containerShapes = diagram.getChildren();
133
		Iterator<Shape> shapeIt = containerShapes.iterator();
134
		// don't cause ConcurrentModificationException
135
		Collection<Shape> allShapes = new HashSet<Shape>();
136
		while (shapeIt.hasNext())
137
		{
138
			Shape shape = shapeIt.next();
139
			allShapes.add(shape);
140
		}
141
		shapeIt = allShapes.iterator();
142
		while (shapeIt.hasNext())
143
		{
144
			Shape containerShape = shapeIt.next();
145
			Graphiti.getPeService().deletePictogramElement(containerShape);
146
		}
147
	}
148
	
149
	private void reconstructNodes(final Diagram diagram)
150
	{
151
		// Add the nodes back to the diagram thus re-establishing mapping between
152
		// pictograms and business objects
153
		
154
		int nodeX = 50;
155
		int nodeY = 50;
156
		int xInc = 100;
157
		DiagramGeometryWrapper diagramGeometry = this.diagramPart.getDiagramGeometry();
158
		
159
		for (DiagramNodeTemplate nodeTemplate : this.diagramPart.getNodeTemplates())
160
		{
161
			for (DiagramNodePart nodePart : nodeTemplate.getDiagramNodes())
162
			{
163
				Bounds bounds = diagramGeometry.getNode(nodePart);
164
				if (bounds == null)
165
				{
166
					bounds = new Bounds(nodeX, nodeY, -1, -1);
167
					nodeX += xInc;
168
				}
169
				AddContext ctx = new AddContext();
170
				ctx.setNewObject(nodePart);
171
				ctx.setTargetContainer(diagram);
172
				ctx.setWidth(bounds.getWidth());
173
				ctx.setHeight(bounds.getHeight());
174
				ctx.setX(bounds.getX());
175
				ctx.setY(bounds.getY());
176
				IAddFeature ft = getDiagramTypeProvider().getFeatureProvider().getAddFeature(ctx);						
177
				ft.add(ctx);						
178
			}
179
			
180
			// add embedded connections
181
			DiagramEmbeddedConnectionTemplate embeddedConnTemplate = 
182
				nodeTemplate.getEmbeddedConnectionTemplate();
183
			if (embeddedConnTemplate != null)
184
			{
185
				for (DiagramConnectionPart connPart : embeddedConnTemplate.getDiagramConnections(null))
186
				{
187
					addConnection(connPart, diagramGeometry);
188
				}
189
			}
190
		}		
191
	}
192
	
193
	private void reconstructConnections(final Diagram diagram)
194
	{
195
		DiagramGeometryWrapper diagramGeometry = this.diagramPart.getDiagramGeometry();
196
		
197
		// add the top level connections back to the diagram
198
		for (DiagramConnectionTemplate connTemplate : this.diagramPart.getConnectionTemplates())
199
		{
200
			for (DiagramConnectionPart connPart : connTemplate.getDiagramConnections(null))
201
			{
202
				addConnection(connPart, diagramGeometry);
203
			}
204
		}		
205
	}
206
	
207
	private ContainerShape getContainerShape(Object bo)
208
	{
209
		ContainerShape containerShape = null;
210
		PictogramElement [] pictograms = 
211
			getDiagramTypeProvider().getFeatureProvider().getAllPictogramElementsForBusinessObject(bo);
212
		for (PictogramElement pictogram : pictograms)
213
		{
214
			if (pictogram instanceof ContainerShape)
215
			{
216
				containerShape = (ContainerShape)pictogram;
217
				break;
218
			}
219
		}
220
		return containerShape;
221
	}
222
	
223
	private Connection addConnection(DiagramConnectionPart connPart, DiagramGeometryWrapper diagramGeometry)
224
	{
225
		Connection conn = null;
226
		
227
		IModelElement endpoint1 = connPart.getEndpoint1();
228
		IModelElement endpoint2 = connPart.getEndpoint2();
229
		DiagramNodePart nodePart1 = this.diagramPart.getDiagramNodePart(endpoint1);
230
		DiagramNodePart nodePart2 = this.diagramPart.getDiagramNodePart(endpoint2);
231
		if (nodePart1 != null && nodePart2 != null)
232
		{
233
			ContainerShape sourceShape = getContainerShape(nodePart1);
234
			ContainerShape targetShape = getContainerShape(nodePart2);
235
			if (sourceShape != null && targetShape != null)
236
			{
237
				Anchor sourceAnchor = sourceShape.getAnchors().get(0);
238
				Anchor targetAnchor = targetShape.getAnchors().get(0);
239
				AddConnectionContext connCtx = new AddConnectionContext(sourceAnchor, targetAnchor);
240
				connCtx.setNewObject(connPart);
241
				IAddFeature fcfp = getDiagramTypeProvider().getFeatureProvider().getAddFeature(connCtx);
242
				
243
				conn = (Connection)fcfp.add(connCtx);
244
				if (conn instanceof FreeFormConnection && 
245
						diagramGeometry.getConnectionBendpoints(connPart) != null)
246
				{
247
					FreeFormConnection freeConn = (FreeFormConnection)conn;
248
					List<org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper.Point> bps = 
249
						diagramGeometry.getConnectionBendpoints(connPart);
250
					List<Point> bendpoints = freeConn.getBendpoints();
251
					int index = 0;
252
					for (org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper.Point pt : bps)
253
					{
254
						Point newPoint = Graphiti.getGaService().createPoint(pt.getX(), pt.getY());										
255
						bendpoints.add(index++, newPoint);										
256
					}
257
				}
258
			}							
259
		}
260
		
261
		return conn;
262
	}
263
	
264
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/editor/SapphireDiagramEditorFactory.java (+120 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.editor;
2
3
import java.io.ByteArrayInputStream;
4
import java.io.IOException;
5
import java.util.Iterator;
6
7
import org.eclipse.core.resources.IFile;
8
import org.eclipse.core.resources.IFolder;
9
import org.eclipse.core.resources.IProject;
10
import org.eclipse.core.runtime.CoreException;
11
import org.eclipse.core.runtime.Path;
12
import org.eclipse.emf.common.util.EList;
13
import org.eclipse.emf.common.util.URI;
14
import org.eclipse.emf.ecore.EObject;
15
import org.eclipse.emf.ecore.resource.Resource;
16
import org.eclipse.emf.ecore.resource.ResourceSet;
17
import org.eclipse.emf.transaction.TransactionalEditingDomain;
18
import org.eclipse.graphiti.mm.pictograms.Diagram;
19
import org.eclipse.graphiti.services.Graphiti;
20
import org.eclipse.graphiti.ui.editor.DiagramEditorFactory;
21
import org.eclipse.graphiti.ui.internal.services.GraphitiUiInternal;
22
import org.eclipse.graphiti.ui.services.GraphitiUi;
23
import org.eclipse.sapphire.modeling.util.internal.FileUtil;
24
import org.eclipse.sapphire.ui.diagram.graphiti.GraphitiFileService;
25
import org.eclipse.sapphire.ui.internal.SapphireUiFrameworkPlugin;
26
import org.eclipse.ui.IEditorInput;
27
import org.eclipse.ui.IFileEditorInput;
28
29
public class SapphireDiagramEditorFactory 
30
{
31
	public static final String SAPPHIRE_DIAGRAM_TYPE = "sapphireDiagram";
32
	
33
	public static SapphireDiagramEditorInput createEditorInput(IEditorInput otherInput) 
34
		throws CoreException
35
	{
36
		if (otherInput instanceof SapphireDiagramEditorInput)
37
		{
38
			return (SapphireDiagramEditorInput)otherInput;
39
		}
40
		else if (otherInput instanceof IFileEditorInput)
41
		{
42
			final IFileEditorInput fileInput = (IFileEditorInput) otherInput;
43
			final IFile file = fileInput.getFile();
44
			final IProject project = file.getProject();
45
			
46
			final IFolder diagramFolder = project.getFolder(".settings/diagrams/");
47
			String fileName = file.getName();
48
			if (fileName.endsWith(".xml"))
49
			{
50
				fileName = fileName.substring(0, fileName.indexOf(".xml"));
51
			}
52
			
53
			TransactionalEditingDomain domain = null;
54
			ResourceSet resourceSet = null;
55
			Diagram diagram = null;
56
			URI diagramFileUri = null;
57
			
58
			// create diagram file if it doesn't exist
59
			final IFile diagramFile = diagramFolder.getFile(fileName + ".xmi");
60
			if (!diagramFile.exists())
61
			{
62
				FileUtil.mkdirs( diagramFile.getParent().getLocation().toFile() );
63
				diagramFile.create( new ByteArrayInputStream(new byte[0]), true, null );
64
				
65
				// Create Diagram Obj
66
				diagram = Graphiti.getPeCreateService().createDiagram(
67
						SAPPHIRE_DIAGRAM_TYPE, fileName, 10, false);
68
				diagramFileUri = URI.createPlatformResourceURI(diagramFile.getFullPath().toString(), true);
69
				domain = GraphitiFileService.createEmfFileForDiagram(diagramFileUri, diagram);
70
			}
71
			else
72
			{			
73
				domain = DiagramEditorFactory.createResourceSetAndEditingDomain();
74
				resourceSet = domain.getResourceSet();
75
			
76
				diagramFileUri = GraphitiUiInternal.getEmfService().getFileURI(diagramFile, resourceSet);
77
				if (diagramFileUri != null)
78
				{
79
					final Resource resource = resourceSet.createResource(diagramFileUri);
80
					try
81
					{
82
						resource.load(null);
83
					}
84
					catch (IOException ie)
85
					{
86
						SapphireUiFrameworkPlugin.log(ie);
87
					}
88
					EList<EObject> objs = resource.getContents();
89
					Iterator<EObject> it = objs.iterator();					
90
					while (it.hasNext()) 
91
					{
92
						EObject obj = it.next();
93
						if ((obj == null) && !Diagram.class.isInstance(obj))
94
							continue;
95
						diagram = (Diagram)obj;
96
						break;
97
					}
98
				}				
99
			}
100
			// create diagram node position file if it doesn't exist
101
			IFile nodePosFile = diagramFile.getParent().getFile(new Path(fileName + ".np"));
102
			if (!nodePosFile.exists())
103
			{
104
				nodePosFile.create( new ByteArrayInputStream(new byte[0]), true, null );
105
			}
106
107
			// create sapphire diagram editor input
108
			if (diagram != null)
109
			{
110
				String providerId = GraphitiUi.getExtensionManager().getDiagramTypeProviderId(diagram.getDiagramTypeId());
111
				final SapphireDiagramEditorInput diagramEditorInput = 
112
					SapphireDiagramEditorInput.createEditorInput(diagram, domain, providerId, false);
113
				diagramEditorInput.setNodePositionFile(nodePosFile);
114
				return diagramEditorInput;
115
			}
116
		}
117
		return null;
118
	}
119
120
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/editor/SapphireDiagramEditorInput.java (+91 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.editor;
2
3
import org.eclipse.core.resources.IFile;
4
import org.eclipse.emf.common.util.URI;
5
import org.eclipse.emf.ecore.EObject;
6
import org.eclipse.emf.ecore.resource.Resource;
7
import org.eclipse.emf.ecore.resource.ResourceSet;
8
import org.eclipse.emf.transaction.TransactionalEditingDomain;
9
import org.eclipse.graphiti.mm.pictograms.Diagram;
10
import org.eclipse.graphiti.ui.editor.DiagramEditorInput;
11
12
public class SapphireDiagramEditorInput extends DiagramEditorInput 
13
{
14
	private Diagram diagram;
15
	private IFile nodePositionFile;
16
	
17
	public SapphireDiagramEditorInput(Diagram diagram, String diagramUriString,
18
			TransactionalEditingDomain domain, String providerId,
19
			boolean disposeEditingDomain) 
20
	{
21
		super(diagramUriString, domain, providerId, disposeEditingDomain);
22
		this.diagram = diagram;
23
	}
24
25
	public SapphireDiagramEditorInput(Diagram diagram, URI diagramUri,
26
			TransactionalEditingDomain domain, String providerId,
27
			boolean disposeEditingDomain) 
28
	{
29
		super(diagramUri, domain, providerId, disposeEditingDomain);
30
		this.diagram = diagram;
31
	}
32
	
33
	public Diagram getDiagram() 
34
	{
35
		return this.diagram;
36
	}	
37
	
38
	public TransactionalEditingDomain getEditingDomain() 
39
	{
40
		return this.editingDomain;
41
	}
42
	
43
	@SuppressWarnings("rawtypes")
44
	public Object getAdapter(Class adapter) 
45
	{
46
		if (EObject.class.isAssignableFrom(adapter)) 
47
		{
48
			return getDiagram();
49
		} 
50
		else if (Diagram.class.isAssignableFrom(adapter)) 
51
		{
52
			return getDiagram();
53
		}
54
		else if (TransactionalEditingDomain.class.isAssignableFrom(adapter)) 
55
		{
56
			return getEditingDomain();
57
		} 
58
		else if (ResourceSet.class.isAssignableFrom(adapter)) 
59
		{
60
			return getEditingDomain().getResourceSet();
61
		}		
62
		return null;
63
	}
64
	
65
	public IFile getNodePositionFile()
66
	{
67
		return this.nodePositionFile;
68
	}
69
	
70
	public void setNodePositionFile(IFile file)
71
	{
72
		this.nodePositionFile = file;
73
	}
74
	
75
	
76
	public static SapphireDiagramEditorInput createEditorInput(Diagram diagram, 
77
			TransactionalEditingDomain domain, String providerId, boolean disposeEditingDomain) 
78
	{
79
		final Resource resource = diagram.eResource();
80
		if (resource == null) {
81
			throw new IllegalArgumentException();
82
		}
83
		final String fragment = resource.getURIFragment(diagram);
84
		final URI fragmentUri = resource.getURI().appendFragment(fragment);
85
		SapphireDiagramEditorInput diagramEditorInput;
86
		diagramEditorInput = new SapphireDiagramEditorInput(diagram, fragmentUri,
87
				domain, providerId, disposeEditingDomain);
88
		return diagramEditorInput;
89
	}	
90
	
91
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/NoResizeConfiguration.java (+17 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IResizeConfiguration;
4
5
public class NoResizeConfiguration implements IResizeConfiguration 
6
{
7
	public boolean isVerticalResizeAllowed() 
8
	{
9
		return false;
10
	}
11
12
	public boolean isHorizontalResizeAllowed() 
13
	{
14
		return false;
15
	}
16
17
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireAddBendpointFeature.java (+33 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.IAddBendpointContext;
5
import org.eclipse.graphiti.features.impl.DefaultAddBendpointFeature;
6
import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
7
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
8
import org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper;
9
import org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramFeatureProvider;
10
11
public class SapphireAddBendpointFeature extends DefaultAddBendpointFeature 
12
{
13
	public SapphireAddBendpointFeature(IFeatureProvider fp)
14
	{
15
		super(fp);
16
	}
17
	
18
	@Override
19
	public void addBendpoint(IAddBendpointContext context) 
20
	{
21
		super.addBendpoint(context);
22
		
23
		FreeFormConnection freeFormConnection = context.getConnection();
24
		Object bo = getBusinessObjectForPictogramElement(freeFormConnection);
25
		if (bo instanceof DiagramConnectionPart)
26
		{
27
			DiagramGeometryWrapper dg = 
28
				((SapphireDiagramFeatureProvider)getFeatureProvider()).getDiagramGeometry();
29
			dg.addConnectionBendpoint((DiagramConnectionPart)bo, 
30
					context.getBendpointIndex(), context.getX(), context.getY());
31
		}		
32
	}	
33
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireAddConnectionFeature.java (+97 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IDirectEditingInfo;
4
import org.eclipse.graphiti.features.IFeatureProvider;
5
import org.eclipse.graphiti.features.context.IAddConnectionContext;
6
import org.eclipse.graphiti.features.context.IAddContext;
7
import org.eclipse.graphiti.features.impl.AbstractAddFeature;
8
import org.eclipse.graphiti.mm.GraphicsAlgorithmContainer;
9
import org.eclipse.graphiti.mm.algorithms.Polygon;
10
import org.eclipse.graphiti.mm.algorithms.Polyline;
11
import org.eclipse.graphiti.mm.algorithms.Text;
12
import org.eclipse.graphiti.mm.pictograms.Connection;
13
import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator;
14
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
15
import org.eclipse.graphiti.services.Graphiti;
16
import org.eclipse.graphiti.services.IGaService;
17
import org.eclipse.graphiti.services.IPeCreateService;
18
import org.eclipse.graphiti.util.IColorConstant;
19
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
20
21
public class SapphireAddConnectionFeature extends AbstractAddFeature 
22
{
23
	public SapphireAddConnectionFeature(IFeatureProvider fp)
24
	{
25
		super(fp);
26
	}
27
	
28
	public boolean canAdd(IAddContext context) 
29
	{
30
		// return true if given business object is an DiagramConnectionPart
31
		// note, that the context must be an instance of IAddConnectionContext
32
		if (context instanceof IAddConnectionContext && 
33
				context.getNewObject() instanceof DiagramConnectionPart) 
34
		{
35
			return true;
36
		}
37
		return false;
38
	}
39
40
	public PictogramElement add(IAddContext context) 
41
	{
42
		IAddConnectionContext addConContext = (IAddConnectionContext) context;
43
		DiagramConnectionPart connectionPart = (DiagramConnectionPart) context.getNewObject();
44
45
		IPeCreateService peCreateService = Graphiti.getPeCreateService();
46
		// CONNECTION WITH POLYLINE
47
		Connection connection = peCreateService.createFreeFormConnection(getDiagram());
48
		connection.setStart(addConContext.getSourceAnchor());
49
		connection.setEnd(addConContext.getTargetAnchor());
50
51
		IGaService gaService = Graphiti.getGaService();
52
		Polyline polyline = gaService.createPolyline(connection);
53
		polyline.setForeground(manageColor(IColorConstant.BLACK));
54
		polyline.setLineWidth(1);
55
       
56
		// create link and wire it
57
		link(connection, connectionPart);
58
59
		// add dynamic text decorator for the reference name
60
		ConnectionDecorator textDecorator = peCreateService.createConnectionDecorator(connection, true, 0.5, true);
61
		Text text = gaService.createDefaultText(textDecorator);
62
		text.setForeground(manageColor(IColorConstant.BLACK));
63
		gaService.setLocation(text, 10, 0);		
64
		
65
		text.setValue(connectionPart.getLabel());
66
67
		// add static graphical decorators (composition and navigable)
68
		ConnectionDecorator cd;
69
		cd = peCreateService.createConnectionDecorator(connection, false, 1.0, true);
70
		createArrow(cd);
71
72
        // provide information to support direct-editing directly 
73
74
        // after object creation (must be activated additionally)
75
        IDirectEditingInfo directEditingInfo = getFeatureProvider().getDirectEditingInfo();
76
77
        // set container shape for direct editing after object creation
78
        directEditingInfo.setMainPictogramElement(connection);
79
80
        // set shape and graphics algorithm where the editor for
81
        // direct editing shall be opened after object creation
82
        directEditingInfo.setPictogramElement(textDecorator);
83
        directEditingInfo.setGraphicsAlgorithm(text);
84
		
85
		return connection;
86
	}
87
88
	private Polygon createArrow(GraphicsAlgorithmContainer gaContainer) 
89
	{
90
		Polygon polygon = Graphiti.getGaCreateService().createPolygon(gaContainer, new int[] { -8, 4, 0, 0, -8, -4, -5, 0 });
91
		polygon.setBackground(manageColor(IColorConstant.BLACK));
92
		//polygon.setStyle(StyleUtil.getStyleForADFView(getDiagram()));
93
		polygon.setFilled(true);
94
		return polygon;
95
	}
96
	
97
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireAddNodeFeature.java (+174 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.IAddContext;
5
import org.eclipse.graphiti.features.impl.AbstractAddShapeFeature;
6
import org.eclipse.graphiti.mm.algorithms.Image;
7
import org.eclipse.graphiti.mm.algorithms.Polyline;
8
import org.eclipse.graphiti.mm.algorithms.Rectangle;
9
import org.eclipse.graphiti.mm.algorithms.Text;
10
import org.eclipse.graphiti.mm.algorithms.styles.Orientation;
11
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
12
import org.eclipse.graphiti.mm.pictograms.Diagram;
13
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
14
import org.eclipse.graphiti.mm.pictograms.Shape;
15
import org.eclipse.graphiti.services.Graphiti;
16
import org.eclipse.graphiti.services.IGaService;
17
import org.eclipse.graphiti.services.IPeCreateService;
18
import org.eclipse.graphiti.util.ColorConstant;
19
import org.eclipse.graphiti.util.IColorConstant;
20
import org.eclipse.sapphire.ui.def.ISapphirePartDef;
21
import org.eclipse.sapphire.ui.diagram.def.IDiagramLabelDef;
22
import org.eclipse.sapphire.ui.diagram.def.IDiagramNodeDef;
23
import org.eclipse.sapphire.ui.diagram.def.IDiagramNodeImageDef;
24
import org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper;
25
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
26
import org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramFeatureProvider;
27
import org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramPropertyKeys;
28
29
public class SapphireAddNodeFeature extends AbstractAddShapeFeature 
30
{
31
    private static final IColorConstant CLASS_TEXT_FOREGROUND = new ColorConstant(51, 51, 153);
32
    private static final IColorConstant CLASS_FOREGROUND = new ColorConstant(255, 102, 0);
33
    private static final IColorConstant CLASS_BACKGROUND =  new ColorConstant(255, 204, 153);
34
    private static int defaultX = 50;
35
    private static int defaultY = 50;
36
    private static int xInc = 100;
37
    private static int yInc = 0;
38
	
39
	public SapphireAddNodeFeature(IFeatureProvider fp)
40
	{
41
		super(fp);
42
	}
43
	
44
	public boolean canAdd(IAddContext context) 
45
	{
46
		Object newObj = context.getNewObject();
47
		if (newObj instanceof DiagramNodePart)
48
		{
49
			return true;
50
		}
51
		return false;
52
	}
53
54
	public PictogramElement add(IAddContext context)
55
	{
56
		DiagramNodePart nodePart = (DiagramNodePart)context.getNewObject();
57
		final Diagram targetDiagram = (Diagram) context.getTargetContainer();
58
		
59
        // define a default size for the shape
60
        IDiagramNodeDef nodeDef = (IDiagramNodeDef)nodePart.getDefinition();
61
        int width = nodeDef.getHint(ISapphirePartDef.HINT_WIDTH, -1);
62
        int height = nodeDef.getHint(ISapphirePartDef.HINT_HEIGHT, -1);
63
        int x, y;
64
        if (context.getX() != -1)
65
        {
66
        	x = context.getX();
67
        }
68
        else
69
        {
70
        	x = defaultX;
71
        	defaultX += xInc;
72
        }
73
        if (context.getY() != -1)
74
        {
75
        	y = context.getY();
76
        }
77
        else
78
        {
79
        	y = defaultY;
80
        	defaultY += yInc;
81
        }
82
83
        // CONTAINER SHAPE WITH RECTANGLE
84
        IPeCreateService peCreateService = Graphiti.getPeCreateService();
85
        ContainerShape containerShape =  peCreateService.createContainerShape(targetDiagram, true);
86
        IGaService gaService = Graphiti.getGaService();
87
        
88
        // TODO clean this up
89
        // The temporary logic is to create a default rectangle if no icon is associated with the node
90
        if (nodePart.getImageId() == null)
91
        {
92
            // create and set graphics algorithm
93
            Rectangle rectangle = gaService.createRectangle(containerShape);
94
            rectangle.setForeground(manageColor(CLASS_FOREGROUND));
95
            rectangle.setBackground(manageColor(CLASS_BACKGROUND));
96
            rectangle.setLineWidth(2);
97
            gaService.setLocationAndSize(rectangle, x, y, width, height);
98
 
99
            // create link and wire it
100
            link(containerShape, nodePart);
101
        		
102
	        // SHAPE WITH LINE
103
	        {
104
	            // create shape for line
105
	            Shape shape = peCreateService.createShape(containerShape, false);
106
	 
107
	            // create and set graphics algorithm
108
	            Polyline polyline =
109
	                gaService.createPolyline(shape, new int[] { 0, 20, width, 20 });
110
	            polyline.setForeground(manageColor(CLASS_FOREGROUND));
111
	            polyline.setLineWidth(2);
112
	        }
113
        }
114
        else
115
        {
116
        	IDiagramNodeImageDef imageDef = nodeDef.getImage().element();
117
        	Rectangle rectangle = gaService.createRectangle(containerShape);
118
        	rectangle.setFilled(false);
119
        	rectangle.setLineVisible(false);
120
        	gaService.setLocationAndSize(rectangle, x, y, width, height);
121
        	
122
        	link(containerShape, nodePart);
123
        	
124
            // Shape with Image
125
            {
126
            	Shape shape = peCreateService.createShape(containerShape, false);
127
            	String imageId = nodePart.getImageId();
128
            	Image image = gaService.createImage(shape, imageId);
129
            	int imageX = imageDef.getHint("x", 0);
130
            	int imageY = imageDef.getHint("y", 0);
131
                int imageWidth = imageDef.getHint(ISapphirePartDef.HINT_WIDTH, width);
132
                int imageHeight = imageDef.getHint(ISapphirePartDef.HINT_HEIGHT, -1);
133
        		Graphiti.getPeService().setPropertyValue(containerShape, 
134
        				SapphireDiagramPropertyKeys.NODE_IMAGE_ID, imageId);
135
136
    	        gaService.setLocationAndSize(image, imageX, imageY, imageWidth, imageHeight);
137
            }        	
138
        }
139
140
        if (nodeDef.getLabel().element() != null)
141
        {
142
            // create shape for text
143
            Shape shape = peCreateService.createShape(containerShape, false);
144
 
145
            // create and set text graphics algorithm
146
            Text text = gaService.createDefaultText(shape, nodePart.getLabel());
147
            text.setForeground(manageColor(CLASS_TEXT_FOREGROUND));
148
            text.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER);
149
            text.setVerticalAlignment(Orientation.ALIGNMENT_CENTER);
150
151
            IDiagramLabelDef labelDef = nodeDef.getLabel().element();
152
            int labelX = labelDef.getHint("x", 0);
153
        	int labelY = labelDef.getHint("y", 0);            
154
            int labelWidth = labelDef.getHint(ISapphirePartDef.HINT_WIDTH, width);
155
            int labelHeight = labelDef.getHint(ISapphirePartDef.HINT_HEIGHT, 15);
156
            
157
            gaService.setLocationAndSize(text, labelX, labelY, labelWidth, labelHeight);
158
 
159
            // create link and wire it
160
            link(shape, nodePart);            
161
        }
162
        
163
        // add a chopbox anchor to the shape
164
        peCreateService.createChopboxAnchor(containerShape);
165
        
166
        // Save the node bounds
167
        DiagramGeometryWrapper diagramGeometry = 
168
        	((SapphireDiagramFeatureProvider)getFeatureProvider()).getDiagramGeometry();
169
        diagramGeometry.addNode(nodePart, x, y, width, height);
170
        
171
		return containerShape;
172
	}
173
174
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireCreateConnectionFeature.java (+112 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.ICreateConnectionContext;
5
import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
6
import org.eclipse.graphiti.features.impl.AbstractCreateConnectionFeature;
7
import org.eclipse.graphiti.mm.pictograms.Anchor;
8
import org.eclipse.graphiti.mm.pictograms.Connection;
9
import org.eclipse.sapphire.ui.SapphirePart;
10
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
11
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionTemplate;
12
import org.eclipse.sapphire.ui.diagram.editor.DiagramEmbeddedConnectionPart;
13
import org.eclipse.sapphire.ui.diagram.editor.DiagramEmbeddedConnectionTemplate;
14
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
15
16
public class SapphireCreateConnectionFeature extends AbstractCreateConnectionFeature 
17
{
18
	private DiagramConnectionTemplate connectionTemplate;
19
	
20
	public SapphireCreateConnectionFeature(IFeatureProvider fp, DiagramConnectionTemplate connectionTemplate)
21
	{
22
		super(fp, connectionTemplate.getToolPaletteLabel(), connectionTemplate.getToolPaletteDesc());
23
		this.connectionTemplate = connectionTemplate;		
24
	}
25
	
26
	public boolean canCreate(ICreateConnectionContext context) 
27
	{
28
		// return true if both anchors belong to an IModelElement
29
		// and those model elements are not identical
30
		SapphirePart source = getEndpoint(context.getSourceAnchor());
31
		SapphirePart target = getEndpoint(context.getTargetAnchor());
32
		if (source instanceof DiagramNodePart && 
33
				target instanceof DiagramNodePart && source != target) 
34
		{
35
			return this.connectionTemplate.canCreateNewConnection((DiagramNodePart)source, 
36
					(DiagramNodePart)target);
37
		}
38
		return false;
39
	}
40
41
	public Connection create(ICreateConnectionContext context) 
42
	{
43
		Connection newConnection = null;
44
45
		// get model elements which should be connected
46
		SapphirePart source = getEndpoint(context.getSourceAnchor());
47
		SapphirePart target = getEndpoint(context.getTargetAnchor());
48
49
		if (source instanceof DiagramNodePart && target instanceof DiagramNodePart) 
50
		{
51
			DiagramNodePart sourceNode = (DiagramNodePart)source;
52
			DiagramNodePart targetNode = (DiagramNodePart)target;
53
			// create new business object
54
			if (this.connectionTemplate instanceof DiagramEmbeddedConnectionTemplate)
55
			{
56
				((DiagramEmbeddedConnectionTemplate)this.connectionTemplate).removeModelListener(sourceNode.getLocalModelElement());
57
			}
58
			else
59
			{
60
				this.connectionTemplate.removeModelListener();
61
			}
62
			DiagramConnectionPart connectionPart = 
63
				this.connectionTemplate.createNewDiagramConnection(sourceNode, targetNode);
64
65
			if (this.connectionTemplate instanceof DiagramEmbeddedConnectionTemplate)
66
			{
67
				((DiagramEmbeddedConnectionTemplate)this.connectionTemplate).addModelListener(sourceNode.getLocalModelElement());
68
			}
69
			else
70
			{
71
				this.connectionTemplate.addModelListener();
72
			}
73
			
74
			// add connection for business object
75
			AddConnectionContext addContext = new AddConnectionContext(context.getSourceAnchor(), context.getTargetAnchor());
76
			addContext.setNewObject(connectionPart);
77
			newConnection = (Connection) getFeatureProvider().addIfPossible(addContext);
78
			
79
	        // activate direct editing after object creation
80
	        getFeatureProvider().getDirectEditingInfo().setActive(true);
81
		}
82
83
		return newConnection;
84
	}
85
86
	public boolean canStartConnection(ICreateConnectionContext context) 
87
	{
88
		// return true if start anchor belongs to an IModelElement
89
		if (getEndpoint(context.getSourceAnchor()) instanceof DiagramNodePart) 
90
		{
91
			return true;
92
		}
93
		return false;
94
	}
95
96
	/**
97
	 * Returns the SapphirePart belonging to the anchor, or null if not available.
98
	 */
99
	private SapphirePart getEndpoint(Anchor anchor) 
100
	{
101
		if (anchor != null) 
102
		{
103
			Object obj = getBusinessObjectForPictogramElement(anchor.getParent());
104
			if (obj instanceof SapphirePart) 
105
			{
106
				return (SapphirePart) obj;
107
			}
108
		}
109
		return null;
110
	}
111
	
112
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireCreateNodeFeature.java (+37 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.ICreateContext;
5
import org.eclipse.graphiti.features.impl.AbstractCreateFeature;
6
import org.eclipse.graphiti.mm.pictograms.Diagram;
7
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
8
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodeTemplate;
9
10
public class SapphireCreateNodeFeature extends AbstractCreateFeature 
11
{
12
	private DiagramNodeTemplate nodeTemplate;
13
	
14
	public SapphireCreateNodeFeature(IFeatureProvider fp, DiagramNodeTemplate nodeTemplate)
15
	{
16
		super(fp, nodeTemplate.getToolPaletteLabel(), nodeTemplate.getToolPaletteDesc());
17
		this.nodeTemplate = nodeTemplate;		
18
	}
19
20
	public boolean canCreate(ICreateContext context) 
21
	{		
22
		return context.getTargetContainer() instanceof Diagram;
23
	}
24
25
	public Object[] create(ICreateContext context) 
26
	{
27
		// In general the model property listener in the node template should handle 
28
		// the addition of new element. But the passed in context contains x, y, width and
29
		// height of the new node, we are bypassing the listener mechanism here.
30
		this.nodeTemplate.removeModelLister();
31
		DiagramNodePart nodePart = this.nodeTemplate.createNewDiagramNode();
32
		this.nodeTemplate.addModelListener();
33
		
34
		addGraphicalRepresentation(context, nodePart);
35
		return new Object[] { nodePart };
36
	}
37
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireDeleteConnectionFeature.java (+62 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.IDeleteContext;
5
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
6
import org.eclipse.graphiti.ui.features.DefaultDeleteFeature;
7
import org.eclipse.sapphire.modeling.IModelElement;
8
import org.eclipse.sapphire.modeling.ModelElementList;
9
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
10
11
public class SapphireDeleteConnectionFeature extends DefaultDeleteFeature 
12
{
13
	private boolean shouldDelete;
14
	
15
	public SapphireDeleteConnectionFeature(IFeatureProvider fp)
16
	{
17
		super(fp);
18
	}
19
	
20
	@Override
21
	protected boolean getUserDecision() 
22
	{
23
		this.shouldDelete = super.getUserDecision();
24
		return this.shouldDelete;
25
	}
26
	
27
	@Override
28
	public void delete(IDeleteContext context) 
29
	{
30
		PictogramElement pe = context.getPictogramElement();
31
		Object[] businessObjectsForPictogramElement = getAllBusinessObjectsForPictogramElement(pe);
32
		if (businessObjectsForPictogramElement != null && businessObjectsForPictogramElement.length > 0) 
33
		{
34
			if (!getUserDecision()) 
35
			{
36
				return;
37
			}			
38
		}
39
		
40
		preDelete(context);
41
		deleteBusinessObjects(businessObjectsForPictogramElement);
42
		postDelete(context);
43
	}
44
	
45
	@Override
46
	protected void deleteBusinessObject(Object bo) 
47
	{
48
		if (bo instanceof DiagramConnectionPart) 
49
		{
50
			final DiagramConnectionPart connPart = (DiagramConnectionPart)bo;
51
			final IModelElement element = connPart.getLocalModelElement();
52
			final ModelElementList<?> list = (ModelElementList<?>) element.parent();
53
			list.remove(element);						
54
		}
55
	}
56
	
57
	@Override
58
	public boolean hasDoneChanges() 
59
	{
60
		return this.shouldDelete;
61
	}
62
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireDeleteNodeFeature.java (+94 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import java.util.Iterator;
4
5
import org.eclipse.graphiti.features.IFeatureProvider;
6
import org.eclipse.graphiti.features.context.IDeleteContext;
7
import org.eclipse.graphiti.features.context.impl.DeleteContext;
8
import org.eclipse.graphiti.mm.pictograms.Anchor;
9
import org.eclipse.graphiti.mm.pictograms.Connection;
10
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
11
import org.eclipse.graphiti.mm.pictograms.Shape;
12
import org.eclipse.graphiti.services.Graphiti;
13
import org.eclipse.graphiti.ui.features.DefaultDeleteFeature;
14
import org.eclipse.sapphire.modeling.IModelElement;
15
import org.eclipse.sapphire.modeling.ModelElementList;
16
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
17
18
public class SapphireDeleteNodeFeature extends DefaultDeleteFeature 
19
{
20
	private boolean shouldDelete;
21
	
22
	public SapphireDeleteNodeFeature(IFeatureProvider fp)
23
	{
24
		super(fp);
25
	}
26
	
27
	@Override
28
	protected boolean getUserDecision() 
29
	{
30
		this.shouldDelete = super.getUserDecision();
31
		return this.shouldDelete;
32
	}
33
	
34
	@Override
35
	public void preDelete(IDeleteContext context) 
36
	{
37
		PictogramElement pe = context.getPictogramElement();
38
		if (pe instanceof Shape)
39
		{
40
			Shape shape = (Shape)pe;
41
		
42
			for (Iterator<Anchor> iter = shape.getAnchors().iterator(); iter.hasNext();) 
43
			{
44
				Anchor anchor = iter.next();
45
				
46
				Iterator<Connection> connIt = Graphiti.getPeService().getAllConnections(anchor).iterator();
47
				while (connIt.hasNext())
48
				{
49
					Connection connection = connIt.next();				
50
					IDeleteContext dc = new DeleteContext(connection);
51
					SapphireInternalDeleteConnectionFeature df = new SapphireInternalDeleteConnectionFeature(getFeatureProvider());
52
					df.delete(dc);
53
				}
54
			}
55
		}		
56
	}
57
	
58
	@Override
59
	public void delete(IDeleteContext context) 
60
	{
61
		PictogramElement pe = context.getPictogramElement();
62
		Object[] businessObjectsForPictogramElement = getAllBusinessObjectsForPictogramElement(pe);
63
		if (businessObjectsForPictogramElement != null && businessObjectsForPictogramElement.length > 0) 
64
		{
65
			if (!getUserDecision()) 
66
			{
67
				return;
68
			}			
69
		}
70
		
71
		preDelete(context);
72
		deleteBusinessObjects(businessObjectsForPictogramElement);
73
		postDelete(context);
74
	}
75
	
76
	@Override
77
	protected void deleteBusinessObject(Object bo) 
78
	{
79
		if (bo instanceof DiagramNodePart)
80
		{
81
			DiagramNodePart nodePart = (DiagramNodePart)bo;
82
			IModelElement element = nodePart.getLocalModelElement();
83
			ModelElementList<?> list = (ModelElementList<?>) element.parent();
84
			list.remove(element);			
85
		}
86
	}
87
	
88
	@Override
89
	public boolean hasDoneChanges() 
90
	{
91
		return this.shouldDelete;
92
	}
93
	
94
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireDirectEditConnectionFeature.java (+61 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.IDirectEditingContext;
5
import org.eclipse.graphiti.features.impl.AbstractDirectEditingFeature;
6
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
7
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
8
9
public class SapphireDirectEditConnectionFeature extends AbstractDirectEditingFeature 
10
{
11
	public SapphireDirectEditConnectionFeature(IFeatureProvider fp)
12
	{
13
		super(fp);
14
	}
15
	
16
	public int getEditingType() 
17
	{
18
		return TYPE_TEXT;
19
	}
20
21
	@Override
22
	public boolean canDirectEdit(IDirectEditingContext context) 
23
	{
24
		PictogramElement pe = (PictogramElement)context.getPictogramElement().eContainer();
25
		Object bo = getBusinessObjectForPictogramElement(pe);
26
		// support direct editing, if it is a DiagramConnectionPart, and the 
27
		// DiagramConnectionPart contains editable label
28
		if (bo instanceof DiagramConnectionPart && 
29
				((DiagramConnectionPart)bo).canEditLabel()) 
30
		{
31
			return true;
32
		}
33
		// direct editing not supported in all other cases
34
		return false;
35
	}
36
	
37
	public String getInitialValue(IDirectEditingContext context) 
38
	{
39
		PictogramElement pe = (PictogramElement)context.getPictogramElement().eContainer();
40
		Object bo = getBusinessObjectForPictogramElement(pe);
41
		if (bo instanceof DiagramConnectionPart)
42
		{
43
			DiagramConnectionPart connPart = (DiagramConnectionPart)bo;
44
			return connPart.getLabel();
45
		}
46
		return null;
47
	}
48
49
	public void setValue(String value, IDirectEditingContext context) 
50
	{
51
		PictogramElement pe = (PictogramElement)context.getPictogramElement().eContainer();
52
		Object bo = getBusinessObjectForPictogramElement(pe);
53
		if (bo instanceof DiagramConnectionPart)
54
		{
55
			DiagramConnectionPart connPart = (DiagramConnectionPart)bo;
56
			connPart.setLabel(value);
57
			updatePictogramElement(pe);
58
		}
59
	}
60
61
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireDirectEditNodeFeature.java (+107 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import java.util.Iterator;
4
5
import org.eclipse.graphiti.features.IFeatureProvider;
6
import org.eclipse.graphiti.features.context.IDirectEditingContext;
7
import org.eclipse.graphiti.features.impl.AbstractDirectEditingFeature;
8
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
9
import org.eclipse.graphiti.mm.algorithms.Text;
10
import org.eclipse.graphiti.mm.pictograms.Anchor;
11
import org.eclipse.graphiti.mm.pictograms.Connection;
12
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
13
import org.eclipse.graphiti.mm.pictograms.Shape;
14
import org.eclipse.graphiti.services.Graphiti;
15
import org.eclipse.sapphire.modeling.IModelElement;
16
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
17
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
18
19
public class SapphireDirectEditNodeFeature extends AbstractDirectEditingFeature 
20
{
21
	public SapphireDirectEditNodeFeature(IFeatureProvider fp)
22
	{
23
		super(fp);
24
	}
25
	
26
	public int getEditingType() 
27
	{
28
		return TYPE_TEXT;
29
	}
30
31
	@Override
32
	public boolean canDirectEdit(IDirectEditingContext context) 
33
	{
34
		PictogramElement pe = context.getPictogramElement();
35
		Object bo = getBusinessObjectForPictogramElement(pe);
36
		GraphicsAlgorithm ga = context.getGraphicsAlgorithm();
37
		// support direct editing, if it is a DiagramNodePart, and the user clicked
38
		// directly on the text and not somewhere else in the rectangle
39
		if (bo instanceof DiagramNodePart && ga instanceof Text) 
40
		{
41
			return ((DiagramNodePart)bo).canEditLabel();
42
		}
43
		// direct editing not supported in all other cases
44
		return false;
45
	}
46
47
	public String getInitialValue(IDirectEditingContext context) 
48
	{
49
		// return the current label of the node
50
		PictogramElement pe = context.getPictogramElement();
51
		DiagramNodePart nodePart = (DiagramNodePart)getBusinessObjectForPictogramElement(pe);
52
		return nodePart.getLabel();
53
	}
54
55
	public void setValue(String value, IDirectEditingContext context) 
56
	{
57
		PictogramElement pe = context.getPictogramElement();
58
				
59
		if (pe.eContainer() instanceof Shape)
60
		{
61
			DiagramNodePart nodePart = (DiagramNodePart)getBusinessObjectForPictogramElement(pe);
62
			nodePart.setLabel(value);
63
			IModelElement nodeElement = nodePart.getLocalModelElement();
64
			Shape nodeShape = (Shape)pe.eContainer();
65
			
66
			// go through all the connections associated with this bo and update them
67
			for (Iterator<Anchor> iter = nodeShape.getAnchors().iterator(); iter.hasNext();) 
68
			{
69
				Anchor anchor = iter.next();
70
				for (Iterator<Connection> iterator = Graphiti.getPeService().getAllConnections(anchor).iterator(); iterator.hasNext();) 
71
				{
72
					Connection connection = iterator.next();
73
					Object bo = getBusinessObjectForPictogramElement(connection);
74
					if (bo instanceof DiagramConnectionPart)
75
					{
76
						DiagramConnectionPart connectionPart = (DiagramConnectionPart)bo;
77
						IModelElement endpoint1 = connectionPart.getEndpoint1();
78
						IModelElement endpoint2 = connectionPart.getEndpoint2();
79
						if (endpoint1.equals(nodeElement) || endpoint2.equals(nodeElement))
80
						{
81
							connectionPart.removeModelListener();
82
							if (endpoint1.equals(nodeElement))
83
							{
84
								connectionPart.refreshEndpoint1();
85
							}
86
							else if (endpoint2.equals(nodeElement))
87
							{
88
								connectionPart.refreshEndpoint2();
89
							}
90
							connectionPart.addModelListener();
91
						}
92
					}
93
				}
94
			}			
95
		}
96
				
97
		// Explicitly update the shape to display the new value in the diagram
98
		// Note, that this might not be necessary in future versions of Graphiti
99
		// (currently in discussion)
100
101
		// we know, that pe is the Shape of the Text, so its container is the
102
		// main shape of the node
103
		updatePictogramElement(((Shape)pe).getContainer());
104
105
	}
106
107
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireInternalDeleteConnectionFeature.java (+24 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
5
public class SapphireInternalDeleteConnectionFeature extends
6
		SapphireDeleteConnectionFeature 
7
{
8
	public SapphireInternalDeleteConnectionFeature(IFeatureProvider fp)
9
	{
10
		super(fp);
11
	}
12
	
13
	@Override
14
	protected boolean getUserDecision() 
15
	{
16
		return true;
17
	}
18
	
19
	@Override
20
	public boolean hasDoneChanges() 
21
	{
22
		return true;
23
	}	
24
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireMoveBendpointFeature.java (+36 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.IMoveBendpointContext;
5
import org.eclipse.graphiti.features.impl.DefaultMoveBendpointFeature;
6
import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
7
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
8
import org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper;
9
import org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramFeatureProvider;
10
11
public class SapphireMoveBendpointFeature extends DefaultMoveBendpointFeature 
12
{
13
	public SapphireMoveBendpointFeature(IFeatureProvider fp)
14
	{
15
		super(fp);
16
	}
17
	
18
	@Override
19
	public boolean moveBendpoint(IMoveBendpointContext context) 
20
	{
21
		boolean ret = false;
22
		super.moveBendpoint(context);
23
		
24
		FreeFormConnection freeFormConnection = context.getConnection();
25
		Object bo = getBusinessObjectForPictogramElement(freeFormConnection);
26
		if (bo instanceof DiagramConnectionPart)
27
		{
28
			DiagramGeometryWrapper dg = 
29
				((SapphireDiagramFeatureProvider)getFeatureProvider()).getDiagramGeometry();
30
			ret = dg.updateConnectionBendpoint((DiagramConnectionPart)bo, 
31
					context.getBendpointIndex(), context.getX(), context.getY());
32
		}		
33
		return ret;
34
	}
35
	
36
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireMoveNodeFeature.java (+31 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.IMoveShapeContext;
5
import org.eclipse.graphiti.features.impl.DefaultMoveShapeFeature;
6
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
7
import org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper;
8
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
9
import org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramFeatureProvider;
10
11
public class SapphireMoveNodeFeature extends DefaultMoveShapeFeature 
12
{
13
	public SapphireMoveNodeFeature(IFeatureProvider fp)
14
	{
15
		super(fp);
16
	}
17
	
18
	@Override
19
	protected void internalMove(IMoveShapeContext context) 
20
	{
21
		super.internalMove(context);
22
 		PictogramElement pe = context.getPictogramElement();
23
 		Object bo = getBusinessObjectForPictogramElement(pe);
24
 		if (bo instanceof DiagramNodePart)
25
 		{
26
			DiagramGeometryWrapper dg = 
27
				((SapphireDiagramFeatureProvider)getFeatureProvider()).getDiagramGeometry();
28
			dg.updateNode((DiagramNodePart)bo, context.getX(), context.getY());
29
 		}
30
	}
31
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireRemoveBendpointFeature.java (+34 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.IRemoveBendpointContext;
5
import org.eclipse.graphiti.features.impl.DefaultRemoveBendpointFeature;
6
import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
7
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
8
import org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper;
9
import org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramFeatureProvider;
10
11
public class SapphireRemoveBendpointFeature extends DefaultRemoveBendpointFeature 
12
{
13
	public SapphireRemoveBendpointFeature(IFeatureProvider fp)
14
	{
15
		super(fp);
16
	}
17
	
18
	@Override
19
	public void removeBendpoint(IRemoveBendpointContext context) 
20
	{
21
		super.removeBendpoint(context);
22
		
23
		FreeFormConnection freeFormConnection = context.getConnection();
24
		Object bo = getBusinessObjectForPictogramElement(freeFormConnection);
25
		if (bo instanceof DiagramConnectionPart)
26
		{
27
			DiagramGeometryWrapper dg = 
28
				((SapphireDiagramFeatureProvider)getFeatureProvider()).getDiagramGeometry();
29
			dg.removeConnectionBendpoint((DiagramConnectionPart)bo, context.getBendpointIndex());
30
		}
31
		
32
	}
33
34
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireRemoveFeature.java (+26 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.context.IRemoveContext;
5
import org.eclipse.graphiti.features.impl.DefaultRemoveFeature;
6
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
7
import org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramFeatureProvider;
8
9
public class SapphireRemoveFeature extends DefaultRemoveFeature 
10
{
11
	public SapphireRemoveFeature(IFeatureProvider fp)
12
	{
13
		super(fp);
14
	}
15
16
	@Override
17
	public void preRemove(IRemoveContext context) 
18
	{
19
		PictogramElement pe = context.getPictogramElement();
20
		SapphireDiagramFeatureProvider sfp = (SapphireDiagramFeatureProvider)getFeatureProvider();
21
		final Object bo = sfp.getBusinessObjectForPictogramElement(pe);
22
		
23
		sfp.remove(bo);
24
	 }
25
26
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireResizeShapeFeature.java (+41 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.DefaultResizeConfiguration;
4
import org.eclipse.graphiti.features.IFeatureProvider;
5
import org.eclipse.graphiti.features.IResizeConfiguration;
6
import org.eclipse.graphiti.features.context.IResizeShapeContext;
7
import org.eclipse.graphiti.features.impl.DefaultResizeShapeFeature;
8
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
9
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
10
11
public class SapphireResizeShapeFeature extends DefaultResizeShapeFeature 
12
{
13
	public SapphireResizeShapeFeature(IFeatureProvider fp)
14
	{
15
		super(fp);
16
	}
17
	
18
	@Override
19
	public boolean canResizeShape(IResizeShapeContext context) 
20
	{
21
		PictogramElement pe = context.getPictogramElement();
22
 		Object bo = getBusinessObjectForPictogramElement(pe);
23
 		if (bo instanceof DiagramNodePart)
24
 		{
25
 			DiagramNodePart nodePart = (DiagramNodePart)bo;
26
 			return nodePart.canResizeShape();
27
 		}
28
 		return super.canResizeShape(context);
29
	}
30
	
31
	@Override
32
	public IResizeConfiguration getResizeConfiguration(IResizeShapeContext context) 
33
	{
34
		if (!canResizeShape(context))
35
		{
36
			return new NoResizeConfiguration();
37
		}
38
		return new DefaultResizeConfiguration();
39
	}
40
	
41
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireUpdateConnectionFeature.java (+94 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.IReason;
5
import org.eclipse.graphiti.features.context.IUpdateContext;
6
import org.eclipse.graphiti.features.impl.AbstractUpdateFeature;
7
import org.eclipse.graphiti.features.impl.Reason;
8
import org.eclipse.graphiti.mm.algorithms.Text;
9
import org.eclipse.graphiti.mm.pictograms.Connection;
10
import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator;
11
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
12
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
13
14
public class SapphireUpdateConnectionFeature extends AbstractUpdateFeature 
15
{
16
	public SapphireUpdateConnectionFeature(IFeatureProvider fp)
17
	{
18
		super(fp);
19
	}
20
	
21
	public boolean canUpdate(IUpdateContext context) 
22
	{
23
		PictogramElement pe = context.getPictogramElement();
24
		Object bo = getBusinessObjectForPictogramElement(pe);
25
		return bo instanceof DiagramConnectionPart;
26
	}
27
28
	public IReason updateNeeded(IUpdateContext context) 
29
	{
30
		// retrieve name from pictogram model
31
		String pictogramName = null;
32
		PictogramElement pictogramElement = context.getPictogramElement();
33
		if (pictogramElement instanceof Connection) {
34
			Connection c = (Connection) pictogramElement;
35
			for (ConnectionDecorator cd : c.getConnectionDecorators()) {
36
				if (cd.getGraphicsAlgorithm() instanceof Text) {
37
					Text text = (Text) cd.getGraphicsAlgorithm();
38
					pictogramName = text.getValue();
39
				}
40
			}
41
		}
42
43
		// retrieve name from business model
44
		String businessName = null;
45
		Object bo = getBusinessObjectForPictogramElement(pictogramElement);
46
		if (bo instanceof DiagramConnectionPart) 
47
		{
48
			DiagramConnectionPart connPart = (DiagramConnectionPart)bo;
49
			businessName = connPart.getLabel();
50
		}
51
52
		// update needed, if names are different
53
		boolean updateNameNeeded = ((pictogramName == null && businessName != null) || (pictogramName != null && !pictogramName
54
				.equals(businessName)));
55
		if (updateNameNeeded) 
56
		{
57
			return Reason.createTrueReason("Name is out of date"); //$NON-NLS-1$
58
		} 
59
		else
60
		{
61
			return Reason.createFalseReason();
62
		}
63
	}
64
65
	public boolean update(IUpdateContext context) 
66
	{
67
		String businessName = null;
68
		PictogramElement pe = context.getPictogramElement();
69
		Object bo = getBusinessObjectForPictogramElement(pe);
70
		if (bo instanceof DiagramConnectionPart) 
71
		{
72
			DiagramConnectionPart connPart = (DiagramConnectionPart)bo;
73
			businessName = connPart.getLabel();
74
		}
75
		
76
		// Set name in pictogram model
77
		if (pe instanceof Connection) 
78
		{
79
			Connection c = (Connection) pe;
80
			for (ConnectionDecorator cd : c.getConnectionDecorators()) 
81
			{
82
				if (cd.getGraphicsAlgorithm() instanceof Text)
83
				{
84
					Text text = (Text) cd.getGraphicsAlgorithm();
85
					text.setValue(businessName);
86
					return true;
87
				}
88
			}
89
		}
90
		
91
		return false;
92
	}
93
94
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/features/SapphireUpdateNodeFeature.java (+129 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.features;
2
3
import org.eclipse.graphiti.features.IFeatureProvider;
4
import org.eclipse.graphiti.features.IReason;
5
import org.eclipse.graphiti.features.context.IUpdateContext;
6
import org.eclipse.graphiti.features.impl.AbstractUpdateFeature;
7
import org.eclipse.graphiti.features.impl.Reason;
8
import org.eclipse.graphiti.mm.algorithms.Image;
9
import org.eclipse.graphiti.mm.algorithms.Text;
10
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
11
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
12
import org.eclipse.graphiti.mm.pictograms.Shape;
13
import org.eclipse.graphiti.services.Graphiti;
14
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
15
import org.eclipse.sapphire.ui.diagram.graphiti.providers.SapphireDiagramPropertyKeys;
16
17
public class SapphireUpdateNodeFeature extends AbstractUpdateFeature 
18
{
19
	private static final String LABEL_REASON = "Label is out of date";	//$NON-NLS-1$
20
	private static final String IMAGE_REASON = "Icon is out of date";	//$NON-NLS-1$
21
	
22
	public SapphireUpdateNodeFeature(IFeatureProvider fp)
23
	{
24
		super(fp);
25
	}
26
	
27
	public boolean canUpdate(IUpdateContext context) 
28
	{
29
		Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
30
		return bo instanceof DiagramNodePart;
31
	}
32
33
	public IReason updateNeeded(IUpdateContext context) 
34
	{
35
		// retrieve name from pictogram model
36
		String pictogramName = null;
37
		PictogramElement pictogramElement = context.getPictogramElement();
38
		ContainerShape cs = null;
39
		if (pictogramElement instanceof ContainerShape) 
40
		{
41
			cs = (ContainerShape) pictogramElement;
42
			for (Shape shape : cs.getChildren()) 
43
			{
44
				if (shape.getGraphicsAlgorithm() instanceof Text) 
45
				{
46
					Text text = (Text) shape.getGraphicsAlgorithm();
47
					pictogramName = text.getValue();
48
					break;
49
				}
50
			}
51
		}
52
		// retrieve name from business model
53
		String businessName = null;
54
		Object bo = getBusinessObjectForPictogramElement(pictogramElement);
55
		DiagramNodePart nodePart = (DiagramNodePart) bo;
56
		businessName = nodePart.getLabel();
57
58
		// update needed, if names are different
59
		boolean updateNameNeeded = 
60
			((pictogramName == null && businessName != null) || 
61
					(pictogramName != null && !pictogramName.equals(businessName)));
62
		if (updateNameNeeded) 
63
		{
64
			return Reason.createTrueReason(LABEL_REASON);
65
		} 
66
		else 
67
		{
68
			String newImageId = nodePart.getImageId();
69
			String oldImageId = Graphiti.getPeService().getPropertyValue(cs, SapphireDiagramPropertyKeys.NODE_IMAGE_ID);
70
			if (newImageId != null && oldImageId != null && !newImageId.equals(oldImageId))
71
			{
72
				return Reason.createTrueReason(IMAGE_REASON);
73
			}
74
			return Reason.createFalseReason();
75
		}		
76
	}
77
78
	public boolean update(IUpdateContext context) 
79
	{
80
		// retrieve name from business model
81
		String businessName = null;
82
		String newImageId = null;
83
		PictogramElement pictogramElement = context.getPictogramElement();
84
		Object bo = getBusinessObjectForPictogramElement(pictogramElement);
85
		if (bo instanceof DiagramNodePart) 
86
		{
87
			DiagramNodePart nodePart = (DiagramNodePart) bo;
88
			businessName = nodePart.getLabel();
89
			newImageId = nodePart.getImageId();
90
		}
91
92
		// Set name in pictogram model
93
		if (pictogramElement instanceof ContainerShape) 
94
		{
95
			ContainerShape cs = (ContainerShape) pictogramElement;
96
			for (Shape shape : cs.getChildren()) 
97
			{
98
				if (shape.getGraphicsAlgorithm() instanceof Text) 
99
				{
100
					Text text = (Text) shape.getGraphicsAlgorithm();
101
					text.setValue(businessName);
102
					return true;
103
				}
104
				else if (shape.getGraphicsAlgorithm() instanceof Image) 
105
				{
106
					Image oldImage = (Image)shape.getGraphicsAlgorithm();
107
					if (!oldImage.getId().equals(newImageId))
108
					{
109
						int x = oldImage.getX();
110
						int y = oldImage.getY();
111
						int width = oldImage.getWidth();
112
						int height = oldImage.getHeight();
113
						
114
						Image image = Graphiti.getGaService().createImage(shape, newImageId);
115
						Graphiti.getGaService().setLocationAndSize(image, x, y, width, height);
116
			    		Graphiti.getPeService().setPropertyValue(cs, 
117
			    				SapphireDiagramPropertyKeys.NODE_IMAGE_ID, newImageId);
118
	
119
						return true;
120
					}
121
				}
122
				
123
			}
124
		}
125
126
		return false;
127
	}
128
129
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/providers/SapphireDiagramFeatureProvider.java (+257 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.providers;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
6
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
7
import org.eclipse.graphiti.features.IAddBendpointFeature;
8
import org.eclipse.graphiti.features.IAddFeature;
9
import org.eclipse.graphiti.features.ICreateConnectionFeature;
10
import org.eclipse.graphiti.features.ICreateFeature;
11
import org.eclipse.graphiti.features.IDeleteFeature;
12
import org.eclipse.graphiti.features.IDirectEditingFeature;
13
import org.eclipse.graphiti.features.IMoveBendpointFeature;
14
import org.eclipse.graphiti.features.IMoveShapeFeature;
15
import org.eclipse.graphiti.features.IRemoveBendpointFeature;
16
import org.eclipse.graphiti.features.IRemoveFeature;
17
import org.eclipse.graphiti.features.IResizeShapeFeature;
18
import org.eclipse.graphiti.features.IUpdateFeature;
19
import org.eclipse.graphiti.features.context.IAddBendpointContext;
20
import org.eclipse.graphiti.features.context.IAddContext;
21
import org.eclipse.graphiti.features.context.IDeleteContext;
22
import org.eclipse.graphiti.features.context.IDirectEditingContext;
23
import org.eclipse.graphiti.features.context.IMoveBendpointContext;
24
import org.eclipse.graphiti.features.context.IMoveShapeContext;
25
import org.eclipse.graphiti.features.context.IRemoveBendpointContext;
26
import org.eclipse.graphiti.features.context.IRemoveContext;
27
import org.eclipse.graphiti.features.context.IResizeShapeContext;
28
import org.eclipse.graphiti.features.context.IUpdateContext;
29
import org.eclipse.graphiti.features.impl.IIndependenceSolver;
30
import org.eclipse.graphiti.mm.pictograms.Connection;
31
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
32
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
33
import org.eclipse.graphiti.ui.features.DefaultFeatureProvider;
34
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionPart;
35
import org.eclipse.sapphire.ui.diagram.editor.DiagramConnectionTemplate;
36
import org.eclipse.sapphire.ui.diagram.editor.DiagramGeometryWrapper;
37
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart;
38
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodeTemplate;
39
import org.eclipse.sapphire.ui.diagram.editor.SapphireDiagramEditorPart;
40
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireAddBendpointFeature;
41
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireAddConnectionFeature;
42
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireAddNodeFeature;
43
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireCreateConnectionFeature;
44
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireCreateNodeFeature;
45
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireDeleteConnectionFeature;
46
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireDeleteNodeFeature;
47
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireDirectEditConnectionFeature;
48
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireDirectEditNodeFeature;
49
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireMoveBendpointFeature;
50
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireMoveNodeFeature;
51
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireRemoveBendpointFeature;
52
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireRemoveFeature;
53
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireResizeShapeFeature;
54
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireUpdateConnectionFeature;
55
import org.eclipse.sapphire.ui.diagram.graphiti.features.SapphireUpdateNodeFeature;
56
57
public class SapphireDiagramFeatureProvider extends DefaultFeatureProvider 
58
{
59
	private SapphireDiagramEditorPart diagramPart;
60
	
61
	public SapphireDiagramFeatureProvider(IDiagramTypeProvider dtp, IIndependenceSolver solver)
62
	{
63
		super(dtp);
64
		this.setIndependenceSolver(solver);
65
	}
66
	
67
	public void setDiagramPart(SapphireDiagramEditorPart diagramPart)
68
	{
69
		this.diagramPart = diagramPart;
70
		
71
	}
72
	
73
	public SapphireDiagramEditorPart getDiagramPart()
74
	{
75
		return this.diagramPart;
76
	}
77
	
78
	public DiagramGeometryWrapper getDiagramGeometry()
79
	{
80
		return this.diagramPart.getDiagramGeometry();
81
	}
82
	
83
	@Override
84
	public IAddFeature getAddFeature(IAddContext context) 
85
	{
86
		Object obj = context.getNewObject();
87
		if (obj instanceof DiagramNodePart)
88
		{
89
			return new SapphireAddNodeFeature(this);
90
		}
91
		else if (obj instanceof DiagramConnectionPart)
92
		{
93
			return new SapphireAddConnectionFeature(this);
94
		}
95
		
96
		return super.getAddFeature(context);
97
	}
98
	
99
	@Override
100
	public ICreateFeature[] getCreateFeatures() 
101
	{
102
		List<DiagramNodeTemplate> nodeTemplates = this.diagramPart.getNodeTemplates();
103
		ICreateFeature[] features = new ICreateFeature[nodeTemplates.size()];
104
		int i = 0;
105
		for (DiagramNodeTemplate nodeTemplate : nodeTemplates)
106
		{
107
			SapphireCreateNodeFeature createNodeFeature = 
108
				new SapphireCreateNodeFeature(this, nodeTemplate);
109
			features[i++] = createNodeFeature;
110
		}
111
		return features;
112
	}	
113
	
114
	@Override
115
	public IDeleteFeature getDeleteFeature(IDeleteContext context) 
116
	{
117
		PictogramElement pe = context.getPictogramElement();
118
		if (pe instanceof Connection)
119
		{
120
			return new SapphireDeleteConnectionFeature(this);
121
		}
122
		else if (pe instanceof ContainerShape)
123
		{
124
			return new SapphireDeleteNodeFeature(this);
125
		}
126
		return null;
127
	}
128
	
129
	@Override
130
	public IRemoveFeature getRemoveFeature(IRemoveContext context) 
131
	{
132
		return new SapphireRemoveFeature(this);
133
	}
134
	
135
	@Override
136
    public ICreateConnectionFeature[] getCreateConnectionFeatures() 
137
	{
138
		List<DiagramConnectionTemplate> connectionTemplates = this.diagramPart.getConnectionTemplates();
139
		List<ICreateConnectionFeature> features = 
140
			new ArrayList<ICreateConnectionFeature>(connectionTemplates.size());
141
		for (DiagramConnectionTemplate connectionTemplate : connectionTemplates)
142
		{
143
			SapphireCreateConnectionFeature createConnectionFeature = 
144
				new SapphireCreateConnectionFeature(this, connectionTemplate);
145
			features.add(createConnectionFeature);
146
		}
147
		
148
		// Add Embedded connection features
149
		List<DiagramNodeTemplate> nodeTemplates = this.diagramPart.getNodeTemplates();
150
		for (DiagramNodeTemplate nodeTemplate : nodeTemplates)
151
		{
152
			DiagramConnectionTemplate connTemplate = nodeTemplate.getEmbeddedConnectionTemplate();
153
			if (connTemplate != null)
154
			{
155
				SapphireCreateConnectionFeature createConnectionFeature = 
156
					new SapphireCreateConnectionFeature(this, connTemplate);
157
				features.add(createConnectionFeature);
158
			}
159
		}		
160
		return features.toArray(new ICreateConnectionFeature[0]);
161
	}
162
	
163
	@Override
164
	public IDirectEditingFeature getDirectEditingFeature(IDirectEditingContext context) 
165
	{
166
		PictogramElement pe = context.getPictogramElement();
167
		Object bo = getBusinessObjectForPictogramElement((PictogramElement) pe.eContainer());
168
		if (bo instanceof DiagramNodePart)
169
		{
170
			return new SapphireDirectEditNodeFeature(this);
171
		}
172
		else if (bo instanceof DiagramConnectionPart)
173
		{
174
			return new SapphireDirectEditConnectionFeature(this);
175
		}
176
		return super.getDirectEditingFeature(context);		
177
	}
178
	
179
	@Override
180
	public IUpdateFeature getUpdateFeature(IUpdateContext context) 
181
	{
182
		PictogramElement pe = context.getPictogramElement();
183
		if (pe instanceof ContainerShape) 
184
		{
185
			Object bo = getBusinessObjectForPictogramElement(pe);
186
			if (bo instanceof DiagramNodePart) 
187
			{
188
				return new SapphireUpdateNodeFeature(this);
189
			}
190
		}
191
		else if (pe instanceof Connection)
192
		{
193
			Object bo = getBusinessObjectForPictogramElement(pe);
194
			if (bo instanceof DiagramConnectionPart)
195
			{
196
				return new SapphireUpdateConnectionFeature(this);
197
			}
198
		}
199
		return super.getUpdateFeature(context);
200
	}
201
	
202
	@Override
203
	public IAddBendpointFeature getAddBendpointFeature(IAddBendpointContext context) 
204
	{
205
		IAddBendpointFeature ret = new SapphireAddBendpointFeature(this);
206
		return ret;
207
	}
208
	
209
	@Override
210
	public IRemoveBendpointFeature getRemoveBendpointFeature(IRemoveBendpointContext context) 
211
	{
212
		IRemoveBendpointFeature ret = new SapphireRemoveBendpointFeature(this);
213
		return ret;
214
	}
215
216
	@Override
217
	public IMoveBendpointFeature getMoveBendpointFeature(IMoveBendpointContext context) 
218
	{
219
		IMoveBendpointFeature ret = new SapphireMoveBendpointFeature(this);
220
		return ret;
221
	}
222
	
223
    @Override
224
    public IMoveShapeFeature getMoveShapeFeature(IMoveShapeContext context) 
225
    {
226
    	return new SapphireMoveNodeFeature(this);
227
    }
228
	
229
	@Override
230
	public IResizeShapeFeature getResizeShapeFeature(IResizeShapeContext context) 
231
	{
232
		IResizeShapeFeature ret = new SapphireResizeShapeFeature(this);
233
		return ret;
234
	}
235
	
236
	/**
237
	 * When a PE is removed from the diagram, we need to remove the corresponding
238
	 * key from the solver and the saved node position/connection bendpoints from
239
	 * the cached diagram geometry
240
	 * @param bo
241
	 */
242
	public void remove(Object bo)
243
	{
244
		((SapphireDiagramSolver)this.getIndependenceSolver()).removeBO(bo);
245
		
246
		DiagramGeometryWrapper gw = getDiagramGeometry();
247
		if (bo instanceof DiagramNodePart)
248
		{
249
			gw.removeNode((DiagramNodePart)bo);
250
		}
251
		else if (bo instanceof DiagramConnectionPart)
252
		{
253
			gw.removeConnectionBendpoints((DiagramConnectionPart)bo);
254
		}
255
	}
256
	    
257
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/providers/SapphireDiagramImageProvider.java (+23 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.providers;
2
3
import org.eclipse.graphiti.ui.platform.AbstractImageProvider;
4
5
public class SapphireDiagramImageProvider extends AbstractImageProvider 
6
{
7
	public SapphireDiagramImageProvider()
8
	{
9
		super();
10
	}
11
	
12
	@Override
13
	protected void addAvailableImages() 
14
	{
15
16
	}
17
	
18
	public void registerImage(String imageId, String imageFilePath)
19
	{
20
		this.addImageFilePath(imageId, imageFilePath);
21
	}
22
23
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/providers/SapphireDiagramPropertyKeys.java (+6 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.providers;
2
3
public interface SapphireDiagramPropertyKeys 
4
{
5
	public static final String NODE_IMAGE_ID = "nodeImageId";
6
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/providers/SapphireDiagramSolver.java (+56 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.providers;
2
3
import java.util.HashMap;
4
5
import org.eclipse.graphiti.features.impl.IIndependenceSolver;
6
import org.eclipse.sapphire.ui.SapphirePart;
7
8
public class SapphireDiagramSolver implements IIndependenceSolver 
9
{
10
	private HashMap<String, SapphirePart> keyToBOMap;
11
	private HashMap<SapphirePart, String> bOToKeyMap;
12
	private int counter = 0;
13
14
	public SapphireDiagramSolver()
15
	{
16
		this.keyToBOMap = new HashMap<String, SapphirePart>();
17
		this.bOToKeyMap = new HashMap<SapphirePart, String>();		
18
	}
19
	
20
	public String getKeyForBusinessObject(Object bo) 
21
	{
22
		if (bo instanceof SapphirePart)			
23
		{
24
			SapphirePart part = (SapphirePart)bo;
25
			if (this.bOToKeyMap.containsKey(bo))
26
			{
27
				return this.bOToKeyMap.get(bo);
28
			}
29
			String key = Integer.toString(this.counter++);
30
			this.keyToBOMap.put(key, part);
31
			this.bOToKeyMap.put(part, key);
32
			
33
			return key;
34
		}
35
		return null;
36
	}
37
38
	public Object getBusinessObjectForKey(String key) 
39
	{
40
		if (key == null)
41
			return null;
42
		return this.keyToBOMap.get(key);
43
	}
44
45
	public boolean removeBO(Object bo)
46
	{
47
		if (this.bOToKeyMap.containsKey(bo))
48
		{
49
			String key = this.bOToKeyMap.get(bo);
50
			this.bOToKeyMap.remove(bo);
51
			this.keyToBOMap.remove(key);
52
			return true;
53
		}
54
		return false;
55
	}
56
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/providers/SapphireDiagramToolBehaviorProvider.java (+25 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.providers;
2
3
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
4
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
5
import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;
6
import org.eclipse.graphiti.tb.IContextButtonPadData;
7
8
9
public class SapphireDiagramToolBehaviorProvider extends DefaultToolBehaviorProvider 
10
{
11
	public SapphireDiagramToolBehaviorProvider(IDiagramTypeProvider dtp) 
12
	{
13
		super(dtp);
14
	}
15
16
	/**
17
	 * Override super class impl to not include "Remove"
18
	 */
19
	@Override
20
	protected void setGenericContextButtons(IContextButtonPadData data, PictogramElement pe, int identifiers) 
21
	{
22
		identifiers -= CONTEXT_BUTTON_REMOVE;
23
		super.setGenericContextButtons(data, pe, identifiers);
24
	}
25
}
(-)src/org/eclipse/sapphire/ui/diagram/graphiti/providers/SapphireDiagramTypeProvider.java (+148 lines)
Added Link Here
1
package org.eclipse.sapphire.ui.diagram.graphiti.providers;
2
3
import java.io.File;
4
import java.io.IOException;
5
import java.net.URL;
6
import java.util.List;
7
8
import org.eclipse.core.runtime.FileLocator;
9
import org.eclipse.core.runtime.Path;
10
import org.eclipse.core.runtime.Platform;
11
import org.eclipse.graphiti.dt.AbstractDiagramTypeProvider;
12
import org.eclipse.graphiti.mm.pictograms.Diagram;
13
import org.eclipse.graphiti.platform.IDiagramEditor;
14
import org.eclipse.graphiti.tb.IToolBehaviorProvider;
15
import org.eclipse.graphiti.ui.internal.platform.ExtensionManager;
16
import org.eclipse.graphiti.ui.platform.IImageProvider;
17
import org.eclipse.graphiti.ui.services.GraphitiUi;
18
import org.eclipse.sapphire.modeling.ModelElementList;
19
import org.eclipse.sapphire.ui.def.IImportDirective;
20
import org.eclipse.sapphire.ui.def.ISapphireUiDef;
21
import org.eclipse.sapphire.ui.diagram.def.IDiagramImageChoice;
22
import org.eclipse.sapphire.ui.diagram.def.IDiagramNodeDef;
23
import org.eclipse.sapphire.ui.diagram.editor.DiagramNodeTemplate;
24
import org.eclipse.sapphire.ui.diagram.editor.SapphireDiagramEditorPart;
25
import org.eclipse.sapphire.ui.diagram.graphiti.editor.SapphireDiagramEditor;
26
import org.eclipse.sapphire.ui.internal.SapphireUiFrameworkPlugin;
27
import org.eclipse.ui.internal.util.BundleUtility;
28
import org.osgi.framework.Bundle;
29
30
public class SapphireDiagramTypeProvider extends AbstractDiagramTypeProvider 
31
{
32
	private SapphireDiagramEditorPart diagramPart;
33
	private SapphireDiagramFeatureProvider featureProvider;
34
	private IToolBehaviorProvider[] toolBehaviorProviders;
35
	
36
	public SapphireDiagramTypeProvider()
37
	{
38
		this.featureProvider = 
39
			new SapphireDiagramFeatureProvider(this, new SapphireDiagramSolver());
40
		setFeatureProvider(this.featureProvider);
41
	}
42
	
43
	public void setDiagramPart(SapphireDiagramEditorPart diagramPart)
44
	{
45
		this.diagramPart = diagramPart;
46
		this.featureProvider.setDiagramPart(diagramPart);		
47
	}
48
	
49
	public SapphireDiagramEditorPart getDiagramPart()
50
	{
51
		return this.diagramPart;
52
	}
53
	
54
	@Override
55
	public void init(Diagram diagram, IDiagramEditor diagramEditor)
56
	{
57
		super.init(diagram, diagramEditor);
58
		setDiagramPart(((SapphireDiagramEditor)diagramEditor).getDiagramEditorPart());
59
		ExtensionManager extManager = (ExtensionManager)GraphitiUi.getExtensionManager();
60
		IImageProvider imageProviders[] = extManager.getImageProviders();
61
		SapphireDiagramImageProvider sapphireImageProvider = null;
62
		for (IImageProvider imageProvider : imageProviders)
63
		{
64
			if (imageProvider instanceof SapphireDiagramImageProvider)
65
			{
66
				sapphireImageProvider = (SapphireDiagramImageProvider)imageProvider;
67
				break;
68
			}
69
		}
70
		if (sapphireImageProvider != null)
71
		{
72
			List<DiagramNodeTemplate> nodeTemplates = this.diagramPart.getNodeTemplates();
73
			for (DiagramNodeTemplate nodeTemplate : nodeTemplates)
74
			{
75
				IDiagramNodeDef nodeDef = nodeTemplate.getDefinition();
76
				if (nodeDef.getImage().element() != null)
77
				{
78
					ModelElementList<IDiagramImageChoice> images = nodeDef.getPossibleImages();
79
					for (IDiagramImageChoice imageChoice : images)
80
					{
81
						ISapphireUiDef uiDef = imageChoice.nearest(ISapphireUiDef.class);
82
						String imageId = imageChoice.getImageId().getContent();
83
						String imagePath = imageChoice.getImagePath().getContent();
84
						String bundleId = resolveImageBundle(uiDef, imagePath);
85
						// Graphiti's image provider doesn't support images from different plugins.
86
						// See http://www.eclipse.org/forums/index.php?t=tree&th=201973&start=0&S=3813ad4d99f2ac8bd56a0072ffa6ebd9
87
						if (bundleId != null)
88
						{
89
							sapphireImageProvider.setPluginId(bundleId);
90
						}
91
						
92
						if (imageId != null && imagePath != null)
93
						{
94
							sapphireImageProvider.registerImage(imageId, imagePath);
95
						}						
96
					}
97
				}
98
			}
99
		}
100
	}
101
	
102
    @Override
103
    public IToolBehaviorProvider[] getAvailableToolBehaviorProviders() 
104
    {
105
        if (this.toolBehaviorProviders == null) 
106
        {
107
            this.toolBehaviorProviders =
108
                new IToolBehaviorProvider[] { new SapphireDiagramToolBehaviorProvider(this) };
109
        }
110
        return this.toolBehaviorProviders;
111
    }
112
	
113
    @Override
114
    public void postInit() 
115
    {    	
116
    	SapphireDiagramEditor sapphireEditor = (SapphireDiagramEditor)getDiagramEditor();
117
    	sapphireEditor.syncDiagramWithModel();
118
    	sapphireEditor.doSave(null);
119
    }
120
    
121
    private String resolveImageBundle(ISapphireUiDef def, String imagePath)
122
    {
123
    	try
124
    	{
125
	    	for (IImportDirective directive : def.getImportDirectives())
126
	    	{
127
	            final String bundleId = directive.getBundle().getText();
128
	            Bundle bundle = Platform.getBundle(bundleId);
129
	            URL url = BundleUtility.find(bundle, imagePath);
130
				URL locatedURL = FileLocator.toFileURL(url);
131
				if ("file".equalsIgnoreCase(locatedURL.getProtocol()))
132
				{
133
					String fullPath = new Path(locatedURL.getPath()).toOSString();
134
					File f = new File(fullPath);
135
					if (f.exists())
136
					{
137
						return bundleId;
138
					}
139
				}
140
	    	}
141
    	}
142
    	catch (IOException e)
143
    	{
144
    		SapphireUiFrameworkPlugin.log(e);
145
    	}
146
    	return null;
147
    }
148
}

Return to bug 330482