/*
* Copyright 2005-6 Pi4 Technologies Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* Change History:
* 14 Feb 2007 : Initial version created by gary
*/
package org.savara.tools.scenario.designer.view;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.views.properties.IPropertySource;
import org.savara.scenario.model.*;
import org.savara.tools.scenario.designer.DesignerImages;
import org.savara.tools.scenario.designer.model.*;
public class ViewSupport {
private static Logger logger = Logger.getLogger(ViewSupport.class.getName());
public static int TYPES_INITIAL_YPADDING=26;
public static final int EVENT_GROUP_PADDING_X=8;
public static final int EVENT_GROUP_PADDING_Y=35;
public static final int PARTICIPANT_PADDING_Y=10;
public static final int HEADER_HEIGHT=60;
public static final int PADDING_Y=10;
//public static final int SIDEBAR_WIDTH=300;
public static final int ROLE_PADDING_X=200;
public static IPropertySource getPropertySource(Object model) {
IPropertySource ret=null;
if (model instanceof Group) {
ret = new GroupPropertySource((Group)model);
} else if (model instanceof Import) {
ret = new ImportPropertySource((Import)model);
} else if (model instanceof Link) {
ret = new LinkPropertySource((Link)model);
} else if (model instanceof MessageEvent) {
ret = new MessageEventPropertySource((MessageEvent)model);
} else if (model instanceof Role) {
ret = new RolePropertySource((Role)model);
} else if (model instanceof Scenario) {
ret = new ScenarioPropertySource((Scenario)model);
} else if (model instanceof TimeElapsedEvent) {
ret = new TimeElapsedEventPropertySource((TimeElapsedEvent)model);
}
return(ret);
}
/**
* This method returns the appropriate image for this scenario
* component on the main display area.
*
* @param component The scenario component
* @return The image
*/
public static Image getImage(Object component, ScenarioDiagram diagram) {
Image ret=null;
String imageName=component.getClass().getName();
int index=imageName.lastIndexOf('.');
if (index != -1) {
imageName = imageName.substring(index+1);
}
if (imageName != null) {
try {
ret = DesignerImages.getImage(imageName+".png");
} catch(Exception e) {
logger.severe("Image for '"+imageName+
"' could not be found");
}
}
return(ret);
}
public static String getName(Object component, ScenarioDiagram diagram) {
String ret=null;
if (component instanceof Group) {
ret = ((Group)component).getName();
} else if (component instanceof Role) {
ret = ((Role)component).getName();
} else if (component instanceof Link) {
ret = getLinkText((Link)component);
}
if (ret == null) {
ret = "<unknown>";
}
return(ret);
}
protected static String getLinkText(Link link) {
String ret=null;
if (ret == null && link.getSource() != null) {
String operation=((MessageEvent)link.getSource()).getOperationName();
String faultName=((MessageEvent)link.getSource()).getFaultName();
String label="";
if (operation != null) {
label += operation;
}
if (((MessageEvent)link.getSource()).getParameter().size() > 0) {
label += "(";
for (int i=0; i < ((MessageEvent)link.getSource()).getParameter().size(); i++) {
if (i > 0) {
label += ",";
}
String type=QName.valueOf(((MessageEvent)link.getSource()).getParameter().get(i).getType()).getLocalPart();
label += type;
}
label += ")";
}
if (faultName != null && faultName.trim().length() > 0) {
String type=QName.valueOf(faultName).getLocalPart();
label += " fault "+type;
}
if (label.length() > 0) {
ret = label;
}
}
return(ret);
}
public static String getFullDescription(Object model) {
String ret=null;
/* TODO: GPB:
if (model instanceof ScenarioObject) {
ret = ((ScenarioObject)model).getDescription();
}
*/
return(ret);
}
/**
* This method sets the tooltip for the supplied figure,
* associated with the supplied model.
*
* @param figure The figure
* @param model The model
*/
public static void setTooltip(org.eclipse.draw2d.IFigure figure,
Object model) {
org.eclipse.draw2d.ScrollPane tooltip=new org.eclipse.draw2d.ScrollPane();
org.eclipse.draw2d.text.FlowPage page=new org.eclipse.draw2d.text.FlowPage();
tooltip.setContents(page);
String description=getFullDescription(model);
if (description != null) {
org.eclipse.draw2d.text.BlockFlow block1=new org.eclipse.draw2d.text.BlockFlow();
page.add(block1);
org.eclipse.draw2d.text.TextFlow text1=new org.eclipse.draw2d.text.TextFlow();
block1.add(text1);
text1.setText(description);
figure.setToolTip(tooltip);
}
}
public static int getHeight(Object component, ScenarioDiagram diagram) {
int ret=0;
java.util.List children=ModelSupport.getChildren(component);
if (children != null && children.size() > 0) {
ret += 40;
for (int i=0; i < children.size(); i++) {
ret += getHeight(children.get(i), diagram);
ret += getPadding(children, i); // padding
}
}
if (ret == 0) {
if (component instanceof org.savara.scenario.model.Group) {
ret = 70;
} else {
ret = 30;
}
}
if (component instanceof Scenario) {
ret += getHeaderPadding((Scenario)component, component);
ret += 40; // Additional padding
// If test scenario is less than 300 high, make
// it 300
if (ret < 300) {
ret = 300;
}
}
return(ret);
}
public static int getWidth(Object component, ScenarioDiagram diagram) {
int ret=0;
if (component instanceof Role) {
String name=((Role)component).getName();
if (name != null) {
ret = (int)(name.length()*6.5);
}
if (ret < 100) {
ret = 100;
} else if (ret > 180) {
ret = 180;
}
} else if (component instanceof TimeElapsedEvent) {
ret = getWidth(ModelSupport.getParent(diagram.getScenario(), component),
diagram);
ret -= 10;
} else {
java.util.List children=ModelSupport.getChildren(component);
boolean f_foundSubGroup = false;
if (children != null) {
for (int i=0; i < children.size(); i++) {
if (children.get(i) instanceof
org.savara.scenario.model.Group) {
int wid=getWidth(children.get(i), diagram);
if (ret < (wid+15)) {
ret = wid + 15; // added padding
}
f_foundSubGroup = true;
}
}
}
if (f_foundSubGroup == false) {
// Need to add width for participants
ret = getSidebarWidth(diagram)+
(diagram.getScenario().getRole().size()*
ROLE_PADDING_X-
(int)(ROLE_PADDING_X*0.6));
}
}
return(ret);
}
public static int getChildYPosition(Object parent, Object child,
ScenarioDiagram diagram) {
int ret=0;
if (child instanceof Role) {
ret = getHeaderPadding(diagram.getScenario(), child);
} else {
java.util.List children=ModelSupport.getChildren(parent);
if (children != null) {
int pos=children.indexOf(child);
ret = getHeaderPadding(diagram.getScenario(), parent);
if (pos > 0) {
for (int i=0; i < pos; i++) {
ret += getHeight(children.get(i), diagram);
ret += getPadding(children, i);
}
}
}
}
/*
if (parent instanceof Scenario) {
ret += getTopBorderHeight(diagram);
}
*/
return(ret);
}
/**
* This method determines how much padding should be included
* after the specified child index in the list of children.
*
* @param children The list of children
* @param index The index of the child prior to the padding
* @return The amount of padding
*/
public static int getPadding(java.util.List children,
int index) {
int ret=PADDING_Y;
if (index < children.size()-1) {
Object child1=children.get(index);
Object child2=children.get(index+1);
if (child1 instanceof org.savara.scenario.model.MessageEvent &&
child2 instanceof org.savara.scenario.model.MessageEvent) {
// Is there a message link between these children
/* TODO: GPB: need to get scenario
java.util.List links=
((org.savara.scenario.model.MessageEvent)child1).getScenario().getMessageLinks();
boolean f_found=false;
for (int i=0; f_found == false &&
i < links.size(); i++) {
org.savara.scenario.Link link=
(org.savara.scenario.Link)
links.get(i);
if ((link.getSource() == child1 &&
link.getTarget() == child2) ||
(link.getSource() == child2 &&
link.getTarget() == child1)) {
f_found = true;
}
}
if (f_found == false) {
ret = 0;
}
*/
} else {
ret = 10;
}
}
return(ret);
}
public static int getChildXPosition(Object parent, Object child,
ScenarioDiagram diagram) {
int ret=0;
if (child instanceof Role) {
int pos=diagram.getScenario().getRole().indexOf(child);
//int pos=diagram.getParticipantIndex((Participant)child);
if (pos != -1) {
ret = getSidebarWidth(diagram) + (pos * ROLE_PADDING_X);
} else {
ret = ROLE_PADDING_X;
}
} else if (child instanceof Group) {
// Return the default value
} else if (child instanceof TimeElapsedEvent) {
ret = 5;
} else if (child instanceof Import) {
ret = 5;
} else if (child instanceof RoleEvent) {
RoleEvent me=(RoleEvent)child;
Role participant=(Role)me.getRole();
if (participant != null) {
ret = getChildXPosition(null, participant, diagram);
// For each contained event group, we need to adjust
// the X position
Object cur=ModelSupport.getParent(diagram.getScenario(), me);
while (cur != null && (cur instanceof Scenario) == false) {
ret -= EVENT_GROUP_PADDING_X;
cur=ModelSupport.getParent(diagram.getScenario(), cur);
}
} else {
ret = 50;
}
}
return(ret);
}
public static int getNewParticipantIndex(int x,
ScenarioDiagram diagram) {
int start=getSidebarWidth(diagram) - ROLE_PADDING_X;
int pos=(x - start) / ROLE_PADDING_X;
return(pos);
}
public static int getNearestParticipantIndex(int x,
ScenarioDiagram diagram) {
int pos=(x - getSidebarWidth(diagram) + (ROLE_PADDING_X/2)) /
ROLE_PADDING_X;
return(pos);
}
public static Role getNearestRole(int x, ScenarioDiagram diagram) {
int pos=getNearestParticipantIndex(x, diagram);
Role ret=null;
java.util.List roles=diagram.getScenario().getRole();
if (roles.size() > 0) {
if (pos < 0) {
ret = (Role)roles.get(0);
} else if (pos >= roles.size()) {
ret = (Role)roles.get(roles.size()-1);
} else {
ret = (Role)roles.get(pos);
}
}
return(ret);
}
public static int getHeaderPadding(Scenario scenario, Object parent) {
int ret=EVENT_GROUP_PADDING_Y;
if (parent instanceof Scenario) {
ret = HEADER_HEIGHT;
ret += 30; // For the name in the header
if (((Scenario)parent).getAuthor() != null) {
ret += 30;
}
} else if (parent instanceof Role) {
ret = PARTICIPANT_PADDING_Y;
ret += 30; // For the name in the header
if (scenario.getAuthor() != null && scenario.getAuthor().trim().length() > 0) {
ret += 30;
}
}
return(ret);
}
/**
* This method calculates an appropriate width for the
* left hand side bar.
*
* @param diagram The diagram
* @return The width
*/
public static int getSidebarWidth(ScenarioDiagram diagram) {
// This can become dynamic, if necessary, based on the
// depth of the event groups
return(100);
}
}