diff --git a/ChangeLog b/ChangeLog index 25462751..f1e3a8a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +14-DEC-2016: 6.0.2.4 + +- Adds text field support for .vsdx import + 13-DEC-2016: 6.0.2.3 - Improves .vsdx import text handling diff --git a/VERSION b/VERSION index c89fd62c..edc9782f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0.2.3 \ No newline at end of file +6.0.2.4 \ No newline at end of file diff --git a/src/com/mxgraph/io/vsdx/Paragraph.java b/src/com/mxgraph/io/vsdx/Paragraph.java index 6e93a034..f7fc6598 100644 --- a/src/com/mxgraph/io/vsdx/Paragraph.java +++ b/src/com/mxgraph/io/vsdx/Paragraph.java @@ -14,23 +14,28 @@ public class Paragraph { protected ArrayList values; - protected ArrayList charIndex; + protected ArrayList charIndices; + + protected ArrayList fields; protected String paraIndex; - public Paragraph(String val, String ch, String pg) + public Paragraph(String val, String ch, String pg, String field) { this.values = new ArrayList(); this.values.add(val); - this.charIndex = new ArrayList(); - this.charIndex.add(ch); + this.charIndices = new ArrayList(); + this.charIndices.add(ch); + this.fields = new ArrayList(); + this.fields.add(field); this.paraIndex = pg; } - public void addValue(String val, String ch) + public void addText(String val, String ch, String field) { this.values.add(val); - this.charIndex.add(ch); + this.charIndices.add(ch); + this.fields.add(field); } public String getParagraphIndex() @@ -45,6 +50,11 @@ public class Paragraph public String getChar(int index) { - return charIndex.get(index); + return charIndices.get(index); + } + + public String getField(int index) + { + return fields.get(index); } } diff --git a/src/com/mxgraph/io/vsdx/Shape.java b/src/com/mxgraph/io/vsdx/Shape.java index 39449589..cba71f8f 100644 --- a/src/com/mxgraph/io/vsdx/Shape.java +++ b/src/com/mxgraph/io/vsdx/Shape.java @@ -26,6 +26,11 @@ public class Shape extends Style */ protected Element text; + /** + * The text fields of the shape, if any + */ + protected LinkedHashMap fields; + /** * List of paragraphs in this shape */ @@ -201,6 +206,36 @@ public class Shape extends Style this.geom.add(elem); } + if (n.equals("Field")) + { + ArrayList rows = mxVsdxUtils.getDirectChildNamedElements(elem, "Row"); + + for (Element row : rows) + { + String ix = row.getAttribute("IX"); + ArrayList cells = mxVsdxUtils.getDirectChildNamedElements(row, "Cell"); + + for (Element cell : cells) + { + n = cell.getAttribute("N"); + + if (n.equals("Value")) + { + String v = cell.getAttribute("V"); + + if (!ix.isEmpty() && !v.isEmpty()) + { + if (this.fields == null) + { + fields = new LinkedHashMap(); + } + + this.fields.put(ix, v); + } + } + } + } + } else { super.parseSection(elem); diff --git a/src/com/mxgraph/io/vsdx/VsdxShape.java b/src/com/mxgraph/io/vsdx/VsdxShape.java index fa8e5428..b38c16a0 100644 --- a/src/com/mxgraph/io/vsdx/VsdxShape.java +++ b/src/com/mxgraph/io/vsdx/VsdxShape.java @@ -239,13 +239,12 @@ public class VsdxShape extends Shape */ public String getTextLabel() { - String masterId = this.getMasterId(); Shape masterShape = null; NodeList txtChildren = getTextChildren(); if ((txtChildren == null || txtChildren.getLength() == 0) && master != null) { - if (masterId != null) + if (this.getMasterId() != null) { masterShape = master.getMasterShape(); } @@ -308,58 +307,62 @@ public class VsdxShape extends Shape paragraphs = new LinkedHashMap(); String ch = null; String pg = null; + String fld = null; for (int index = 0; index < children.getLength(); index++) { String value = null; Node node = children.item(index); + String nodeName = node.getNodeName(); - if (node.getNodeName().equals("cp")) + switch (nodeName) { - Element elem = (Element)node; - ch = elem.getAttribute("IX"); - } - else if (node.getNodeName().equals("tp")) - { - // TODO - Element elem = (Element)node; - elem.getAttribute("IX"); - } - else if (node.getNodeName().equals("pp")) - { - Element elem = (Element)node; - pg = elem.getAttribute("IX"); - - } - else if (node.getNodeName().equals("fld")) - { - // TODO - Element elem = (Element)node; - elem.getAttribute("IX"); - } - else if (node.getNodeName().equals("#text")) - { - value = StringUtils.chomp(node.getTextContent()); - } - - if (value != null && value.length() > 0) - { - // Assumes text is always last - // null key is allowed - Paragraph para = paragraphs.get(pg); - - if (para == null) + case "cp": { - para = new Paragraph(value, ch, pg); - paragraphs.put(pg, para); + Element elem = (Element)node; + ch = elem.getAttribute("IX"); } - else + break; + case "tp": { - para.addValue(value, ch); + // TODO + Element elem = (Element)node; + elem.getAttribute("IX"); + } + break; + case "pp": + { + Element elem = (Element)node; + pg = elem.getAttribute("IX"); + } + break; + case "fld": + { + Element elem = (Element)node; + fld = elem.getAttribute("IX"); + break; + } + case "#text": + { + value = StringUtils.chomp(node.getTextContent()); + + // Assumes text is always last + // null key is allowed + Paragraph para = paragraphs.get(pg); + + if (para == null) + { + para = new Paragraph(value, ch, pg, fld); + paragraphs.put(pg, para); + } + else + { + para.addText(value, ch, fld); + } + + ch = null; + pg = null; } - - ch = null; - pg = null; } } } @@ -385,7 +388,38 @@ public class VsdxShape extends Shape fontStyle |= isUnderline(index) ? mxConstants.FONT_UNDERLINE : 0; this.styleMap.put("fontStyle", String.valueOf(fontStyle)); - return para.getValue(0); + String value = para.getValue(0); + + if (value.isEmpty() && this.fields != null) + { + String fieldIx = para.getField(0); + + if (fieldIx != null) + { + value = this.fields.get(fieldIx); + + if (value == null) + { + Shape masterShape = null; + + if (this.getMasterId() != null) + { + masterShape = master.getMasterShape(); + } + else + { + masterShape = master.getSubShape(this.getShapeMasterId()); + } + + if (masterShape != null && masterShape.fields != null) + { + value = masterShape.fields.get(fieldIx); + } + } + } + } + + return value == null ? "" : value; } /** @@ -1616,6 +1650,8 @@ public class VsdxShape extends Shape int currentPointCount = 0; double lastX = startPoint.getX(); double lastY = startPoint.getY(); + double offsetX = 0; + double offsetY = 0; for (int i = 0; i < 2; i++) { @@ -1644,45 +1680,58 @@ public class VsdxShape extends Shape { switch (childName) { - case "LineTo": - if (i == 0) - { - controlPointCount++; - } - else if (currentPointCount < controlPointCount - 1) + case "MoveTo": { + // Initial moveto behaves as a offset to the whole connector Map children = getChildValues(childElem, null); String xValue = children.get("X"); String yValue = children.get("Y"); - double x = 0, y = 0; + + offsetX = xValue != null ? Double.parseDouble(xValue) : 0; + offsetY = yValue != null ? Double.parseDouble(yValue) : 0; + } + break; + case "LineTo": + { + if (i == 0) + { + controlPointCount++; + } + else if (currentPointCount < controlPointCount - 1) + { + Map children = getChildValues(childElem, null); + String xValue = children.get("X"); + String yValue = children.get("Y"); + double x = 0, y = 0; + + if (xValue != null) + { + x = (Double.parseDouble(xValue) - offsetX) * mxVsdxUtils.conversionFactor; + lastX = x; + x += startPoint.getX(); + } + else + { + x = lastX; + } - if (xValue != null) - { - x = Double.parseDouble(xValue) * mxVsdxUtils.conversionFactor; - lastX = x; - x += startPoint.getX(); + if (yValue != null) + { + y = ((Double.parseDouble(yValue) - offsetY) * mxVsdxUtils.conversionFactor) * -1; + lastY = y; + y += startPoint.getY(); + } + else + { + y = lastY; + } + + x = Math.round(x * 100.0) / 100.0; + y = Math.round(y * 100.0) / 100.0; + + points.add(new mxPoint(x, y)); + currentPointCount++; } - else - { - x = lastX; - } - - if (yValue != null) - { - y = (Double.parseDouble(yValue) * mxVsdxUtils.conversionFactor) * -1; - lastY = y; - y += startPoint.getY(); - } - else - { - y = lastY; - } - - x = Math.round(x * 100.0) / 100.0; - y = Math.round(y * 100.0) / 100.0; - - points.add(new mxPoint(x, y)); - currentPointCount++; } break; default: diff --git a/src/com/mxgraph/io/vsdx/mxPropertiesManager.java b/src/com/mxgraph/io/vsdx/mxPropertiesManager.java index 3d0a9239..b8e5495d 100644 --- a/src/com/mxgraph/io/vsdx/mxPropertiesManager.java +++ b/src/com/mxgraph/io/vsdx/mxPropertiesManager.java @@ -50,7 +50,7 @@ public class mxPropertiesManager { defaultColors.put("0", "#000000"); defaultColors.put("1", "#FFFFFF"); - defaultColors.put("2", "#FF0000"); + defaultColors.put("2", "#FFFFFF"); // Multiple label background test cases suggest white, flow3.vsdx for example defaultColors.put("3", "#00FF00"); defaultColors.put("4", "#0000FF"); defaultColors.put("5", "#FFFF00"); diff --git a/war/WEB-INF/appengine-web.xml b/war/WEB-INF/appengine-web.xml index b802ccf2..8810596f 100644 --- a/war/WEB-INF/appengine-web.xml +++ b/war/WEB-INF/appengine-web.xml @@ -2,7 +2,7 @@ drawdotio - 6-0-2-3 + 6-0-2-4 diff --git a/war/cache.manifest b/war/cache.manifest index d35c3195..6468127e 100644 --- a/war/cache.manifest +++ b/war/cache.manifest @@ -1,7 +1,7 @@ CACHE MANIFEST # THIS FILE WAS GENERATED. DO NOT MODIFY! -# 12/13/2016 04:10 PM +# 12/14/2016 02:50 PM /app.html /index.html?offline=1 diff --git a/war/js/app.min.js b/war/js/app.min.js index 50886c03..531b8cbb 100644 --- a/war/js/app.min.js +++ b/war/js/app.min.js @@ -7411,7 +7411,7 @@ c);while(c++navigator.userAgent.indexOf("MSIE")&& +window.STYLE_PATH=window.STYLE_PATH||"styles";window.CSS_PATH=window.CSS_PATH||"styles";window.OPEN_FORM=window.OPEN_FORM||"open.html";window.mxBasePath=window.mxBasePath||"../../../src";window.mxLanguage=window.mxLanguage||urlParams.lang;window.mxLanguages=window.mxLanguages||["de"];var mxClient={VERSION:"6.0.2.4",IS_IE:0<=navigator.userAgent.indexOf("MSIE"),IS_IE6:0<=navigator.userAgent.indexOf("MSIE 6"),IS_IE11:!!navigator.userAgent.match(/Trident\/7\./),IS_EDGE:!!navigator.userAgent.match(/Edge\//),IS_QUIRKS:0<=navigator.userAgent.indexOf("MSIE")&&(null==document.documentMode||5==document.documentMode),IS_EM:"spellcheck"in document.createElement("textarea")&&8==document.documentMode,VML_PREFIX:"v",OFFICE_PREFIX:"o",IS_NS:0<=navigator.userAgent.indexOf("Mozilla/")&&0>navigator.userAgent.indexOf("MSIE")&& 0>navigator.userAgent.indexOf("Edge/"),IS_OP:0<=navigator.userAgent.indexOf("Opera/")||0<=navigator.userAgent.indexOf("OPR/"),IS_OT:0<=navigator.userAgent.indexOf("Presto/")&&0>navigator.userAgent.indexOf("Presto/2.4.")&&0>navigator.userAgent.indexOf("Presto/2.3.")&&0>navigator.userAgent.indexOf("Presto/2.2.")&&0>navigator.userAgent.indexOf("Presto/2.1.")&&0>navigator.userAgent.indexOf("Presto/2.0.")&&0>navigator.userAgent.indexOf("Presto/1."),IS_SF:0<=navigator.userAgent.indexOf("AppleWebKit/")&& 0>navigator.userAgent.indexOf("Chrome/")&&0>navigator.userAgent.indexOf("Edge/"),IS_IOS:navigator.userAgent.match(/(iPad|iPhone|iPod)/g)?!0:!1,IS_GC:0<=navigator.userAgent.indexOf("Chrome/")&&0>navigator.userAgent.indexOf("Edge/"),IS_CHROMEAPP:null!=window.chrome&&null!=chrome.app&&null!=chrome.app.runtime,IS_FF:0<=navigator.userAgent.indexOf("Firefox/"),IS_MT:0<=navigator.userAgent.indexOf("Firefox/")&&0>navigator.userAgent.indexOf("Firefox/1.")&&0>navigator.userAgent.indexOf("Firefox/2.")||0<=navigator.userAgent.indexOf("Iceweasel/")&& 0>navigator.userAgent.indexOf("Iceweasel/1.")&&0>navigator.userAgent.indexOf("Iceweasel/2.")||0<=navigator.userAgent.indexOf("SeaMonkey/")&&0>navigator.userAgent.indexOf("SeaMonkey/1.")||0<=navigator.userAgent.indexOf("Iceape/")&&0>navigator.userAgent.indexOf("Iceape/1."),IS_SVG:0<=navigator.userAgent.indexOf("Firefox/")||0<=navigator.userAgent.indexOf("Iceweasel/")||0<=navigator.userAgent.indexOf("Seamonkey/")||0<=navigator.userAgent.indexOf("Iceape/")||0<=navigator.userAgent.indexOf("Galeon/")|| diff --git a/war/js/reader.min.js b/war/js/reader.min.js index 2e620dee..208f7c81 100644 --- a/war/js/reader.min.js +++ b/war/js/reader.min.js @@ -184,7 +184,7 @@ f)+"\n"+u+"}":"{"+v.join(",")+"}";f=u;return r}}"function"!==typeof Date.prototy e=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,f,g,h={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},k;"function"!==typeof JSON.stringify&&(JSON.stringify=function(a,b,d){var e;g=f="";if("number"===typeof d)for(e=0;enavigator.userAgent.indexOf("MSIE")&& +window.STYLE_PATH=window.STYLE_PATH||"styles";window.CSS_PATH=window.CSS_PATH||"styles";window.OPEN_FORM=window.OPEN_FORM||"open.html";window.mxBasePath=window.mxBasePath||"../../../src";window.mxLanguage=window.mxLanguage||urlParams.lang;window.mxLanguages=window.mxLanguages||["de"];var mxClient={VERSION:"6.0.2.4",IS_IE:0<=navigator.userAgent.indexOf("MSIE"),IS_IE6:0<=navigator.userAgent.indexOf("MSIE 6"),IS_IE11:!!navigator.userAgent.match(/Trident\/7\./),IS_EDGE:!!navigator.userAgent.match(/Edge\//),IS_QUIRKS:0<=navigator.userAgent.indexOf("MSIE")&&(null==document.documentMode||5==document.documentMode),IS_EM:"spellcheck"in document.createElement("textarea")&&8==document.documentMode,VML_PREFIX:"v",OFFICE_PREFIX:"o",IS_NS:0<=navigator.userAgent.indexOf("Mozilla/")&&0>navigator.userAgent.indexOf("MSIE")&& 0>navigator.userAgent.indexOf("Edge/"),IS_OP:0<=navigator.userAgent.indexOf("Opera/")||0<=navigator.userAgent.indexOf("OPR/"),IS_OT:0<=navigator.userAgent.indexOf("Presto/")&&0>navigator.userAgent.indexOf("Presto/2.4.")&&0>navigator.userAgent.indexOf("Presto/2.3.")&&0>navigator.userAgent.indexOf("Presto/2.2.")&&0>navigator.userAgent.indexOf("Presto/2.1.")&&0>navigator.userAgent.indexOf("Presto/2.0.")&&0>navigator.userAgent.indexOf("Presto/1."),IS_SF:0<=navigator.userAgent.indexOf("AppleWebKit/")&& 0>navigator.userAgent.indexOf("Chrome/")&&0>navigator.userAgent.indexOf("Edge/"),IS_IOS:navigator.userAgent.match(/(iPad|iPhone|iPod)/g)?!0:!1,IS_GC:0<=navigator.userAgent.indexOf("Chrome/")&&0>navigator.userAgent.indexOf("Edge/"),IS_CHROMEAPP:null!=window.chrome&&null!=chrome.app&&null!=chrome.app.runtime,IS_FF:0<=navigator.userAgent.indexOf("Firefox/"),IS_MT:0<=navigator.userAgent.indexOf("Firefox/")&&0>navigator.userAgent.indexOf("Firefox/1.")&&0>navigator.userAgent.indexOf("Firefox/2.")||0<=navigator.userAgent.indexOf("Iceweasel/")&& 0>navigator.userAgent.indexOf("Iceweasel/1.")&&0>navigator.userAgent.indexOf("Iceweasel/2.")||0<=navigator.userAgent.indexOf("SeaMonkey/")&&0>navigator.userAgent.indexOf("SeaMonkey/1.")||0<=navigator.userAgent.indexOf("Iceape/")&&0>navigator.userAgent.indexOf("Iceape/1."),IS_SVG:0<=navigator.userAgent.indexOf("Firefox/")||0<=navigator.userAgent.indexOf("Iceweasel/")||0<=navigator.userAgent.indexOf("Seamonkey/")||0<=navigator.userAgent.indexOf("Iceape/")||0<=navigator.userAgent.indexOf("Galeon/")||