Pārlūkot izejas kodu

6.7.4 release

Former-commit-id: 99ed564f52f97a5a44bd005761409a9263c7274d
Gaudenz Alder 8 gadi atpakaļ
vecāks
revīzija
8904e4f760

+ 6 - 0
ChangeLog

@@ -1,3 +1,9 @@
+05-JUN-2017: 6.7.4
+
+- Fixes overridden rounded style for non-rounded shapes
+- Adds defaultVertexStyle/defaultEdgeStyle in Editor.configure
+- Adds replay plugin
+
 03-JUN-2017: 6.7.3
 
 - Updates Gliffy translations to add Flowchart v2 library

+ 1 - 1
VERSION

@@ -1 +1 @@
-6.7.3
+6.7.4

+ 55 - 43
src/com/mxgraph/io/mxVsdxCodec.java

@@ -806,6 +806,22 @@ public class mxVsdxCodec
 		geo.setY(Math.round(y1 + cy - geo.getHeight() / 2));
 	}
 
+	public static void rotatedEdgePoint(mxPoint pt, double rotation,
+			double cx, double cy)
+	{
+		rotation = Math.toRadians(rotation);
+		double cos = Math.cos(rotation), sin = Math.sin(rotation);
+
+		double x = pt.getX() - cx;
+		double y = pt.getY() - cy;
+
+		double x1 = x * cos - y * sin;
+		double y1 = y * cos + x * sin;
+
+		pt.setX(Math.round(x1 + cx));
+		pt.setY(Math.round(y1 + cy));
+	}
+
 	/**
 	 * Adds a simple shape to the graph
 	 * @param graph Graph where the parsed graph is included.
@@ -924,11 +940,11 @@ public class mxVsdxCodec
 
 		//Get beginXY and endXY coordinates.
 		mxPoint beginXY = edgeShape.getStartXY(parentHeight);
-		mxPoint origBeginXY = new mxPoint(beginXY);
-		
-		beginXY = calculateAbsolutePoint(parent, graph, beginXY);
+		mxPoint endXY = edgeShape.getEndXY(parentHeight);
+		List<mxPoint> points = edgeShape.getRoutingPoints(parentHeight, beginXY, edgeShape.getRotation());
+
+		rotateChildEdge(graph.getModel(), parent, beginXY, endXY, points);
 
-		mxPoint fromConstraint = null;
 		Integer sourceSheet = connect.getSourceToSheet();
 
 		mxCell source = sourceSheet != null ? vertexMap
@@ -938,16 +954,10 @@ public class mxVsdxCodec
 		{
 			// Source is dangling
 			source = (mxCell) graph.insertVertex(parent, null, null,
-					origBeginXY.getX(), origBeginXY.getY(), 0, 0);
-			fromConstraint = new mxPoint(0, 0);
+					beginXY.getX(), beginXY.getY(), 0, 0);
 		}
 		//Else: Routing points will contain the exit/entry points, so no need to set the to/from constraint 
 
-		mxPoint endXY = edgeShape.getEndXY(parentHeight);
-		mxPoint originEndXY = new mxPoint(endXY);
-		endXY = calculateAbsolutePoint(parent, graph, endXY);
-		
-		mxPoint toConstraint = null;
 		Integer toSheet = connect.getTargetToSheet();
 
 		mxCell target = toSheet != null ? vertexMap.get(new ShapePageId(
@@ -957,8 +967,7 @@ public class mxVsdxCodec
 		{
 			// Target is dangling
 			target = (mxCell) graph.insertVertex(parent, null, null,
-					originEndXY.getX(), originEndXY.getY(), 0, 0);
-			toConstraint = new mxPoint(0, 0);
+					endXY.getX(), endXY.getY(), 0, 0);
 		}
 		//Else: Routing points will contain the exit/entry points, so no need to set the to/from constraint 
 
@@ -967,7 +976,6 @@ public class mxVsdxCodec
 				.getStyleFromEdgeShape(parentHeight);
 		//Insert new edge and set constraints.
 		Object edge;
-		List<mxPoint> points = edgeShape.getRoutingPoints(parentHeight, origBeginXY, edgeShape.getRotation());
 		double rotation = edgeShape.getRotation();
 		if (rotation != 0)
 		{
@@ -998,17 +1006,6 @@ public class mxVsdxCodec
 		mxGeometry edgeGeometry = graph.getModel().getGeometry(edge);
 		edgeGeometry.setPoints(points);
 
-		if (fromConstraint != null)
-		{
-			graph.setConnectionConstraint(edge, source, true,
-					new mxConnectionConstraint(fromConstraint, false));
-		}
-		if (toConstraint != null)
-		{
-			graph.setConnectionConstraint(edge, target, false,
-					new mxConnectionConstraint(toConstraint, false));
-		}
-
 		//Gets and sets routing points of the edge.
 		if (styleMap.containsKey("curved")
 				&& styleMap.get("curved").equals("1"))
@@ -1022,24 +1019,6 @@ public class mxVsdxCodec
 		return edgeId;
 	}
 
-	/**
-	 * Find the top parent in a group
-	 * 
-	 * @param cell
-	 * @return the top most parent (which has the defaultParent as its parent)
-	 */
-	private mxCell findTopParent(mxCell cell, mxCell defaultParent)
-	{
-		mxCell parent = (mxCell) cell.getParent();
-		
-		while (parent.getParent() != null && parent.getParent() != defaultParent)
-		{
-			parent = (mxCell) parent.getParent();
-		}
-
-		return parent;
-	}
-
 	/**
 	 * Adds a new edge not connected to any vertex to the graph.
 	 * @param graph Graph where the parsed graph is included.
@@ -1111,6 +1090,9 @@ public class mxVsdxCodec
 			mxPoint lblOffset = edgeShape.getLblEdgeOffset(graph.getView(), points);
 			((mxCell)edge).getGeometry().setOffset(lblOffset);
 		}
+		
+		rotateChildEdge(graph.getModel(), parent, beginXY, endXY, points);
+		
 		mxGeometry edgeGeometry = graph.getModel().getGeometry(edge);
 		edgeGeometry.setPoints(points);
 		
@@ -1130,6 +1112,36 @@ public class mxVsdxCodec
 		return edge;
 	}
 
+	protected void rotateChildEdge(mxIGraphModel model, Object parent, mxPoint beginXY, mxPoint endXY, List<mxPoint> points) {
+		//Rotate all points based on parent rotation
+		//Must get parent rotation and apply it similar to what we did in group rotation of all children
+		if (parent != null)
+		{
+			mxGeometry pgeo = model.getGeometry(parent);
+			String pStyle = model.getStyle(parent);
+			
+			if (pgeo != null && pStyle != null) 
+			{
+				int pos = pStyle.indexOf("rotation=");
+				
+				if (pos > -1)
+				{
+					double pRotation = Double.parseDouble(pStyle.substring(pos + 9, pStyle.indexOf(';', pos))); //9 is the length of "rotation="
+	
+					double hw = pgeo.getWidth() / 2, hh = pgeo.getHeight() / 2;
+					
+					rotatedEdgePoint(beginXY, pRotation, hw, hh);
+					rotatedEdgePoint(endXY, pRotation, hw, hh);
+					
+					for (mxPoint p : points) 
+					{
+						rotatedEdgePoint(p, pRotation, hw, hh);
+					}
+				}
+			}
+		}
+	}
+
 	/**
 	 * Post processes groups to remove leaf vertices that render nothing
 	 * @param group

+ 1 - 1
war/cache.manifest

@@ -1,7 +1,7 @@
 CACHE MANIFEST
 
 # THIS FILE WAS GENERATED. DO NOT MODIFY!
-# 06/03/2017 09:45 AM
+# 06/05/2017 12:53 PM
 
 app.html
 index.html?offline=1

+ 6 - 6
war/images/manifest.json

@@ -2,37 +2,37 @@
 	"name": "draw.io",
 	"icons": [
 		{
-			"src": "images\/android-chrome-36x36.png",
+			"src": "\/images\/android-chrome-36x36.png",
 			"sizes": "36x36",
 			"type": "image\/png",
 			"density": 0.75
 		},
 		{
-			"src": "images\/android-chrome-48x48.png",
+			"src": "\/images\/android-chrome-48x48.png",
 			"sizes": "48x48",
 			"type": "image\/png",
 			"density": 1
 		},
 		{
-			"src": "images\/android-chrome-72x72.png",
+			"src": "\/images\/android-chrome-72x72.png",
 			"sizes": "72x72",
 			"type": "image\/png",
 			"density": 1.5
 		},
 		{
-			"src": "images\/android-chrome-96x96.png",
+			"src": "\/images\/android-chrome-96x96.png",
 			"sizes": "96x96",
 			"type": "image\/png",
 			"density": 2
 		},
 		{
-			"src": "images\/android-chrome-144x144.png",
+			"src": "\/images\/android-chrome-144x144.png",
 			"sizes": "144x144",
 			"type": "image\/png",
 			"density": 3
 		},
 		{
-			"src": "images\/android-chrome-192x192.png",
+			"src": "\/images\/android-chrome-192x192.png",
 			"sizes": "192x192",
 			"type": "image\/png",
 			"density": 4

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 35 - 35
war/js/app.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 19 - 18
war/js/atlas-viewer.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 37 - 37
war/js/atlas.min.js


+ 4 - 2
war/js/diagramly/App.js

@@ -185,7 +185,8 @@ App.pluginRegistry = {'4xAKTrabTpTzahoLthkwPNUn': '/plugins/explore.js',
 	'number': '/plugins/number.js', 'sql': '/plugins/sql.js',
 	'props': '/plugins/props.js', 'text': '/plugins/text.js',
 	'anim': '/plugins/animation.js', 'update': '/plugins/update.js',
-	'trees': '/plugins/trees/trees.js', 'import': '/plugins/import.js'};
+	'trees': '/plugins/trees/trees.js', 'import': '/plugins/import.js',
+	'replay': '/plugins/replay.js'};
 
 /**
  * Function: authorize
@@ -2398,7 +2399,8 @@ App.prototype.showSplash = function(force)
 				if (cancel && !mxClient.IS_CHROMEAPP)
 				{
 					var prev = Editor.useLocalStorage;
-					this.createFile(this.defaultFilename, null, null, null, null, null, null, true);
+					this.createFile(this.defaultFilename, null, null, null, null, null, null,
+						urlParams['local'] != '1');
 					Editor.useLocalStorage = prev;
 				}
 			}));

+ 25 - 6
war/js/diagramly/Editor.js

@@ -119,12 +119,31 @@
 	 */
 	Editor.configure = function(config)
 	{
-		// LATER: DefaultFont and DefaultFontSize should override Graph's stylesheet,
-		// default edge and vertex styles would have to be set before loading mxSettings
-		Menus.prototype.defaultFonts = config.defaultFonts || Menus.prototype.defaultFonts;
-		ColorDialog.prototype.presetColors = config.presetColors || ColorDialog.prototype.presetColors;
-		ColorDialog.prototype.defaultColors = config.defaultColors || ColorDialog.prototype.defaultColors;
-		StyleFormatPanel.prototype.defaultColorSchemes = config.defaultColorSchemes || StyleFormatPanel.prototype.defaultColorSchemes;
+		if (config != null)
+		{
+			Menus.prototype.defaultFonts = config.defaultFonts || Menus.prototype.defaultFonts;
+			ColorDialog.prototype.presetColors = config.presetColors || ColorDialog.prototype.presetColors;
+			ColorDialog.prototype.defaultColors = config.defaultColors || ColorDialog.prototype.defaultColors;
+			StyleFormatPanel.prototype.defaultColorSchemes = config.defaultColorSchemes || StyleFormatPanel.prototype.defaultColorSchemes;
+
+			// Overrides themes for default edge and vertex styles
+			var graphLoadStylesheet = Graph.prototype.loadStylesheet;
+			
+			Graph.prototype.loadStylesheet = function()
+			{
+				graphLoadStylesheet.apply(this, arguments);
+				
+				if (config.defaultVertexStyle != null)
+				{
+					this.getStylesheet().putDefaultVertexStyle(config.defaultVertexStyle);
+				}
+				
+				if (config.defaultEdgeStyle != null)
+				{
+					this.getStylesheet().putDefaultEdgeStyle(config.defaultEdgeStyle);
+				}
+			};
+		}
 	};
 
 	/**

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 2
war/js/embed-static.min.js


+ 4 - 1
war/js/mxgraph/EditorUi.js

@@ -460,7 +460,10 @@ EditorUi = function(editor, container, lightbox)
 	
 	for (var i = 0; i < connectStyles.length; i++)
 	{
-		styles.push(connectStyles[i]);
+		if (mxUtils.indexOf(styles, connectStyles[i]) < 0)
+		{
+			styles.push(connectStyles[i]);
+		}
 	}
 
 	// Implements a global current style for edges and vertices that is applied to new cells

+ 3 - 2
war/js/mxgraph/Graph.js

@@ -8,8 +8,9 @@ if (typeof html4 !== 'undefined')
 	html4.ATTRIBS["a::target"] = 0;
 	html4.ATTRIBS["source::src"] = 0;
 	html4.ATTRIBS["video::src"] = 0;
-	html4.ATTRIBS["video::autoplay"] = 0;
-	html4.ATTRIBS["video::autobuffer"] = 0;
+	// Would be nice for tooltips but probably a security risk...
+	//html4.ATTRIBS["video::autoplay"] = 0;
+	//html4.ATTRIBS["video::autobuffer"] = 0;
 }
 
 /**

+ 2 - 2
war/js/mxgraph/Sidebar.js

@@ -905,7 +905,7 @@ Sidebar.prototype.addGeneralPalette = function(expand)
 	var lineTags = 'line lines connector connectors connection connections arrow arrows ';
 	
 	var fns = [
-	 	this.createVertexTemplateEntry('whiteSpace=wrap;html=1;', 120, 60, '', 'Rectangle', null, null, 'rect rectangle box'),
+	 	this.createVertexTemplateEntry('rounded=0;whiteSpace=wrap;html=1;', 120, 60, '', 'Rectangle', null, null, 'rect rectangle box'),
 	 	this.createVertexTemplateEntry('rounded=1;whiteSpace=wrap;html=1;', 120, 60, '', 'Rounded Rectangle', null, null, 'rounded rect rectangle box'),
 	 	// Explicit strokecolor/fillcolor=none is a workaround to maintain transparent background regardless of current style
 	 	this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;',
@@ -913,7 +913,7 @@ Sidebar.prototype.addGeneralPalette = function(expand)
 	 	this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;spacing=5;spacingTop=-20;whiteSpace=wrap;overflow=hidden;', 190, 120,
 			'<h1>Heading</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>',
 			'Textbox', null, null, 'text textbox textarea'),
-		this.createVertexTemplateEntry('shape=ext;double=1;whiteSpace=wrap;html=1;', 120, 60, '', 'Double Rectangle', null, null, 'rect rectangle box double'),
+		this.createVertexTemplateEntry('shape=ext;double=1;rounded=0;whiteSpace=wrap;html=1;', 120, 60, '', 'Double Rectangle', null, null, 'rect rectangle box double'),
 	 	this.createVertexTemplateEntry('shape=ext;double=1;rounded=1;whiteSpace=wrap;html=1;', 120, 60, '', 'Double Rounded Rectangle', null, null, 'rounded rect rectangle box double'),
  		this.createVertexTemplateEntry('ellipse;whiteSpace=wrap;html=1;', 120, 80, '', 'Ellipse', null, null, 'oval ellipse state'),
 	 	this.createVertexTemplateEntry('ellipse;shape=doubleEllipse;whiteSpace=wrap;html=1;', 120, 80, '', 'Double Ellipse', null, null, 'oval ellipse start end state double'),

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 2
war/js/reader.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 19 - 18
war/js/viewer.min.js


+ 170 - 0
war/plugins/replay.js

@@ -0,0 +1,170 @@
+/**
+ * Replay plugin. To record steps in the Editor, click on Extras, Record.
+ * To stop recording click Extras, Record again. Enter the delay between
+ * the steps and use the URL that opens in the new window.
+ */
+Draw.loadPlugin(function(ui) {
+
+	var graph = ui.editor.graph;
+	var codec = new mxCodec();
+	var model = graph.model;
+	
+	codec.lookup = function(id)
+	{
+		return model.getCell(id);
+	};
+	
+	if (ui.editor.chromeless)
+	{
+		function decodeChanges(delta)
+		{
+			var codec2 = new mxCodec(delta.ownerDocument);
+			codec2.lookup = function(id)
+			{
+				return model.getCell(id);
+			};
+			
+			var changeNode = delta.firstChild.firstChild;
+			var changes = [];
+			
+			while (changeNode != null)
+			{
+				var change = codec2.decode(changeNode);
+				
+				change.model = model;
+				change.execute();
+				changes.push(change);
+				
+				changeNode = changeNode.nextSibling;
+			}
+			
+			return changes;
+		};
+
+		function createUndoableEdit(changes)
+		{
+			var edit = new mxUndoableEdit(model);
+			edit.changes = changes;
+			
+			edit.notify = function()
+			{
+				// LATER: Remove changes property (deprecated)
+				edit.source.fireEvent(new mxEventObject(mxEvent.CHANGE,
+					'edit', edit, 'changes', edit.changes));
+				edit.source.fireEvent(new mxEventObject(mxEvent.NOTIFY,
+					'edit', edit, 'changes', edit.changes));
+			};
+			
+			return edit;
+		};
+
+		function processDelta(delta)
+		{
+			var changes = decodeChanges(delta);
+			
+			if (changes.length > 0)
+			{
+				var edit = createUndoableEdit(changes);
+				
+				// No notify event here to avoid the edit from being encoded and transmitted
+				// LATER: Remove changes property (deprecated)
+				model.fireEvent(new mxEventObject(mxEvent.CHANGE,
+					'edit', edit, 'changes', changes));
+				model.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
+				
+				ui.chromelessResize();
+			}
+		};
+		
+		var replayData = urlParams['replay-data'];
+		var delay = parseInt(urlParams['delay-delay'] || 1000);
+		
+		if (replayData != null)
+		{
+			var xmlDoc = mxUtils.parseXml(graph.decompress(replayData));
+			// LATER: Avoid duplicate parsing
+			ui.fileLoaded(new LocalFile(ui, mxUtils.getXml(xmlDoc.documentElement.firstChild.firstChild)));
+
+			// Process deltas
+			var delta = xmlDoc.documentElement.firstChild.nextSibling;
+			
+			function nextStep()
+			{
+				if (delta != null)
+				{
+					window.setTimeout(function()
+					{
+						processDelta(delta);
+						delta = delta.nextSibling;
+						nextStep();
+					}, delay);
+				}
+			};
+			
+			nextStep();
+		}
+	}
+	else
+	{
+		var tape = null;
+
+		model.addListener(mxEvent.CHANGE, function(sender, evt)
+	    {
+	    	if (tape != null)
+	    	{
+		    	var changes = evt.getProperty('changes');
+		    	var node = codec.encode(changes);
+		    	var delta = codec.document.createElement('delta');
+		    	delta.appendChild(node);
+		    	tape.push(mxUtils.getXml(delta));
+	    	}
+	    });
+		
+		// Extends View menu
+		mxResources.parse('record=Record');
+	
+	    // Adds action
+	    var action = ui.actions.addAction('record...', function()
+	    {
+	    	if (tape == null)
+	    	{
+	    		var node = codec.encode(model);
+		    	var state = codec.document.createElement('state');
+		    	state.appendChild(node);
+		    	tape =[mxUtils.getXml(state)];
+	    	}
+	    	else if (tape != null)
+	    	{
+	    		var tmp = tape;
+	    		tape = null;
+
+				var dlg = new FilenameDialog(ui, 1000, mxResources.get('apply'), function(newValue)
+				{
+					if (newValue != null)
+					{
+						var dlg = new EmbedDialog(ui, 'https://www.draw.io/?p=replay&lightbox=1&replay-delay=' +
+								parseFloat(newValue) + '&replay-data=' + graph.compress('<recording>' +
+								tmp.join('') + '</recording>'));
+						ui.showDialog(dlg.container, 440, 240, true, true);
+						dlg.init();
+					}
+				}, 'Delay');
+				ui.showDialog(dlg.container, 300, 80, true, true);
+				dlg.init();
+	    	}
+	    });
+		
+	    action.setToggleAction(true);
+		action.setSelectedCallback(function() { return tape != null; });
+	    
+		var menu = ui.menus.get('extras');
+		var oldFunct = menu.funct;
+		
+		menu.funct = function(menu, parent)
+		{
+			oldFunct.apply(this, arguments);
+			
+			ui.menus.addMenuItems(menu, ['-', 'record'], parent);
+		};
+	}
+});