| /** |
| * Copyright (c) 2014 CEA LIST. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * CEA LIST - Initial API and implementation |
| */ |
| import org.eclipse.papyrus.dd.qvt.DDUtilities; |
| |
| modeltype DC uses "http://www.omg.org/spec/DD/20110901/DC"; |
| modeltype DG uses "http://www.omg.org/spec/DD/20110901/DG"; |
| modeltype DI uses "http://www.omg.org/spec/DD/20110901/DI"; |
| modeltype UMLDI uses "http://www.omg.org/spec/UML/20131001/UMLDI"; |
| modeltype UML uses "http://www.eclipse.org/uml2/4.0.0/UML"; |
| |
| library UmlUtilities; |
| |
| property black = createColor('#000000'); |
| |
| property white = createColor('#FFFFFF'); |
| |
| query Collection(String)::separate(separator : String) : String { |
| var str := self->iterate(s; acc : String = '' | if s = null or s = '' then acc else acc.concat(s.concat(separator)) endif); |
| return if str = '' then '' else str.substring(1,str.size()-separator.size()) endif; |
| } |
| |
| query Collection(String)::separate() : String { |
| return self->separate(', '); |
| } |
| |
| query min(n1 : Real, n2 : Real) : Real { |
| return if (n1 > n2) then n2 else n1 endif; |
| } |
| |
| query max(n1 : Real, n2 : Real) : Real { |
| return if (n1 > n2) then n1 else n2 endif; |
| } |
| |
| query abs(n : Real) : Real { |
| return if (n<0) then -n else n endif; |
| } |
| |
| query anchorPoint(bounds : Bounds, refX : Real, refY : Real) : Tuple(x: Real, y : Real) { |
| var centerX := bounds.x + bounds.width/2; |
| var centerY := bounds.y + bounds.height/2; |
| var dx = refX - centerX; |
| var dy = refY - centerY; |
| var scale = 0.5 / max(abs(dx) / bounds.width, abs(dy) / bounds.height); |
| dx := dx * scale; |
| dy := dy * scale; |
| return Tuple {x=centerX+dx, y=centerY+dy}; |
| } |
| |
| query replace(o : String, n : String, p : String) : String { |
| var s := p.replace('<o>', if o=null then '' else o endif); |
| return s.replace('<n>', if n=null then '' else n endif); |
| } |
| |
| query replaceIfNotEmpty(o : String, n : String, p : String) : String { |
| return if n = null or n = '' then o else replace(o, n, p) endif; |
| } |
| |
| query UMLDI::UmlDiagramElement::rootDiagram() : UMLDI::UmlDiagram { |
| return if (self.owningUmlDiagramElement->isEmpty()) then |
| self.oclAsType(UMLDI::UmlDiagram) |
| else |
| self.owningUmlDiagramElement.rootDiagram() |
| endif; |
| } |
| |
| query UMLDI::UmlDiagramElement::resolveDefinitions() : DG::Definitions { |
| return self.rootDiagram().resolveone(DG::Definitions); |
| } |
| |
| query DG::Definitions::getDefinition(s : String) : DG::Definition { |
| return self.definition->selectOne(id = s); |
| } |
| |
| query DG::Definitions::getMarker(s : String) : DG::Marker { |
| return self.getDefinition(s).oclAsType(DG::Marker); |
| } |
| |
| helper DG::GraphicalElement::createStyleIfNeeded() : DG::Style { |
| var e := self; |
| if e.style.oclIsUndefined() then |
| e.style := object DG::Style {} |
| endif; |
| return e.style; |
| } |
| |
| helper createNoteShape(shape : DI::Shape) : DG::Path { |
| var b := shape.bounds; |
| return object DG::Path { |
| command += object DG::MoveTo { point := object DC::Point { x := b.x; y := b.y; } }; |
| command += object DG::LineTo { point := object DC::Point { x := b.x+b.width-10; y := b.y; } }; |
| command += object DG::LineTo { point := object DC::Point { x := b.x+b.width; y := b.y+10; } }; |
| command += object DG::LineTo { point := object DC::Point { x := b.x+b.width; y := b.y+b.height; } }; |
| command += object DG::LineTo { point := object DC::Point { x := b.x; y := b.y+b.height; } }; |
| command += object DG::LineTo { point := object DC::Point { x := b.x; y := b.y; } }; |
| command += object DG::MoveTo { point := object DC::Point { x := b.x+b.width-10; y := b.y; } }; |
| command += object DG::LineTo { point := object DC::Point { x := b.x+b.width-10; y := b.y+10; } }; |
| command += object DG::LineTo { point := object DC::Point { x := b.x+b.width; y := b.y+10; } }; |
| } |
| } |
| |
| helper createNoteAttachment(shape : DI::Shape) : DG::Line { |
| var refX : Real, refY : Real; |
| var x1 : Real, y1 : Real; |
| if shape.owningDiagramElement.oclIsKindOf(DI::Edge) then { |
| var w := shape.owningDiagramElement.oclAsType(DI::Edge).waypoint; |
| var pt1 := w->at(w->size()-1); |
| var pt2 := w->at(w->size()); |
| refX := pt1.x + (pt2.x - pt1.x) / 2; |
| refY := pt1.y + (pt2.y - pt1.y) / 2; |
| x1 := refX; |
| y1 := refY; |
| } else { |
| var tb := shape.owningDiagramElement.oclAsType(DI::Shape).bounds; |
| refX := tb.x + tb.width/2; |
| refY := tb.y + tb.height/2; |
| var sb := shape.bounds; |
| var point1 := anchorPoint(tb, sb.x + sb.width/2, sb.y+sb.height/2); |
| x1 := point1.x; |
| y1 := point1.y; |
| } endif; |
| |
| var point2 := anchorPoint(shape.bounds, refX, refY); |
| var x2 := point2.x; |
| var y2 := point2.y; |
| |
| return object DG::Line { |
| start := object DC::Point { x:=x1; y:=y1; }; |
| _end := object DC::Point { x:=x2; y:=y2; }; |
| _class := "dotted"; |
| }; |
| } |
| |