/**
* Copyright 2007-2010 非也
* All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License v3 as published by the Free Software
* Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this library; if not, see http://www.gnu.org/licenses/lgpl.html.
*
*/
package org.fireflow.webdesigner.transformer;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.fireflow.model.ModelElement;
import org.fireflow.model.io.SerializerException;
import org.fireflow.pdl.fpdl.diagram.ActivityShape;
import org.fireflow.pdl.fpdl.diagram.AssociationShape;
import org.fireflow.pdl.fpdl.diagram.CommentShape;
import org.fireflow.pdl.fpdl.diagram.ConnectorShape;
import org.fireflow.pdl.fpdl.diagram.Diagram;
import org.fireflow.pdl.fpdl.diagram.DiagramElement;
import org.fireflow.pdl.fpdl.diagram.EndNodeShape;
import org.fireflow.pdl.fpdl.diagram.GroupShape;
import org.fireflow.pdl.fpdl.diagram.LaneShape;
import org.fireflow.pdl.fpdl.diagram.MessageFlowShape;
import org.fireflow.pdl.fpdl.diagram.NodeShape;
import org.fireflow.pdl.fpdl.diagram.PoolShape;
import org.fireflow.pdl.fpdl.diagram.ProcessNodeShape;
import org.fireflow.pdl.fpdl.diagram.RouterShape;
import org.fireflow.pdl.fpdl.diagram.StartNodeShape;
import org.fireflow.pdl.fpdl.diagram.TransitionShape;
import org.fireflow.pdl.fpdl.diagram.figure.Figure;
import org.fireflow.pdl.fpdl.diagram.figure.Line;
import org.fireflow.pdl.fpdl.diagram.figure.Rectangle;
import org.fireflow.pdl.fpdl.diagram.figure.part.Bounds;
import org.fireflow.pdl.fpdl.diagram.figure.part.BoundsImpl;
import org.fireflow.pdl.fpdl.diagram.figure.part.FulfilStyle;
import org.fireflow.pdl.fpdl.diagram.figure.part.Label;
import org.fireflow.pdl.fpdl.diagram.figure.part.LabelImpl;
import org.fireflow.pdl.fpdl.diagram.figure.part.Point;
import org.fireflow.pdl.fpdl.io.FPDLNames;
import org.fireflow.pdl.fpdl.process.Activity;
import org.fireflow.pdl.fpdl.process.EndNode;
import org.fireflow.pdl.fpdl.process.Router;
import org.fireflow.pdl.fpdl.process.StartNode;
import org.fireflow.pdl.fpdl.process.WorkflowProcess;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
/**
*
* @author 非也 nychen2000@163.com Fire Workflow 官方网站:www.firesoa.com 或者
* www.fireflow.org
*
*/
public class FpdlDiagramSerializerVmlImpl extends AbstractFpdlDiagramSerializer {
private Log log = LogFactory.getLog(FpdlDiagramSerializerVmlImpl.class);
public Document serializeDiagramToDoc(WorkflowProcess workflowProcess,
String subProcessName) throws SerializerException {
_init(workflowProcess, subProcessName);
// 构造根节点
Element root = document.createElement("v:group");
root.setAttribute("id", diagram.getId());
if (diagram.getWorkflowElementRef() != null) {
root.setAttribute(FPDLNames.REF, diagram.getWorkflowElementRef()
.getId());
}
document.appendChild(root);
// 流程节点
List<ProcessNodeShape> processNodeShapeList = diagram
.getProcessNodeShapes();
if (processNodeShapeList != null && processNodeShapeList.size() > 0) {
for (ProcessNodeShape nodeShape : processNodeShapeList) {
Element cell = this.transformProcessNodeShape2Vml(nodeShape,
true);
if (cell != null) {
root.appendChild(cell);
}
}
}
// 注释
List<CommentShape> commentShapeList = diagram.getComments();
if (commentShapeList != null && commentShapeList.size() > 0) {
for (CommentShape commentShape : commentShapeList) {
Element cell = transformCommentShape2Vml(commentShape, true);
if (cell != null) {
root.appendChild(cell);
}
}
}
// Group
List<GroupShape> groupShapeList = diagram.getGroups();
if (groupShapeList != null && groupShapeList.size() > 0) {
for (GroupShape groupShape : groupShapeList) {
Element cell = transformGroupShape2Vml(groupShape, true);
if (cell != null) {
root.appendChild(cell);
}
}
}
//
// //Pool
List<PoolShape> poolShapeList = diagram.getPools();
if (poolShapeList != null && poolShapeList.size() > 0) {
for (PoolShape poolShape : poolShapeList) {
Element cell = this.transformPool2Vml(poolShape, true);
if (cell != null) {
root.appendChild(cell);
}
}
}
//
// transition
List<TransitionShape> transitionShapeList = diagram.getTransitions();
if (transitionShapeList != null && transitionShapeList.size() > 0) {
for (TransitionShape transitionShape : transitionShapeList) {
transformConnectorShape2Vml(root, transitionShape);
}
}
// association
List<AssociationShape> associationShapeList = diagram.getAssociations();
if (associationShapeList != null && associationShapeList.size() > 0) {
for (AssociationShape associationShape : associationShapeList) {
Element associationCell = transformConnectorShape2Vml(root,
associationShape);
}
}
//
// //messageflow
List<MessageFlowShape> messageFlowShapeList = diagram.getMessageFlows();
if (messageFlowShapeList != null && messageFlowShapeList.size() > 0) {
for (MessageFlowShape messageFlowShape : messageFlowShapeList) {
Element messageFlowCell = this
.transformConnectorShape2Vml(root,messageFlowShape);
}
}
// 根据图形长宽,设置root属性
int width = this.rightDownX - this.leftTopX;
int height = this.rightDownY - this.leftTopY;
StringBuffer styleBuf = new StringBuffer();
styleBuf.append("position:absolute;").append("width:").append(width)
.append("px;").append("height:").append(height).append("px;");
root.setAttribute("style", styleBuf.toString());
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(width).append(",").append(height);
root.setAttribute("coordsize", coordSizeBuf.toString());
int origX = 0;
int origY = 0;
if (this.leftTopX < 0) {
origX = this.leftTopX;
}
if (this.leftTopY < 0) {
origY = this.leftTopY;
}
root.setAttribute("coordorigin", origX + "," + origY);
// 构造一个和viewport一样尺寸的rect,便于拖拉
Element rect = document.createElement("v:rect");
StringBuffer rectStyle = (new StringBuffer())
.append("position:absolute;").append("left:").append(0)
.append("px;").append("top:").append(0).append("px;")
.append("width:").append(width).append("px;").append("height:")
.append(height).append("px;").append("z-index:-99");
rect.setAttribute("style", rectStyle.toString());
rect.setAttribute("strokecolor", "white");
// rect.setAttribute("stroked","false");
// rect.setAttribute("filled", "false");
root.appendChild(rect);
return document;
}
private Element transformPool2Vml(PoolShape nodeShape,
boolean isTopLevelElem) {
// 1、构造viewport
Bounds viewportBounds = _getViewPortBounds(nodeShape);
Rectangle figure = (Rectangle) nodeShape.getFigure();
Element nodeGroup = document.createElement("v:group");
StringBuffer groupStyle = new StringBuffer();
groupStyle.append("position:absolute;").append("left:")
.append(viewportBounds.getX()).append("px;").append("top:")
.append(viewportBounds.getY()).append("px;").append("width:")
.append(viewportBounds.getWidth()).append("px;")
.append("height:").append(viewportBounds.getHeight())
.append("px;");
nodeGroup.setAttribute("style", groupStyle.toString());
nodeGroup.setAttribute(FPDLNames.ID, nodeShape.getId());
nodeGroup.setAttribute(TYPE, FPDLNames.POOL);
ModelElement wfElmRef = nodeShape.getWorkflowElementRef();
if (wfElmRef != null) {
nodeGroup.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(viewportBounds.getWidth()).append(",")
.append(viewportBounds.getHeight());
nodeGroup.setAttribute("coordsize", coordSizeBuf.toString());
// 2、构造pool边框
Bounds rectBounds = figure.getBounds().copy();
int thick = rectBounds.getThick();
int newWidth = rectBounds.getWidth() - thick * 2;
int newHeight = rectBounds.getHeight() - thick * 2;
Element rect = document.createElement("v:rect");
StringBuffer rectStyle = (new StringBuffer())
.append("position:absolute;").append("left:").append(thick)
.append("px;").append("top:").append(thick).append("px;")
.append("width:").append(newWidth).append("px;")
.append("height:").append(newHeight).append("px;")
.append("z-index:-1;");
rect.setAttribute("style", rectStyle.toString());
nodeGroup.appendChild(rect);
Element line = document.createElement("v:line");
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
String from = thick + "," + POOL_LANE_TITLE_HEIGHT;
line.setAttribute("from", from);
String to = (thick + newWidth) + "," + POOL_LANE_TITLE_HEIGHT;
line.setAttribute("to", to);
} else {
String from = POOL_LANE_TITLE_HEIGHT + "," + thick;
line.setAttribute("from", from);
String to = POOL_LANE_TITLE_HEIGHT + "," + (thick + newHeight);
line.setAttribute("to", to);
}
nodeGroup.appendChild(line);
// 2.1画笔
if (rectBounds != null) {
Element stroke = document.createElement("v:stroke");
stroke.setAttribute("weight",
Integer.toString(thick < 0 ? 1 : thick) + "px");
String color = rectBounds.getColor();
stroke.setAttribute("color",
(color == null || color.trim().equals("")) ? "#000000"
: color);
String lineType = rectBounds.getLineType();
if (lineType == null || lineType.trim().equals("")) {
stroke.setAttribute("dashstyle", "solid");
} else if (Bounds.LINETYPE_DOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dot");
} else if (Bounds.LINETYPE_DASHED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dash");
} else if (Bounds.LINETYPE_DASHDOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dashdot");
}
Element stroke2 = (Element) stroke.cloneNode(true);
rect.appendChild(stroke);
line.appendChild(stroke2);
}
// 2.2填充
if (figure.getFulfilStyle() != null) {
String color1 = figure.getFulfilStyle().getColor1();
String color2 = figure.getFulfilStyle().getColor2();
String gradient = figure.getFulfilStyle().getGradientStyle();
Element fillStyle = document.createElement("v:fill");
if (gradient == null || gradient.trim().equals("")
|| FulfilStyle.GRADIENT_STYLE_NONE.equals(gradient)) {
fillStyle.setAttribute("type", "solid");
fillStyle.setAttribute("color", color2);
} else {
fillStyle.setAttribute("type", "gradient");
fillStyle.setAttribute("method", "linear");
fillStyle.setAttribute("color", color1);
fillStyle.setAttribute("color2", color2);
if (FulfilStyle.GRADIENT_STYLE_TOP2DOWN.equals(gradient)) {
fillStyle.setAttribute("angle", "180");// 上至下
} else if (FulfilStyle.GRADIENT_STYLE_UPPERLEFT2LOWERRIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "225");
} else if (FulfilStyle.GRADIENT_STYLE_UPPERRIGHT2LOWERLEFT
.equals(gradient)) {
fillStyle.setAttribute("angle", "135");
} else if (FulfilStyle.GRADIENT_STYLE_LEFT2RIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "270");// 从左到右
} else {
fillStyle.setAttribute("angle", "270");// 从左到右
}
}
rect.appendChild(fillStyle);
}
// 2.3 label的名称
String title = figure.getTitle();
if (title != null && !title.trim().equals("")) {
// 构造textbox
int paddingLeft = (thick);
Label titleLabel = figure.getTitleLabel().copy();
int fontSize = titleLabel.getFontSize();
;
int textRectHeight = (int) (fontSize + 2);// 设置一定的余量
int check = POOL_LANE_TITLE_HEIGHT - textRectHeight - thick;
int paddingTop = thick;
if (check > 0) {
paddingTop = thick + (int) (check / 2);
} else {
textRectHeight = POOL_LANE_TITLE_HEIGHT - thick;
}
// 纵向泳道
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
int width = rectBounds.getWidth() - paddingLeft * 2;// 一般而言,width不可能小于2倍thick
if (width < 0) {
width = 0;
}
Element textRect = this.buildVmlTextBox(nodeShape,
FPDLNames.POOL, paddingLeft, paddingTop, width,
textRectHeight, titleLabel, true, "center");
nodeGroup.appendChild(textRect);
} else {// 横向泳道
int height = rectBounds.getHeight() - paddingLeft * 2;
Element textRect = this.buildVmlTextBox(nodeShape,
FPDLNames.POOL, paddingTop, paddingLeft,
textRectHeight, height, titleLabel, true, "center",
"middle", false);
nodeGroup.appendChild(textRect);
}
}
if (isTopLevelElem) {
_refreshDiagramSize(viewportBounds);
}
// 3、构造子节点
List<DiagramElement> children = nodeShape.getChildren();
if (children != null && children.size() > 0) {
// 构造一个新的坐标系统
Element childrenGroup = document.createElement("v:group");
StringBuffer tmpStyle = new StringBuffer();
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
tmpStyle.append("position:absolute;")
.append("left:")
.append(thick)
.append("px;")
// 去掉边线的宽度
.append("top:")
.append(POOL_LANE_TITLE_HEIGHT)
.append("px;")
//
.append("width:")
.append(newWidth)
.append("px;")
.append("height:")
.append(rectBounds.getHeight() - GROUP_TITLE_HEIGHT
- thick).append("px");
} else {
tmpStyle.append("position:absolute;")
.append("left:")
.append(POOL_LANE_TITLE_HEIGHT)
.append("px;")
.append("top:")
.append(thick)
.append("px;")
.append("width:")
.append(rectBounds.getWidth() - POOL_LANE_TITLE_HEIGHT
- thick).append("px;").append("height:")
.append(newHeight).append("px");
}
childrenGroup.setAttribute("style", tmpStyle.toString());
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
StringBuffer coordSizeBufTmp = new StringBuffer();
coordSizeBufTmp
.append(newWidth)
.append(",")
.append(rectBounds.getHeight() - GROUP_TITLE_HEIGHT
- thick);
childrenGroup.setAttribute("coordsize",
coordSizeBufTmp.toString());
} else {
StringBuffer coordSizeBufTmp = new StringBuffer();
coordSizeBufTmp
.append(viewportBounds.getWidth()
- POOL_LANE_TITLE_HEIGHT - thick).append(",")
.append(newHeight);
childrenGroup.setAttribute("coordsize",
coordSizeBufTmp.toString());
}
int offset = 0;
int laneCount = children.size();
for (int index = 0; index < laneCount; index++) {
DiagramElement diagramElm = children.get(index);
if (diagramElm instanceof LaneShape) {
LaneShape laneShape = (LaneShape) diagramElm;
Element elm = this.transformLane2Vml(laneShape, offset,
index, laneCount);
if (elm != null) {
childrenGroup.appendChild(elm);
}
Rectangle rectTmp = (Rectangle) laneShape.getFigure();
Bounds tmpBounds = rectTmp.getBounds();
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
offset = offset + tmpBounds.getWidth();
} else {
offset = offset + tmpBounds.getHeight();
}
}
}
nodeGroup.appendChild(childrenGroup);
}
return nodeGroup;
}
private Element transformLane2Vml(LaneShape nodeShape, int offset,
int laneIndex, int laneCount) {
Bounds viewportBounds = _getViewPortBounds(nodeShape);
Rectangle figure = (Rectangle) nodeShape.getFigure();
Element nodeGroup = document.createElement("v:group");
StringBuffer groupStyle = new StringBuffer();
groupStyle.append("position:absolute;").append("width:")
.append(viewportBounds.getWidth()).append("px;")
.append("height:").append(viewportBounds.getHeight())
.append("px;");
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
groupStyle.append("left:").append(offset).append("px;")
.append("top:").append(0).append("px;");
} else {
groupStyle.append("left:").append(0).append("px;").append("top:")
.append(offset).append("px;");
}
nodeGroup.setAttribute("style", groupStyle.toString());
nodeGroup.setAttribute(FPDLNames.ID, nodeShape.getId());
nodeGroup.setAttribute(TYPE, FPDLNames.LANE);
ModelElement wfElmRef = nodeShape.getWorkflowElementRef();
if (wfElmRef != null) {
nodeGroup.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(viewportBounds.getWidth()).append(",")
.append(viewportBounds.getHeight());
nodeGroup.setAttribute("coordsize", coordSizeBuf.toString());
Bounds rectBounds = figure.getBounds().copy();
int thick = rectBounds.getThick();
int newWidth = rectBounds.getWidth() - thick * 2;
int newHeight = rectBounds.getHeight() - thick * 2;
String title = figure.getTitle();
// 画笔
Element stroke = null;
if (rectBounds != null) {
stroke = document.createElement("v:stroke");
stroke.setAttribute("weight",
Integer.toString(thick < 0 ? 1 : thick) + "px");
String color = rectBounds.getColor();
stroke.setAttribute("color",
(color == null || color.trim().equals("")) ? "#000000"
: color);
String lineType = rectBounds.getLineType();
if (lineType == null || lineType.trim().equals("")) {
stroke.setAttribute("dashstyle", "solid");
} else if (Bounds.LINETYPE_DOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dot");
} else if (Bounds.LINETYPE_DASHED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dash");
} else if (Bounds.LINETYPE_DASHDOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dashdot");
}
}
// lane边框
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
// 横线2
if (title != null && !title.trim().equals("")) {
Element line = document.createElement("v:line");
String from = thick + "," + POOL_LANE_TITLE_HEIGHT;
line.setAttribute("from", from);
String to = (thick + newWidth) + "," + POOL_LANE_TITLE_HEIGHT;
line.setAttribute("to", to);
if (stroke != null) {
Node tmpStroke = stroke.cloneNode(true);
line.appendChild(tmpStroke);
}
nodeGroup.appendChild(line);
}
// 竖线
if (laneIndex > 0) {
Element line = document.createElement("v:line");
String from = thick + "," + thick;
line.setAttribute("from", from);
String to = (thick + newHeight) + "," + (thick);
line.setAttribute("to", to);
if (stroke != null) {
Node tmpStroke = stroke.cloneNode(true);
line.appendChild(tmpStroke);
}
nodeGroup.appendChild(line);
}
} else {
// 竖线1
// 竖线2
if (title != null && !title.trim().equals("")) {
Element line = document.createElement("v:line");
String from = POOL_LANE_TITLE_HEIGHT + "," + thick;
line.setAttribute("from", from);
String to = POOL_LANE_TITLE_HEIGHT + "," + (thick + newHeight);
line.setAttribute("to", to);
if (stroke != null) {
Node tmpStroke = stroke.cloneNode(true);
line.appendChild(tmpStroke);
}
nodeGroup.appendChild(line);
}
// 横线
if (laneIndex > 0) {
Element line = document.createElement("v:line");
String from = thick + "," + thick;
line.setAttribute("from", from);
String to = (thick + newWidth) + "," + (thick);
line.setAttribute("to", to);
if (stroke != null) {
Node tmpStroke = stroke.cloneNode(true);
line.appendChild(tmpStroke);
}
nodeGroup.appendChild(line);
}
}
// 填充
Element rect = document.createElement("v:rect");
StringBuffer rectStyle = (new StringBuffer())
.append("position:absolute;").append("width:").append(newWidth)
.append("px;").append("height:").append(newHeight)
.append("px;").append("z-index:-1;");
rectStyle.append("left:").append(thick).append("px;").append("top:")
.append(thick).append("px;");
rect.setAttribute("style", rectStyle.toString());
rect.setAttribute("stroked", "false");
nodeGroup.appendChild(rect);
/* rect.appendChild(stroke); */
if (figure.getFulfilStyle() != null) {
String color1 = figure.getFulfilStyle().getColor1();
String color2 = figure.getFulfilStyle().getColor2();
String gradient = figure.getFulfilStyle().getGradientStyle();
Element fillStyle = document.createElement("v:fill");
if (gradient == null || gradient.trim().equals("")
|| FulfilStyle.GRADIENT_STYLE_NONE.equals(gradient)) {
fillStyle.setAttribute("type", "solid");
fillStyle.setAttribute("color", color2);
} else {
fillStyle.setAttribute("type", "gradient");
fillStyle.setAttribute("method", "linear");
fillStyle.setAttribute("color", color1);
fillStyle.setAttribute("color2", color2);
if (FulfilStyle.GRADIENT_STYLE_TOP2DOWN.equals(gradient)) {
fillStyle.setAttribute("angle", "180");// 上至下
} else if (FulfilStyle.GRADIENT_STYLE_UPPERLEFT2LOWERRIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "225");
} else if (FulfilStyle.GRADIENT_STYLE_UPPERRIGHT2LOWERLEFT
.equals(gradient)) {
fillStyle.setAttribute("angle", "135");
} else if (FulfilStyle.GRADIENT_STYLE_LEFT2RIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "270");// 从左到右
} else {
fillStyle.setAttribute("angle", "270");// 从左到右
}
}
rect.appendChild(fillStyle);
}
// label的名称
if (title != null && !title.trim().equals("")) {
int paddingLeft = (thick);
Label titleLabel = figure.getTitleLabel().copy();
int fontSize = titleLabel.getFontSize();
int textRectHeight = (int) (fontSize + 2);// 设置一定的余量
int check = POOL_LANE_TITLE_HEIGHT - textRectHeight - thick;
int paddingTop = thick;
if (check > 0) {
paddingTop = thick + (int) (check / 2);
} else {
textRectHeight = POOL_LANE_TITLE_HEIGHT - thick;
}
// 纵向泳道
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
int width = rectBounds.getWidth() - paddingLeft * 2;// 一般而言,width不可能小于2倍thick
if (width < 0) {
width = 0;
}
Element textRect = this.buildVmlTextBox(nodeShape,
FPDLNames.LANE, paddingLeft, paddingTop, width,
textRectHeight, titleLabel, true, "center");
nodeGroup.appendChild(textRect);
} else {// 横向泳道
int height = rectBounds.getHeight() - paddingLeft * 2;
Element textRect = this.buildVmlTextBox(nodeShape,
FPDLNames.LANE, paddingTop, paddingLeft,
textRectHeight, height, titleLabel, true, "center",
"middle", false);
nodeGroup.appendChild(textRect);
}
}
// 构造子节点
List<DiagramElement> children = nodeShape.getChildren();
if (children != null && children.size() > 0) {
// 构造一个新的坐标系统
Element childrenGroup = document.createElement("v:group");
StringBuffer tmpStyle = new StringBuffer();
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
tmpStyle.append("position:absolute;")
.append("left:")
.append(thick)
.append("px;")
.append("top:")
.append(POOL_LANE_TITLE_HEIGHT)
.append("px;")
.append("width:")
.append(rectBounds.getWidth() - thick * 2)
.append("px;")
.append("height:")
.append(rectBounds.getHeight() - POOL_LANE_TITLE_HEIGHT
- thick).append("px");
} else {
tmpStyle.append("position:absolute;")
.append("left:")
.append(POOL_LANE_TITLE_HEIGHT)
.append("px;")
.append("top:")
.append(thick)
.append("px;")
.append("width:")
.append(rectBounds.getWidth() - POOL_LANE_TITLE_HEIGHT
- thick).append("px;").append("height:")
.append(rectBounds.getHeight() - thick * 2)
.append("px");
}
childrenGroup.setAttribute("style", tmpStyle.toString());
if (Diagram.VERTICAL.equals(diagram.getDirection())) {
StringBuffer coordSizeBufTmp = new StringBuffer();
coordSizeBufTmp
.append(rectBounds.getWidth() - thick * 2)
.append(",")
.append(rectBounds.getHeight() - POOL_LANE_TITLE_HEIGHT
- thick);
childrenGroup.setAttribute("coordsize",
coordSizeBufTmp.toString());
} else {
StringBuffer coordSizeBufTmp = new StringBuffer();
coordSizeBufTmp
.append(rectBounds.getWidth() - POOL_LANE_TITLE_HEIGHT
- thick).append(",")
.append(rectBounds.getHeight() - thick * 2);
childrenGroup.setAttribute("coordsize",
coordSizeBufTmp.toString());
}
for (DiagramElement diagramElm : children) {
if (diagramElm instanceof ProcessNodeShape) {
Element elm = this.transformProcessNodeShape2Vml(
(ProcessNodeShape) diagramElm, false);
if (elm != null) {
childrenGroup.appendChild(elm);
}
} else if (diagramElm instanceof CommentShape) {
Element elm = this.transformCommentShape2Vml(
(CommentShape) diagramElm, false);
if (elm != null) {
childrenGroup.appendChild(elm);
}
} else if (diagram instanceof GroupShape) {
Element elm = this.transformGroupShape2Vml(
(GroupShape) diagram, false);
if (elm != null) {
childrenGroup.appendChild(elm);
}
}
}
nodeGroup.appendChild(childrenGroup);
}
return nodeGroup;
}
private Element transformGroupShape2Vml(GroupShape nodeShape,
boolean isTopLevelElem) {
// 1、构造viewport
Bounds viewportBounds = _getViewPortBounds(nodeShape);
Rectangle figure = (Rectangle) nodeShape.getFigure();
Element nodeGroup = document.createElement("v:group");
StringBuffer groupStyle = new StringBuffer();
groupStyle.append("position:absolute;").append("left:")
.append(viewportBounds.getX()).append("px;").append("top:")
.append(viewportBounds.getY()).append("px;").append("width:")
.append(viewportBounds.getWidth()).append("px;")
.append("height:").append(viewportBounds.getHeight())
.append("px");
nodeGroup.setAttribute("style", groupStyle.toString());
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(viewportBounds.getWidth()).append(",")
.append(viewportBounds.getHeight());
nodeGroup.setAttribute("coordsize", coordSizeBuf.toString());
nodeGroup.setAttribute(FPDLNames.ID, nodeShape.getId());
nodeGroup.setAttribute(TYPE, FPDLNames.GROUP);
ModelElement wfElmRef = nodeShape.getWorkflowElementRef();
if (wfElmRef != null) {
nodeGroup.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
// 2、Group边框
Bounds rectBounds = figure.getBounds().copy();
int thick = rectBounds.getThick();
Element rect = document.createElement("v:roundrect");
StringBuffer rectStyle = (new StringBuffer())
.append("position:absolute;").append("left:").append(thick)
.append("px;").append("top:").append(thick).append("px;")
.append("width:").append(rectBounds.getWidth() - thick * 2)
.append("px;").append("height:")
.append(rectBounds.getHeight() - thick * 2).append("px;")
.append("z-index:-1;");
rect.setAttribute("style", rectStyle.toString());
rect.setAttribute("arcsize", "9.0%");
nodeGroup.appendChild(rect);
// 2.1 画笔
if (rectBounds != null) {
Element stroke = document.createElement("v:stroke");
stroke.setAttribute("weight",
Integer.toString(thick < 0 ? 1 : thick) + "px");
String color = rectBounds.getColor();
stroke.setAttribute("color",
(color == null || color.trim().equals("")) ? "#000000"
: color);
String lineType = rectBounds.getLineType();
if (lineType == null || lineType.trim().equals("")) {
stroke.setAttribute("dashstyle", "solid");
} else if (Bounds.LINETYPE_DOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dot");
} else if (Bounds.LINETYPE_DASHED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dash");
} else if (Bounds.LINETYPE_DASHDOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dashdot");
}
rect.appendChild(stroke);
}
// 2.2 填充
if (figure.getFulfilStyle() != null) {
String color1 = figure.getFulfilStyle().getColor1();
String color2 = figure.getFulfilStyle().getColor2();
String gradient = figure.getFulfilStyle().getGradientStyle();
Element fillStyle = document.createElement("v:fill");
if (gradient == null || gradient.trim().equals("")
|| FulfilStyle.GRADIENT_STYLE_NONE.equals(gradient)) {
fillStyle.setAttribute("type", "solid");
fillStyle.setAttribute("color", color2);
} else {
fillStyle.setAttribute("type", "gradient");
fillStyle.setAttribute("method", "linear");
fillStyle.setAttribute("color", color1);
fillStyle.setAttribute("color2", color2);
if (FulfilStyle.GRADIENT_STYLE_TOP2DOWN.equals(gradient)) {
fillStyle.setAttribute("angle", "180");// 上至下
} else if (FulfilStyle.GRADIENT_STYLE_UPPERLEFT2LOWERRIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "225");
} else if (FulfilStyle.GRADIENT_STYLE_UPPERRIGHT2LOWERLEFT
.equals(gradient)) {
fillStyle.setAttribute("angle", "135");
} else if (FulfilStyle.GRADIENT_STYLE_LEFT2RIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "270");// 从左到右
} else {
fillStyle.setAttribute("angle", "270");// 从左到右
}
}
rect.appendChild(fillStyle);
}
// 2.3 label的名称
String title = figure.getTitle();
if (title != null && !title.trim().equals("")) {
// 构造textbox
int paddingLeft = thick;
Label titleLabel = figure.getTitleLabel();
int fontSize = titleLabel.getFontSize();
int width = rectBounds.getWidth() - paddingLeft * 2;// 一般而言,width不可能小于2倍thick
if (width < 0) {
width = 0;
}
int textRectHeight = (int) (fontSize + 2);// 设置一定的余量
int check = GROUP_TITLE_HEIGHT - textRectHeight - thick;
int paddingTop = thick;
int height = textRectHeight;
if (check > 0) {
paddingTop = thick + (int) (check / 2);
} else {
height = GROUP_TITLE_HEIGHT - thick;
}
Element textRect = this.buildVmlTextBox(nodeShape, FPDLNames.GROUP,
paddingLeft, paddingTop, width, height, titleLabel, true,
"center");
nodeGroup.appendChild(textRect);
}
if (isTopLevelElem) {
_refreshDiagramSize(viewportBounds);
}
// 3、构造子节点
List<DiagramElement> children = nodeShape.getChildren();
if (children != null && children.size() > 0) {
// 构造一个新的view port,该viewport应该和group边框匹配
Element childrenGroup = document.createElement("v:group");
StringBuffer tmpStyle = new StringBuffer();
tmpStyle.append("position:absolute;")
.append("left:")
.append(thick)
.append("px;")
.append("top:")
.append(GROUP_TITLE_HEIGHT)
.append("px;")
.append("width:")
.append(rectBounds.getWidth() - thick * 2)
.append("px;")
.append("height:")
.append(rectBounds.getHeight() - GROUP_TITLE_HEIGHT - thick)
.append("px");
childrenGroup.setAttribute("style", tmpStyle.toString());
StringBuffer coordSizeBufTmp = new StringBuffer();
coordSizeBufTmp
.append(rectBounds.getWidth() - thick * 2)
.append(",")
.append(rectBounds.getHeight() - GROUP_TITLE_HEIGHT - thick);
childrenGroup.setAttribute("coordsize", coordSizeBufTmp.toString());
for (DiagramElement diagramElm : children) {
if (diagramElm instanceof ProcessNodeShape) {
Element elm = this.transformProcessNodeShape2Vml(
(ProcessNodeShape) diagramElm, false);
if (elm != null) {
childrenGroup.appendChild(elm);
}
} else if (diagramElm instanceof CommentShape) {
Element elm = this.transformCommentShape2Vml(
(CommentShape) diagramElm, false);
if (elm != null) {
childrenGroup.appendChild(elm);
}
}
}
nodeGroup.appendChild(childrenGroup);
}
return nodeGroup;
}
private Element transformCommentShape2Vml(CommentShape commentShape,
boolean isTopLevelElm) {
// 1、构造view port
Bounds viewportBounds = _getViewPortBounds(commentShape);
Rectangle figure = (Rectangle) commentShape.getFigure();
Element nodeGroup = document.createElement("v:group");
StringBuffer groupStyle = new StringBuffer();
groupStyle.append("position:absolute;").append("left:")
.append(viewportBounds.getX()).append("px;").append("top:")
.append(viewportBounds.getY()).append("px;").append("width:")
.append(viewportBounds.getWidth()).append("px;")
.append("height:").append(viewportBounds.getHeight())
.append("px");
nodeGroup.setAttribute("style", groupStyle.toString());
nodeGroup.setAttribute(FPDLNames.ID, commentShape.getId());
nodeGroup.setAttribute(TYPE, FPDLNames.COMMENT);
ModelElement wfElmRef = commentShape.getWorkflowElementRef();
if (wfElmRef != null) {
nodeGroup.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(viewportBounds.getWidth()).append(",")
.append(viewportBounds.getHeight());
nodeGroup.setAttribute("coordsize", coordSizeBuf.toString());
// 2、Comment边框
Bounds rectBounds = figure.getBounds().copy();
int thick = rectBounds.getThick();
int newWidth = rectBounds.getWidth() - thick * 2;
int newHeight = rectBounds.getHeight() - thick * 2;
Element polyline = document.createElement("v:polyline");
StringBuffer pointList = new StringBuffer();
pointList.append((int) (rectBounds.getWidth() / 3)).append(",")
.append(0).append(" ").append(0).append(",").append(0)
.append(" ").append(0).append(",")
.append(rectBounds.getHeight()).append(" ")
.append((int) (rectBounds.getWidth() / 3)).append(",")
.append(rectBounds.getHeight());
polyline.setAttribute("points", pointList.toString());
polyline.setAttribute("filled", "f");
StringBuffer polyLineStyle = (new StringBuffer()).append(
"position:absolute;").append("z-index:-1;");
polyline.setAttribute("style", polyLineStyle.toString());
nodeGroup.appendChild(polyline);
/*
* Element borderRect = document.createElement("v:rect");
* borderRect.setAttribute("filled", "f"); StringBuffer polyLineStyle =
* (new StringBuffer()).append("position:absolute;")
* .append("top:").append(thick).append("px;")
* .append("left:").append(thick).append("px;")
* .append("width:").append(newWidth).append("px;")
* .append("height:").append(newHeight).append("px;")
* .append("z-index:-1;"); borderRect.setAttribute("style",
* polyLineStyle.toString()); nodeGroup.appendChild(borderRect);
*/
// 2.1边框画笔
if (figure.getBounds() != null) {
Element stroke = document.createElement("v:stroke");
stroke.setAttribute("weight",
Integer.toString(thick < 0 ? 1 : thick) + "px");
String color = rectBounds.getColor();
stroke.setAttribute("color",
(color == null || color.trim().equals("")) ? "#000000"
: color);
String lineType = rectBounds.getLineType();
if (lineType == null || lineType.trim().equals("")) {
stroke.setAttribute("dashstyle", "solid");
} else if (Bounds.LINETYPE_DOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dot");
} else if (Bounds.LINETYPE_DASHED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dash");
} else if (Bounds.LINETYPE_DASHDOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dashdot");
}
polyline.appendChild(stroke);
}
// 2.2 内容区域填充
Element contentBackground = document.createElement("v:rect");
StringBuffer rectStyle = (new StringBuffer())
.append("position:absolute;").append("left:").append(thick + 1)
.append("px;").append("top:").append(thick + 1).append("px;")
.append("width:").append(newWidth - 2).append("px;")
.append("height:").append(newHeight - 2).append("px;");
contentBackground.setAttribute("style", rectStyle.toString());
contentBackground.setAttribute("strokecolor", "white");
contentBackground.setAttribute("StrokeWeight", "1px");
nodeGroup.appendChild(contentBackground);
if (figure.getFulfilStyle() != null) {
String color1 = figure.getFulfilStyle().getColor1();
String color2 = figure.getFulfilStyle().getColor2();
String gradient = figure.getFulfilStyle().getGradientStyle();
Element fillStyle = document.createElement("v:fill");
if (gradient == null || gradient.trim().equals("")
|| FulfilStyle.GRADIENT_STYLE_NONE.equals(gradient)) {
fillStyle.setAttribute("type", "solid");
if (color2 == null || color2.trim().equals("")) {
color2 = "white";
}
fillStyle.setAttribute("color", color2);
} else {
fillStyle.setAttribute("type", "gradient");
fillStyle.setAttribute("method", "linear");
fillStyle.setAttribute("color", color1);
fillStyle.setAttribute("color2", color2);
if (FulfilStyle.GRADIENT_STYLE_TOP2DOWN.equals(gradient)) {
fillStyle.setAttribute("angle", "180");// 上至下
} else if (FulfilStyle.GRADIENT_STYLE_UPPERLEFT2LOWERRIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "225");
} else if (FulfilStyle.GRADIENT_STYLE_UPPERRIGHT2LOWERLEFT
.equals(gradient)) {
fillStyle.setAttribute("angle", "135");
} else if (FulfilStyle.GRADIENT_STYLE_LEFT2RIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "270");// 从左到右
} else {
fillStyle.setAttribute("angle", "270");// 从左到右
}
}
contentBackground.appendChild(fillStyle);
}
// comment的内容
String contentTxt = figure.getContent();
if (contentTxt != null && !contentTxt.trim().equals("")) {
// 构造textbox
int padding = 4;
int spacing = 0;
int textBoxPadding = (padding + thick);
Label contentLabel = figure.getContentLabel().copy();
Element textRect = this.drawCommentText(commentShape,
FPDLNames.COMMENT, textBoxPadding, textBoxPadding, newWidth
- textBoxPadding * 2, newHeight - textBoxPadding
* 2, contentLabel);
if (textRect != null) {
nodeGroup.appendChild(textRect);
}
}
if (isTopLevelElm) {
_refreshDiagramSize(viewportBounds);
}
return nodeGroup;
}
private Element transformConnectorShape2Vml(Element root,
ConnectorShape connectorShape) {
NodeShape fromNodeShape = connectorShape.getFromNode();
NodeShape toNodeShape = connectorShape.getToNode();
ModelElement wfElm = connectorShape.getWorkflowElementRef();
String wfElmId = wfElm == null ? "null" : wfElm.getId();
if (fromNodeShape == null || toNodeShape == null) {
log.warn("TransitionShape[Id=" + connectorShape.getId()
+ ",WfElemId=" + wfElmId
+ "]的 from_node或者to_node为空,无法绘制该连接线");
return null;
}
Bounds absoluteFromNodeBounds = this._getAbsoluteBounds(fromNodeShape);
Bounds absoluteToNodeBounds = this._getAbsoluteBounds(toNodeShape);
if (absoluteFromNodeBounds == null || absoluteToNodeBounds == null) {
log.warn("TransitionShape[Id=" + connectorShape.getId()
+ ",WfElemId=" + wfElmId
+ "]的 from_node或者to_node的bounds为空,无法绘制该连接线");
return null;
}
Line fireLine = (Line) connectorShape.getFigure();
List<Point> linePoints = fireLine.getPoints();
Point fromRefPoint = null;// from_anchor的参考点
Point toRefPoint = null;// to_anchor的参考点
if (linePoints == null || linePoints.size() == 0) {
fromRefPoint = new Point();
fromRefPoint.setX(absoluteToNodeBounds.getX()
+ absoluteToNodeBounds.getWidth() / 2);
fromRefPoint.setY(absoluteToNodeBounds.getY()
+ absoluteToNodeBounds.getHeight() / 2);
} else {
fromRefPoint = linePoints.get(0);
}
if (linePoints == null || linePoints.size() == 0) {
toRefPoint = new Point();
toRefPoint.setX(absoluteFromNodeBounds.getX()
+ absoluteFromNodeBounds.getWidth() / 2);
toRefPoint.setY(absoluteFromNodeBounds.getY()
+ absoluteFromNodeBounds.getHeight() / 2);
} else {
toRefPoint = linePoints.get(linePoints.size() - 1);
}
// 计算from_anchor
Point fromAnchor = null;
fromAnchor = _calculateAnchor(fromNodeShape, absoluteFromNodeBounds,
fromRefPoint);
// 计算to_anchor
Point toAnchor = null;
toAnchor = _calculateAnchor(toNodeShape, absoluteToNodeBounds,
toRefPoint);
// polyline
Element polylineElm = document.createElement("v:polyline");
polylineElm.setAttribute("style", "position:absolute");
polylineElm.setAttribute("points",
_makePointsSeq(fromAnchor.copy(), toAnchor.copy(), linePoints));
polylineElm.setAttribute("filled", "f");
String elementType = null;
polylineElm.setAttribute(FPDLNames.ID, connectorShape.getId());
if (connectorShape instanceof TransitionShape) {
elementType = FPDLNames.TRANSITION;
} else if (connectorShape instanceof MessageFlowShape) {
elementType = FPDLNames.MESSAGEFLOW;
} else if (connectorShape instanceof AssociationShape) {
elementType = FPDLNames.ASSOCIATION;
}
polylineElm.setAttribute(TYPE, elementType);
ModelElement wfElmRef = connectorShape.getWorkflowElementRef();
if (wfElmRef != null) {
polylineElm.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
// 画笔
Element strokeElm = document.createElement("v:stroke");
Bounds tmpBounds = fireLine.getBounds() ;
String color = "#000000";
color = tmpBounds.getColor();
color = (color == null || color.trim()
.equals("")) ? "#000000" : color;
if (connectorShape instanceof TransitionShape) {
strokeElm.setAttribute("EndArrow", "Block");
} else if (connectorShape instanceof MessageFlowShape) {
strokeElm.setAttribute("EndArrow", "Open");
//在前头画一个圆圈
Element startArrowElm = document.createElement("v:oval");
int tmpX = fromAnchor.getX()-4;
int tmpY = fromAnchor.getY()-4;
int tmpW = 8;
int tmpH = 8;
StringBuffer circleStyle = new StringBuffer();
circleStyle.append("left:").append(tmpX).append("px;")
.append("top:").append(tmpY).append("px;")
.append("width:").append(tmpW).append("px;")
.append("height:").append(tmpH).append("px;");
startArrowElm.setAttribute("style", circleStyle.toString());
startArrowElm.setAttribute("strokecolor", color);
startArrowElm.setAttribute("filled", "false");
root.appendChild(startArrowElm);
}
if (tmpBounds!= null) {
int thick = fireLine.getBounds().getThick();
strokeElm.setAttribute("weight",
Integer.toString(thick < 0 ? 1 : thick) + "px");
strokeElm.setAttribute("color", color);
String lineType = fireLine.getBounds().getLineType();
if (lineType == null || lineType.trim().equals("")) {
strokeElm.setAttribute("dashstyle", "solid");
} else if (Bounds.LINETYPE_DOTTED.equals(lineType)) {
strokeElm.setAttribute("dashstyle", "dot");
} else if (Bounds.LINETYPE_DASHED.equals(lineType)) {
strokeElm.setAttribute("dashstyle", "dash");
} else if (Bounds.LINETYPE_DASHDOTTED.equals(lineType)) {
strokeElm.setAttribute("dashstyle", "dashdot");
}
}
polylineElm.appendChild(strokeElm);
// 构造标题
Label lb = fireLine.getTitleLabel();
String displayName = null;
if (wfElm != null) {
displayName = wfElm.getDisplayName();
} else {
displayName = fireLine.getTitle();
}
if (displayName != null && !displayName.trim().equals("")) {
Point labelRelativePos = fireLine.getLabelPosition();
// labelAbsPos是label的中心点
Point labelAbsPos = _getLabelAbsolutePosition(fromAnchor.copy(),
toAnchor.copy(), linePoints, labelRelativePos);
Label titleLabel = null;
if (lb == null) {
titleLabel = new LabelImpl();
titleLabel.setFontSize(DEFAULT_FONT_SIZE);
} else {
titleLabel = lb.copy();
}
titleLabel.setText(displayName);
Dimension dimension = _calculateFontSize(titleLabel.getText(),
titleLabel.getFontSize());
labelAbsPos.setX(labelAbsPos.getX() - dimension.width / 2);
labelAbsPos.setY(labelAbsPos.getY() - dimension.height / 2);
Element textRect = this.buildVmlTextBox(connectorShape,
elementType, labelAbsPos.getX(), labelAbsPos.getY(),
dimension.width, dimension.height, titleLabel, true,
"center");
root.appendChild(textRect);
// 重设画布大小
Bounds boundsTmp = new BoundsImpl();
boundsTmp.setX(labelAbsPos.getX());
boundsTmp.setY(labelAbsPos.getY());
boundsTmp.setWidth(dimension.width);
boundsTmp.setHeight(dimension.height);
this._refreshDiagramSize(boundsTmp);
}
root.appendChild(polylineElm);
// 重设画布大小
List<Point> tmpList = new ArrayList<Point>();
tmpList.addAll(linePoints);
tmpList.add(fromAnchor);
tmpList.add(toAnchor);
_refreshDiagramSize(tmpList);
return polylineElm;
}
private Element transformProcessNodeShape2Vml(ProcessNodeShape nodeShape,
boolean isTopLevelElem) {
Element cell = null;
if (nodeShape instanceof StartNodeShape) {
cell = this.transformStartNodeShape2Vml((StartNodeShape) nodeShape,
isTopLevelElem);
}
else if (nodeShape instanceof EndNodeShape) {
cell = this.transformEndNodeShape2Vml((EndNodeShape) nodeShape,
isTopLevelElem);
} else if (nodeShape instanceof RouterShape) {
cell = this.transformRouterShape2Vml((RouterShape) nodeShape,
isTopLevelElem);
} else if (nodeShape instanceof ActivityShape) {
cell = this.transformActivityShape2Vml((ActivityShape) nodeShape,
true);
}
// ModelElement wfElm = nodeShape.getWorkflowElementRef();
return cell;
}
/**
*
* @param nodeShape
* @param isTopLevelElem
* @return
*/
private Element transformActivityShape2Vml(ActivityShape nodeShape,
boolean isTopLevelElem) {
Activity node = (Activity) nodeShape.getWorkflowElementRef();
String imgUri = _getActivityImgUri(node);
// 1、构造viewport
Bounds newportBounds = _getViewPortBounds(nodeShape);
Rectangle figure = (Rectangle) nodeShape.getFigure();
Element nodeGroup = document.createElement("v:group");
StringBuffer groupStyle = new StringBuffer();
groupStyle.append("position:absolute;").append("left:")
.append(newportBounds.getX()).append("px;").append("top:")
.append(newportBounds.getY()).append("px;").append("width:")
.append(newportBounds.getWidth()).append("px;")
.append("height:").append(newportBounds.getHeight())
.append("px");
nodeGroup.setAttribute("style", groupStyle.toString());
nodeGroup.setAttribute(FPDLNames.ID, nodeShape.getId());
nodeGroup.setAttribute(TYPE, FPDLNames.ACTIVITY);
ModelElement wfElmRef = nodeShape.getWorkflowElementRef();
if (wfElmRef != null) {
nodeGroup.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(newportBounds.getWidth()).append(",")
.append(newportBounds.getHeight());
nodeGroup.setAttribute("coordsize", coordSizeBuf.toString());
// 2、Activity边框
Bounds rectBounds = figure.getBounds().copy();
int thick = rectBounds.getThick();
int newWidth = rectBounds.getWidth() - thick;
int newHeight = rectBounds.getHeight() - thick;
Element rect = document.createElement("v:roundrect");
StringBuffer rectStyle = (new StringBuffer())
.append("position:absolute;").append("left:").append(thick / 2)
.append("px;").append("top:").append(thick / 2).append("px;")
.append("width:").append(newWidth).append("px;")
.append("height:").append(newHeight).append("px;")
.append("z-index:-1;");
rect.setAttribute("style", rectStyle.toString());
rect.setAttribute("arcsize", "7.0%");
nodeGroup.appendChild(rect);
// 2.1 画笔
if (figure.getBounds() != null) {
Element stroke = document.createElement("v:stroke");
stroke.setAttribute("weight",
Integer.toString(thick < 0 ? 1 : thick) + "px");
String color = rectBounds.getColor();
stroke.setAttribute("color",
(color == null || color.trim().equals("")) ? "#000000"
: color);
String lineType = rectBounds.getLineType();
if (lineType == null || lineType.trim().equals("")) {
stroke.setAttribute("dashstyle", "solid");
} else if (Bounds.LINETYPE_DOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dot");
} else if (Bounds.LINETYPE_DASHED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dash");
} else if (Bounds.LINETYPE_DASHDOTTED.equals(lineType)) {
stroke.setAttribute("dashstyle", "dashdot");
}
rect.appendChild(stroke);
}
// 2.2填充
if (figure.getFulfilStyle() != null) {
String color1 = figure.getFulfilStyle().getColor1();
String color2 = figure.getFulfilStyle().getColor2();
String gradient = figure.getFulfilStyle().getGradientStyle();
Element fillStyle = document.createElement("v:fill");
if (gradient == null || gradient.trim().equals("")
|| FulfilStyle.GRADIENT_STYLE_NONE.equals(gradient)) {
fillStyle.setAttribute("type", "solid");
fillStyle.setAttribute("color", color2);
} else {
fillStyle.setAttribute("type", "gradient");
fillStyle.setAttribute("method", "linear");
fillStyle.setAttribute("color", color1);
fillStyle.setAttribute("color2", color2);
if (FulfilStyle.GRADIENT_STYLE_TOP2DOWN.equals(gradient)) {
fillStyle.setAttribute("angle", "180");// 上至下
} else if (FulfilStyle.GRADIENT_STYLE_UPPERLEFT2LOWERRIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "225");
} else if (FulfilStyle.GRADIENT_STYLE_UPPERRIGHT2LOWERLEFT
.equals(gradient)) {
fillStyle.setAttribute("angle", "135");
} else if (FulfilStyle.GRADIENT_STYLE_LEFT2RIGHT
.equals(gradient)) {
fillStyle.setAttribute("angle", "270");// 从左到右
} else {
fillStyle.setAttribute("angle", "270");// 从左到右
}
}
rect.appendChild(fillStyle);
}
// 2.3 activity的名称
String displayName = node.getDisplayName();
if (displayName == null || displayName.trim().equals("")) {
displayName = node.getName();
}
int padding = 6;
int spacing = 5;
// 构造textbox
int textBoxPaddingY = (SVC_LOGO_RADIUS * 2 + padding + spacing);
int textBoxPaddingX = padding ;
Label contentLabel = null;
int fontSize = DEFAULT_FONT_SIZE;
if (figure.getContentLabel() != null) {
contentLabel = figure.getContentLabel().copy();
fontSize = contentLabel.getFontSize();
} else {
contentLabel = new LabelImpl();
contentLabel.setFontSize(fontSize);
}
contentLabel.setText(displayName);
Element textRect = this.drawActivityText(nodeShape, FPDLNames.ACTIVITY,
textBoxPaddingX, textBoxPaddingY, rectBounds.getWidth()
- textBoxPaddingX * 2, rectBounds.getHeight()
- textBoxPaddingY * 2, contentLabel);
if (textRect != null) {
nodeGroup.appendChild(textRect);
}
// 图形logo
if (imgUri != null) {
Element nodeImg = document.createElement("v:image");
StringBuffer imgStyle = new StringBuffer();
imgStyle.append("position:absolute;").append("left:")
.append(padding + thick).append("px;").append("top:")
.append(padding + thick).append("px;").append("width:")
.append(SVC_LOGO_RADIUS * 2).append("px;")
.append("height:").append(SVC_LOGO_RADIUS * 2).append("px");
nodeImg.setAttribute("style", imgStyle.toString());
nodeImg.setAttribute("src", this.resourcePathPrefix + imgUri);
nodeGroup.appendChild(nodeImg);
}
//构造attatched event node
List<DiagramElement> children = nodeShape.getChildren();
if (children!=null && children.size()>0){
//1、首先构造坐标系
int width = rectBounds.getWidth();
int height = IMG_RADIUS*2+DEFAULT_FONT_SIZE+IconTextGap;
Element attachedEvtSvg = document.createElement("v:group");
StringBuffer tmpStyle = new StringBuffer();
tmpStyle.append("position:absolute;")
.append("left:")
.append(0)
.append("px;")
.append("top:")
.append(rectBounds.getHeight()-IMG_RADIUS)
.append("px;")
.append("width:")
.append(width)
.append("px;")
.append("height:")
.append(height)
.append("px");
attachedEvtSvg.setAttribute("style", tmpStyle.toString());
attachedEvtSvg.setAttribute("coordsize",width+","+height);
nodeGroup.appendChild(attachedEvtSvg);
for (DiagramElement child : children){
Element elm = this.transformAttachedEvent2Vml((StartNodeShape)child);
attachedEvtSvg.appendChild(elm);
}
}
if (isTopLevelElem) {
_refreshDiagramSize(newportBounds);
}
return nodeGroup;
}
/**
*
* @param nodeShape
* @param isTopLevelElem
* @return
*/
private Element transformRouterShape2Vml(RouterShape nodeShape,
boolean isTopLevelElem) {
String imgUri = _getSynchronizerNodeImgUri(nodeShape);
Router node = (Router) nodeShape.getWorkflowElementRef();
// 计算start node group的大小以及位置
Bounds bounds = _getViewPortBounds(nodeShape);
Figure figure = nodeShape.getFigure();
Element nodeGroup = document.createElement("v:group");
StringBuffer groupStyle = new StringBuffer();
groupStyle.append("position:absolute;").append("left:")
.append(bounds.getX()).append("px;").append("top:")
.append(bounds.getY()).append("px;").append("width:")
.append(bounds.getWidth()).append("px;").append("height:")
.append(bounds.getHeight()).append("px");
nodeGroup.setAttribute("style", groupStyle.toString());
// id 等属性
nodeGroup.setAttribute(FPDLNames.ID, nodeShape.getId());
nodeGroup.setAttribute(TYPE, FPDLNames.ROUTER);
ModelElement wfElmRef = nodeShape.getWorkflowElementRef();
if (wfElmRef != null) {
nodeGroup.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(bounds.getWidth()).append(",")
.append(bounds.getHeight());
nodeGroup.setAttribute("coordsize", coordSizeBuf.toString());
Element nodeImg = document.createElement("v:image");
StringBuffer imgStyle = new StringBuffer();
imgStyle.append("position:absolute;").append("left:")
.append((bounds.getWidth() / 2 - IMG_RADIUS)).append("px;")
.append("top:").append(0).append("px;").append("width:")
.append(IMG_RADIUS * 2).append("px;").append("height:")
.append(IMG_RADIUS * 2).append("px");
nodeImg.setAttribute("style", imgStyle.toString());
nodeImg.setAttribute("src", this.resourcePathPrefix + imgUri);
nodeGroup.appendChild(nodeImg);
// 增加一个临时边框
// Element rect = document.createElement("v:rect");
// StringBuffer rectStyle = (new
// StringBuffer()).append("position:absolute;")
// .append("left:").append(0).append("px;")
// .append("top:").append(0).append("px;")
// .append("width:").append(bounds.getWidth()).append("px;")
// .append("height:").append(bounds.getHeight()).append("px");
// rect.setAttribute("style", rectStyle.toString());
// startNodeGroup.appendChild(rect);
String displayName = node.getDisplayName();
if (displayName != null && !displayName.trim().equals("")) {
Label titleLabel = null;
int fontSize = DEFAULT_FONT_SIZE;
if (figure.getTitleLabel() != null) {
titleLabel = figure.getTitleLabel().copy();
fontSize = titleLabel.getFontSize();
} else {
titleLabel = new LabelImpl();
titleLabel.setFontSize(fontSize);
}
titleLabel.setText(displayName);
Element textRect = this.buildVmlTextBox(nodeShape,
FPDLNames.ROUTER, 0, (IMG_RADIUS * 2 + IconTextGap),
bounds.getWidth(), (int) (fontSize * PT_2_PX_RATE),
titleLabel, true, "center");
nodeGroup.appendChild(textRect);
}
if (isTopLevelElem) {
_refreshDiagramSize(bounds);
}
return nodeGroup;
}
/**
*
* @param nodeShape
* @param isTopLevelElem
* @return
*/
private Element transformEndNodeShape2Vml(EndNodeShape nodeShape,
boolean isTopLevelElem) {
String imgUri = _getSynchronizerNodeImgUri(nodeShape);
EndNode node = (EndNode) nodeShape.getWorkflowElementRef();
// 计算start node group的大小以及位置
Bounds bounds = _getViewPortBounds(nodeShape);
Figure figure = nodeShape.getFigure();
Element nodeGroup = document.createElement("v:group");
StringBuffer groupStyle = new StringBuffer();
groupStyle.append("position:absolute;").append("left:")
.append(bounds.getX()).append("px;").append("top:")
.append(bounds.getY()).append("px;").append("width:")
.append(bounds.getWidth()).append("px;").append("height:")
.append(bounds.getHeight()).append("px");
nodeGroup.setAttribute("style", groupStyle.toString());
nodeGroup.setAttribute(FPDLNames.ID, nodeShape.getId());
nodeGroup.setAttribute(TYPE, FPDLNames.END_NODE);
ModelElement wfElmRef = nodeShape.getWorkflowElementRef();
if (wfElmRef != null) {
nodeGroup.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(bounds.getWidth()).append(",")
.append(bounds.getHeight());
nodeGroup.setAttribute("coordsize", coordSizeBuf.toString());
// 增加一个临时边框
// Element rect = document.createElement("v:rect");
// StringBuffer rectStyle = (new
// StringBuffer()).append("position:absolute;")
// .append("left:").append(0).append("px;")
// .append("top:").append(0).append("px;")
// .append("width:").append(bounds.getWidth()).append("px;")
// .append("height:").append(bounds.getHeight()).append("px");
// rect.setAttribute("style", rectStyle.toString());
// startNodeGroup.appendChild(rect);
Element nodeImg = document.createElement("v:image");
StringBuffer imgStyle = new StringBuffer();
imgStyle.append("position:absolute;").append("left:")
.append((bounds.getWidth() / 2 - IMG_RADIUS)).append("px;")
.append("top:").append(0).append("px;").append("width:")
.append(IMG_RADIUS * 2).append("px;").append("height:")
.append(IMG_RADIUS * 2).append("px");
nodeImg.setAttribute("style", imgStyle.toString());
nodeImg.setAttribute("src", this.resourcePathPrefix + imgUri);
nodeGroup.appendChild(nodeImg);
String displayName = node.getDisplayName();
if (displayName != null && !displayName.trim().equals("")) {
Label titleLabel = null;
int fontSize = DEFAULT_FONT_SIZE;
if (figure.getTitleLabel() != null) {
titleLabel = figure.getTitleLabel().copy();
fontSize = titleLabel.getFontSize();
} else {
titleLabel = new LabelImpl();
titleLabel.setFontSize(fontSize);
}
titleLabel.setText(displayName);
Element textRect = this.buildVmlTextBox(nodeShape,
FPDLNames.END_NODE, 0, (IMG_RADIUS * 2 + IconTextGap),
bounds.getWidth(), (int) (fontSize * PT_2_PX_RATE),
titleLabel, true, "center");
nodeGroup.appendChild(textRect);
}
if (isTopLevelElem) {
_refreshDiagramSize(bounds);
}
return nodeGroup;
}
private Element transformAttachedEvent2Vml(StartNodeShape startNodeShape){
String imgUri = _getSynchronizerNodeImgUri(startNodeShape);
StartNode startNode = (StartNode) startNodeShape
.getWorkflowElementRef();
// 计算start node group的大小以及位置
Figure figure = startNodeShape.getFigure();
Bounds bounds = figure.getBounds();
Element startNodeGroup = document.createElement("v:group");
StringBuffer groupStyle = new StringBuffer();
groupStyle.append("position:absolute;").append("left:")
.append(bounds.getX()).append("px;").append("top:")
.append(bounds.getY()).append("px;").append("width:")
.append(bounds.getWidth()).append("px;").append("height:")
.append(bounds.getHeight()).append("px");
startNodeGroup.setAttribute("style", groupStyle.toString());
// id 等属性
startNodeGroup.setAttribute(FPDLNames.ID, startNodeShape.getId());
startNodeGroup.setAttribute(TYPE, FPDLNames.START_NODE);
ModelElement wfElmRef = startNodeShape.getWorkflowElementRef();
if (wfElmRef != null) {
startNodeGroup.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(bounds.getWidth()).append(",")
.append(bounds.getHeight());
startNodeGroup.setAttribute("coordsize", coordSizeBuf.toString());
Element startNodeImg = document.createElement("v:image");
StringBuffer imgStyle = new StringBuffer();
imgStyle.append("position:absolute;").append("left:")
.append((bounds.getWidth() / 2 - IMG_RADIUS)).append("px;")
.append("top:").append(0).append("px;").append("width:")
.append(IMG_RADIUS * 2).append("px;").append("height:")
.append(IMG_RADIUS * 2).append("px");
startNodeImg.setAttribute("style", imgStyle.toString());
startNodeImg.setAttribute("src", this.resourcePathPrefix + imgUri);
startNodeGroup.appendChild(startNodeImg);
return startNodeGroup;
}
/**
*
* @param startNodeShape
* @param isTopLevelElem
* @return
*/
private Element transformStartNodeShape2Vml(StartNodeShape startNodeShape,
boolean isTopLevelElem) {
String imgUri = _getSynchronizerNodeImgUri(startNodeShape);
StartNode startNode = (StartNode) startNodeShape
.getWorkflowElementRef();
// 计算start node group的大小以及位置
Bounds bounds = _getViewPortBounds(startNodeShape);
Figure figure = startNodeShape.getFigure();
Element startNodeGroup = document.createElement("v:group");
StringBuffer groupStyle = new StringBuffer();
groupStyle.append("position:absolute;").append("left:")
.append(bounds.getX()).append("px;").append("top:")
.append(bounds.getY()).append("px;").append("width:")
.append(bounds.getWidth()).append("px;").append("height:")
.append(bounds.getHeight()).append("px");
startNodeGroup.setAttribute("style", groupStyle.toString());
// id 等属性
startNodeGroup.setAttribute(FPDLNames.ID, startNodeShape.getId());
startNodeGroup.setAttribute(TYPE, FPDLNames.START_NODE);
ModelElement wfElmRef = startNodeShape.getWorkflowElementRef();
if (wfElmRef != null) {
startNodeGroup.setAttribute(FPDLNames.REF, wfElmRef == null ? ""
: wfElmRef.getId());
}
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(bounds.getWidth()).append(",")
.append(bounds.getHeight());
startNodeGroup.setAttribute("coordsize", coordSizeBuf.toString());
Element startNodeImg = document.createElement("v:image");
StringBuffer imgStyle = new StringBuffer();
imgStyle.append("position:absolute;").append("left:")
.append((bounds.getWidth() / 2 - IMG_RADIUS)).append("px;")
.append("top:").append(0).append("px;").append("width:")
.append(IMG_RADIUS * 2).append("px;").append("height:")
.append(IMG_RADIUS * 2).append("px");
startNodeImg.setAttribute("style", imgStyle.toString());
startNodeImg.setAttribute("src", this.resourcePathPrefix + imgUri);
startNodeGroup.appendChild(startNodeImg);
String displayName = startNode.getDisplayName();
if (displayName != null && !displayName.trim().equals("")) {
Label titleLabel = null;
int fontSize = DEFAULT_FONT_SIZE;
if (figure.getTitleLabel() != null) {
titleLabel = figure.getTitleLabel().copy();
fontSize = titleLabel.getFontSize();
} else {
titleLabel = new LabelImpl();
titleLabel.setFontSize(fontSize);
}
titleLabel.setText(displayName);
Element textRect = this.buildVmlTextBox(startNodeShape,
FPDLNames.START_NODE, 0, (IMG_RADIUS * 2 + IconTextGap),
bounds.getWidth(), (int) (fontSize * PT_2_PX_RATE),
titleLabel, true, "center");
startNodeGroup.appendChild(textRect);
}
if (isTopLevelElem) {
_refreshDiagramSize(bounds);
}
return startNodeGroup;
}
private Element drawActivityText(DiagramElement diagramElement,
String elementType, int x, int y, int w, int h, Label label) {
Element result = null;
String text = label.getText();
if (text == null || text.trim().length() == 0) {
return null;
}
String fontColor = label.getFontColor();
// String fontFamily = "FangSong_GB2312";//mxUtils.getString(style,
// mxConstants.STYLE_FONTFAMILY, mxConstants.DEFAULT_FONTFAMILIES);
int fontSize = label.getFontSize();
String fireFontStyle = label.getFontStyle();
boolean isItalic = false;
if (Label.FONT_STYLE_ITALIC.equals(fireFontStyle)
|| Label.FONT_STYLE_ITALIC_BOLD.equals(fireFontStyle)) {
isItalic = true;
}
// int fontStyle = mxUtils.getInt(style, mxConstants.STYLE_FONTSTYLE);
String weight = "normal";
if (Label.FONT_STYLE_BOLD.equals(fireFontStyle)
|| Label.FONT_STYLE_ITALIC_BOLD.equals(fireFontStyle)) {
weight = "bold";
}
String uline = "none";
String fontStyle = label.getFontStyle();
if (fontStyle == null || fontStyle.trim().equals("")) {
fontStyle = Label.FONT_STYLE_NORMAL;
}
Element textBox = document.createElement("v:textbox");
StringBuffer textStyle = new StringBuffer();
textStyle.append("position:absolute;").append("left:").append(x)
.append("px;").append("top:").append(y).append("px;")
.append("width:").append(w).append("px;").append("height:")
.append(h).append("px;")
.append("font-size:").append(fontSize).append("px;")
.append("letter-spacing:").append("1px;")
// .append("word-wrap:").append("break-word;")
// .append("color:").append(fontColor).append(";")
;
// if (fontStyle.equals(Label.FONT_STYLE_BOLD)){
// textStyle.append("font-weight:").append("bold;");
// }else if (fontStyle.equals(Label.FONT_STYLE_ITALIC)){
// textStyle.append("font-style:").append("italic;");
// }else if (fontStyle.equals(Label.FONT_STYLE_ITALIC_BOLD)){
// textStyle.append("font-weight:").append("bold;");
// textStyle.append("font-style:").append("italic;");
// }
textBox.setAttribute("style", textStyle.toString());
textBox.setAttribute("inset", "0,0,0,0");
textBox.setAttribute("posLeft", Integer.toString(x));
textBox.setAttribute("posTop", Integer.toString(y));
textBox.setAttribute("pixelWidth", Integer.toString(w));
textBox.setAttribute("pixelHeight", Integer.toString(h));
textBox.setAttribute("fontSize", Integer.toString(fontSize));
Element textDiv = document.createElement("div");
textBox.appendChild(textDiv);
// textDiv.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
textDiv.setAttribute("onmouseover", "this.style.cursor='pointer';");
textDiv.setAttribute("onmouseout", "this.style.cursor='default';");
StringBuffer styleBufP = new StringBuffer();
//
styleBufP.append("width:100%;")//.append(w).append("px;")
.append("height:100%;")//.append(h).append("px;")
.append("text-align:center;word-wrap:break-word;");
// 行高 等于 fontSize+3像素
styleBufP.append("line-height:100%;");
styleBufP.append("font-weight:").append(weight).append(";")
//.append("font-size:").append(String.valueOf(fontSize))//font-size必须放在textBox的Style里面,使之能够放缩
.append("px;").append("color:").append(fontColor).append(";")
.append("text-decoration:none;");
if (isItalic) {
styleBufP.append("font-style:").append("italic").append(";");
}
textDiv.setAttribute("style", styleBufP.toString());
// 构造click handler,diagramId
StringBuffer clickHandler = new StringBuffer();
clickHandler.append("on_element_click(").append("'")
.append(diagramElement.getId()).append("',");
ModelElement wfElement = diagramElement.getWorkflowElementRef();
// 构造click handler wfElement Id
if (wfElement != null) {
clickHandler.append("'").append(wfElement.getId()).append("',");
} else {
clickHandler.append("'',");
}
// 构造click handler --element type
clickHandler.append("'").append(elementType).append("',");
// 构造click handler --process id
clickHandler.append("'").append(workflowProcess.getId()).append("',");
// 构造click handler --subprocess name
clickHandler.append("'").append(this.subProcessName).append("');");
textDiv.setAttribute("onclick", clickHandler.toString());
textDiv.appendChild(document.createTextNode(text));
result = textBox;
return result;
}
private Element drawCommentText(DiagramElement diagramElement,
String elementType, int x, int y, int w, int h, Label label) {
Element result = null;
String text = label.getText();
if (text == null || text.trim().length() == 0) {
return null;
}
String fontColor = label.getFontColor();
// String fontFamily = "FangSong_GB2312";//mxUtils.getString(style,
// mxConstants.STYLE_FONTFAMILY, mxConstants.DEFAULT_FONTFAMILIES);
int fontSize = label.getFontSize();
String fireFontStyle = label.getFontStyle();
boolean isItalic = false;
if (Label.FONT_STYLE_ITALIC.equals(fireFontStyle)
|| Label.FONT_STYLE_ITALIC_BOLD.equals(fireFontStyle)) {
isItalic = true;
}
// int fontStyle = mxUtils.getInt(style, mxConstants.STYLE_FONTSTYLE);
String weight = "normal";
if (Label.FONT_STYLE_BOLD.equals(fireFontStyle)
|| Label.FONT_STYLE_ITALIC_BOLD.equals(fireFontStyle)) {
weight = "bold";
}
String uline = "none";
String fontStyle = label.getFontStyle();
if (fontStyle == null || fontStyle.trim().equals("")) {
fontStyle = Label.FONT_STYLE_NORMAL;
}
Element textBox = document.createElement("v:textbox");
StringBuffer textStyle = new StringBuffer();
textStyle.append("position:absolute;").append("left:").append(x)
.append("px;").append("top:").append(y).append("px;")
.append("width:").append(w).append("px;").append("height:")
.append(h).append("px;")
.append("font-size:").append(fontSize).append("px;")
.append("letter-spacing:").append("1px;")
// .append("word-wrap:").append("break-word;")
// .append("color:").append(fontColor).append(";")
;
// if (fontStyle.equals(Label.FONT_STYLE_BOLD)){
// textStyle.append("font-weight:").append("bold;");
// }else if (fontStyle.equals(Label.FONT_STYLE_ITALIC)){
// textStyle.append("font-style:").append("italic;");
// }else if (fontStyle.equals(Label.FONT_STYLE_ITALIC_BOLD)){
// textStyle.append("font-weight:").append("bold;");
// textStyle.append("font-style:").append("italic;");
// }
textBox.setAttribute("style", textStyle.toString());
textBox.setAttribute("inset", "0,0,0,0");
textBox.setAttribute("posLeft", Integer.toString(x));
textBox.setAttribute("posTop", Integer.toString(y));
textBox.setAttribute("pixelWidth", Integer.toString(w));
textBox.setAttribute("pixelHeight", Integer.toString(h));
textBox.setAttribute("fontSize", Integer.toString(fontSize));
Element textDiv = document.createElement("div");
// textDiv.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
textBox.appendChild(textDiv);
StringBuffer styleBuf = new StringBuffer();
//
styleBuf.append("width:100%;")//.append(w).append("px;")
.append("height:100%;") //.append(h).append("px;")
.append("word-wrap:break-word;");
// 行高 等于 fontSize+3像素
styleBuf.append("line-height:100%;");
styleBuf.append("font-weight:").append(weight).append(";")
// .append("font-size:").append(String.valueOf(fontSize))//必须放在textBox的style中,使之能够被放缩
.append("px;").append("color:").append(fontColor).append(";");
if (isItalic) {
styleBuf.append("font-style:").append("italic").append(";");
}
textDiv.setAttribute("style", styleBuf.toString());
StringTokenizer tokenizer = new StringTokenizer(text, "\n", true);
while (tokenizer.hasMoreTokens()) {
String tmpStr = tokenizer.nextToken();
if (tmpStr.equals("\n")) {
Element brElm = document.createElement("br");
textDiv.appendChild(brElm);
} else {
Element pElem = document.createElement("span");
pElem.appendChild(document.createTextNode(tmpStr));
textDiv.appendChild(pElem);
}
}
result = textBox;
return result;
}
private Element buildVmlTextBox(DiagramElement diagramElement,
String elementType, int left, int top, int width, int height,
Label label, boolean createWrapperRect, String textAlign) {
return buildVmlTextBox(diagramElement, elementType, left, top, width,
height, label, createWrapperRect, textAlign, "middle", true);
}
private Element buildVmlTextBox(DiagramElement diagramElement,
String elementType, int left, int top, int width, int height,
Label label, boolean createWrapperRect, String textAlign,
String valign, boolean ishorizonal) {
int fontSize = label.getFontSize();
String fontColor = label.getFontColor();
String fontStyle = label.getFontStyle();
if (fontStyle == null || fontStyle.trim().equals("")) {
fontStyle = Label.FONT_STYLE_NORMAL;
}
Element textBox = document.createElement("v:textbox");
StringBuffer textStyle = new StringBuffer();
textStyle.append("position:absolute;").append("left:").append(left)
.append("px;").append("top:").append(top).append("px;")
.append("width:").append(width).append("px;").append("height:")
.append(height).append("px;").append("font-size:")
.append(fontSize).append("px;").append("letter-spacing:")
.append("1px;").append("word-wrap:").append("break-word;")
.append("color:").append(fontColor).append(";");
// .append("border:1 solid black;");//测试
// .append("text-align:").append(textAlign).append(";");//横向对齐
if (fontStyle.equals(Label.FONT_STYLE_BOLD)) {
textStyle.append("font-weight:").append("bold;");
} else if (fontStyle.equals(Label.FONT_STYLE_ITALIC)) {
textStyle.append("font-style:").append("italic;");
} else if (fontStyle.equals(Label.FONT_STYLE_ITALIC_BOLD)) {
textStyle.append("font-weight:").append("bold;");
textStyle.append("font-style:").append("italic;");
}
textBox.setAttribute("style", textStyle.toString());
textBox.setAttribute("inset", "0,0,0,0");
textBox.setAttribute("posLeft", Integer.toString(left));
textBox.setAttribute("posTop", Integer.toString(top));
textBox.setAttribute("pixelWidth", Integer.toString(width));
textBox.setAttribute("pixelHeight", Integer.toString(height));
textBox.setAttribute("fontSize", Integer.toString(fontSize));
Element textDiv = document.createElement("div");
if (ishorizonal) {
textDiv.setAttribute("style", "width:100%;height:100%;text-align:"
+ textAlign + ";");
} else {
textDiv.setAttribute("style",
"width:100%;height:100%;layout-flow:vertical-ideographic;text-align:"
+ textAlign + ";");
}
textBox.appendChild(textDiv);
Element textA = document.createElement("a");
textA.setAttribute("href", "#");
// 构造click handler,diagramId
StringBuffer clickHandler = new StringBuffer();
clickHandler.append("on_element_click(").append("'")
.append(diagramElement.getId()).append("',");
ModelElement wfElement = diagramElement.getWorkflowElementRef();
// 构造click handler wfElement Id
if (wfElement != null) {
clickHandler.append("'").append(wfElement.getId()).append("',");
} else {
clickHandler.append("'',");
}
// 构造click handler --element type
clickHandler.append("'").append(elementType).append("',");
// 构造click handler --process id
clickHandler.append("'").append(workflowProcess.getId()).append("',");
// 构造click handler --subprocess name
clickHandler.append("'").append(this.subProcessName).append("');");
textA.setAttribute("onclick", clickHandler.toString());
// 设置anchor的样式
StringBuffer anchorStyle = new StringBuffer();
anchorStyle.append("color:").append(fontColor).append(";")
.append("text-decoration:none;");
textA.setAttribute("style", anchorStyle.toString());
Text textNode = document.createTextNode(label.getText());
textA.appendChild(textNode);
textDiv.appendChild(textA);
if (createWrapperRect) {
Element textRect = document.createElement("v:rect");
StringBuffer textRectStyle = new StringBuffer();
textRectStyle.append("position:absolute;").append("width:")
.append(width).append("px;").append("height:")
.append(height).append("px;").append("left:").append(left)
.append("px;").append("top:").append(top).append("px;");
textRect.setAttribute("style", textRectStyle.toString());
textRect.setAttribute("filled", "f");
textRect.setAttribute("stroked", "f");
textRect.appendChild(textBox);
return textRect;
} else {
return textBox;
}
}
}