mirror of
https://github.com/ProjectSWGCore/ConversationScriptCreator.git
synced 2026-01-16 23:05:01 -05:00
Added open option, Added delete option for nodes, General functionality changes
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -15,4 +15,6 @@ hs_err_pid*
|
||||
/build/
|
||||
/ConversationEditor/build/
|
||||
/dist/
|
||||
/nbproject/private/
|
||||
/nbproject/private/
|
||||
/ConversationEditor/nbproject/private/
|
||||
/ConversationCompiler/nbproject/private/
|
||||
@@ -45,14 +45,51 @@ public class ConversationConnectProvider implements ConnectProvider {
|
||||
JOptionPane.showMessageDialog(null, "Cannot attach end conversation node to responses/options!", "Conversation Script Creator", JOptionPane.INFORMATION_MESSAGE);
|
||||
return;
|
||||
}
|
||||
ConversationNode cSource = ((ConversationWidget) source).getAttachedNode();
|
||||
ConversationNode cTarget = ((ConversationWidget) target).getAttachedNode();
|
||||
|
||||
if (cSource.isOption()) {
|
||||
if (cTarget.isOption())
|
||||
return;
|
||||
|
||||
else if (cTarget.isStartNode())
|
||||
return;
|
||||
|
||||
} else if (cSource.isStartNode()) {
|
||||
if (cTarget.isEndNode())
|
||||
return;
|
||||
} else if (cSource.isEndNode()) {
|
||||
return;
|
||||
|
||||
} else { // Response nodes
|
||||
if (cTarget.isEndNode())
|
||||
return;
|
||||
|
||||
else if (cTarget.isStartNode())
|
||||
return;
|
||||
}
|
||||
|
||||
/* This won't work for preventing linking to same node 2x's. Need to find another way :(
|
||||
if (scene.getConnectionLayer().getChildren().size() > 0) {
|
||||
for (Widget widget : scene.getConnectionLayer().getChildren()) {
|
||||
System.out.println("CHILD: " + widget.toString());
|
||||
if (!(widget instanceof ConnectionWidget)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ConnectionWidget existingConn = (ConnectionWidget) widget;
|
||||
if (existingConn.getTargetAnchor().getRelatedWidget() == target) {
|
||||
System.out.println("SAME");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
ConnectionWidget conn = new ConnectionWidget(scene);
|
||||
conn.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
|
||||
conn.setTargetAnchor(AnchorFactory.createRectangularAnchor(target));
|
||||
conn.setSourceAnchor(AnchorFactory.createRectangularAnchor(source));
|
||||
scene.getConnectionLayer().addChild(conn);
|
||||
|
||||
((ConversationWidget)source).getAttachedNode().setCompiled(false);
|
||||
((ConversationWidget)target).getAttachedNode().setCompiled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.openide.nodes.Sheet;
|
||||
import org.openide.util.Lookup;
|
||||
|
||||
public class ConversationNode extends AbstractNode implements Lookup.Provider {
|
||||
private final int id;
|
||||
private int id;
|
||||
private int optionId;
|
||||
private String displayText;
|
||||
private String stf;
|
||||
@@ -24,10 +24,10 @@ public class ConversationNode extends AbstractNode implements Lookup.Provider {
|
||||
this.stf = stf;
|
||||
this.option = isOption;
|
||||
this.displayText = "";
|
||||
this.id = id;
|
||||
this.endNode = isEndNode;
|
||||
this.startNode = isStartNode;
|
||||
this.optionId = optionId;
|
||||
this.id = id;
|
||||
|
||||
// Properties Window
|
||||
if (!isStartNode)
|
||||
@@ -76,6 +76,10 @@ public class ConversationNode extends AbstractNode implements Lookup.Provider {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isCompiled() {
|
||||
return compiled;
|
||||
}
|
||||
|
||||
@@ -18,13 +18,14 @@ import org.openide.util.LookupListener;
|
||||
public class ConversationWidget extends IconNodeWidget implements LookupListener {
|
||||
private final ConversationNode attachedNode;
|
||||
private final ExplorerManager mgr;
|
||||
private boolean selected;
|
||||
|
||||
public ConversationWidget(SceneView scene, final ExplorerManager mgr, final ConversationNode node, boolean endConversation) {
|
||||
super(scene.getScene());
|
||||
|
||||
this.attachedNode = node;
|
||||
this.mgr = mgr;
|
||||
|
||||
|
||||
if (node.isEndNode()) {
|
||||
setLabel(node.getStf());
|
||||
setImage(ImageUtilities.loadImage("com/projectswg/tools/csc/conversationeditor/conversation_end.png"));
|
||||
@@ -50,10 +51,24 @@ public class ConversationWidget extends IconNodeWidget implements LookupListener
|
||||
public Point locationSuggested(Widget widget, Point originalLocation, Point suggestedLocation) {
|
||||
if (!(widget instanceof ConversationWidget))
|
||||
return suggestedLocation;
|
||||
ConversationWidget cWidget = (ConversationWidget) widget;
|
||||
ConversationNode node = cWidget.getAttachedNode();
|
||||
|
||||
if (((ConversationWidget) widget).getAttachedNode().isLocked())
|
||||
if (node.isLocked())
|
||||
return originalLocation;
|
||||
|
||||
if (cWidget.getExpManager().getRootContext() != node) {
|
||||
cWidget.getExpManager().setRootContext(node);
|
||||
|
||||
ConversationNode[] nodes = new ConversationNode[1];
|
||||
nodes[0] = node;
|
||||
try {
|
||||
cWidget.getExpManager().setSelectedNodes(nodes);
|
||||
} catch (PropertyVetoException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}
|
||||
}
|
||||
|
||||
return suggestedLocation;
|
||||
}
|
||||
}, ActionFactory.createDefaultMoveProvider()));
|
||||
@@ -98,6 +113,14 @@ public class ConversationWidget extends IconNodeWidget implements LookupListener
|
||||
return mgr;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
this.selected = selected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resultChanged(LookupEvent ev) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
|
||||
@@ -1,30 +1,26 @@
|
||||
package com.projectswg.tools.csc.conversationeditor;
|
||||
|
||||
import com.projectswg.tools.csc.conversationeditor.actions.SaveConversation;
|
||||
import java.awt.Point;
|
||||
import java.io.IOException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import com.projectswg.tools.csc.conversationeditor.actions.OpenConversation;
|
||||
import java.io.File;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.netbeans.api.settings.ConvertAsProperties;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.explorer.ExplorerUtils;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.TopComponent;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@ConvertAsProperties(
|
||||
dtd = "-//com.projectswg.tools.csc.conversationeditor//Editor//EN",
|
||||
autostore = false
|
||||
autostore = true
|
||||
)
|
||||
@TopComponent.Description(
|
||||
preferredID = "EditorTopComponent",
|
||||
//iconBase="SET/PATH/TO/ICON/HERE",
|
||||
persistenceType = TopComponent.PERSISTENCE_ALWAYS
|
||||
)
|
||||
@TopComponent.Registration(mode = "editor", openAtStartup = true)
|
||||
@TopComponent.Registration(mode = "editor", openAtStartup = false)
|
||||
@ActionID(category = "Window", id = "com.projectswg.tools.csc.conversationeditor.EditorTopComponent")
|
||||
@ActionReference(path = "Menu/Window" /*, position = 333 */)
|
||||
@TopComponent.OpenActionRegistration(
|
||||
@@ -40,41 +36,21 @@ public final class EditorTopComponent extends TopComponent implements ExplorerMa
|
||||
|
||||
private final ExplorerManager mgr = new ExplorerManager();
|
||||
private final SceneView scene;
|
||||
private String activePath = "";
|
||||
|
||||
// New Conversation
|
||||
public EditorTopComponent() {
|
||||
initComponents();
|
||||
|
||||
setToolTipText(Bundle.HINT_EditorTopComponent());
|
||||
|
||||
SceneView scene = new SceneView(mgr);
|
||||
scrollPane.setViewportView(scene.createView());
|
||||
|
||||
setName(Bundle.CTL_EditorTopComponent() + " - *New Conversation*");
|
||||
setName("*New Conversation*");
|
||||
|
||||
scene.addNode(new ConversationNode("Begin Conversation", false, 0, false, true, 0));
|
||||
scene.addNode(new ConversationNode("End Conversation", false, 1, true, false, 0));
|
||||
|
||||
this.scene = new SceneView(mgr);
|
||||
scrollPane.setViewportView(scene.createView());
|
||||
associateLookup(ExplorerUtils.createLookup(mgr, getActionMap()));
|
||||
this.scene = scene;
|
||||
|
||||
}
|
||||
|
||||
// Open Conversation
|
||||
public EditorTopComponent(String convName) {
|
||||
initComponents();
|
||||
|
||||
setToolTipText(Bundle.HINT_EditorTopComponent());
|
||||
|
||||
SceneView scene = new SceneView(mgr);
|
||||
scene.setSceneName(convName);
|
||||
|
||||
scrollPane.setViewportView(scene.createView());
|
||||
|
||||
setName(Bundle.CTL_EditorTopComponent() + " - " + (scene.getSceneName().equals("") ? "*New Conversation*" : scene.getSceneName()));
|
||||
|
||||
associateLookup(ExplorerUtils.createLookup(mgr, getActionMap()));
|
||||
this.scene = scene;
|
||||
}
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
@@ -100,30 +76,40 @@ public final class EditorTopComponent extends TopComponent implements ExplorerMa
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JScrollPane scrollPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
public void componentOpened() {
|
||||
// TODO add custom code on component opening
|
||||
if (activePath.equals("")) {
|
||||
// blankSlate();
|
||||
// scene.validate();
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(activePath);
|
||||
|
||||
if (!file.exists()) {
|
||||
JOptionPane.showMessageDialog(null, "Couldn't open conversation file " + file.getAbsolutePath()
|
||||
+ " because it no longer exists.", "Conversation Script Editor", JOptionPane.INFORMATION_MESSAGE);
|
||||
blankSlate();
|
||||
scene.validate();
|
||||
} else {
|
||||
OpenConversation.open(file, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentClosed() {
|
||||
/*try {
|
||||
SaveConversation.save(scene);
|
||||
} catch (ParserConfigurationException | IOException | SAXException | TransformerException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}*/
|
||||
// TODO: save msg
|
||||
}
|
||||
|
||||
void writeProperties(java.util.Properties p) {
|
||||
// better to version settings since initial version as advocated at
|
||||
// http://wiki.apidesign.org/wiki/PropertyFiles
|
||||
p.setProperty("version", "1.0");
|
||||
// TODO store your settings
|
||||
//p.setProperty("version", "1.0");
|
||||
p.setProperty("activePath", scene.getScenePath());
|
||||
}
|
||||
|
||||
void readProperties(java.util.Properties p) {
|
||||
String version = p.getProperty("version");
|
||||
// TODO read your settings according to their version
|
||||
//String version = p.getProperty("version");
|
||||
this.activePath = p.getProperty("activePath");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,4 +120,9 @@ public final class EditorTopComponent extends TopComponent implements ExplorerMa
|
||||
public SceneView getScene() {
|
||||
return scene;
|
||||
}
|
||||
|
||||
public void blankSlate() {
|
||||
scene.addNode(new ConversationNode("Begin Conversation", false, 0, false, true, 0));
|
||||
scene.addNode(new ConversationNode("End Conversation", false, 1, true, false, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@ package com.projectswg.tools.csc.conversationeditor;
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.netbeans.api.visual.graph.GraphScene;
|
||||
import org.netbeans.api.visual.anchor.AnchorFactory;
|
||||
import org.netbeans.api.visual.anchor.AnchorShape;
|
||||
import org.netbeans.api.visual.widget.ConnectionWidget;
|
||||
import org.netbeans.api.visual.widget.Widget;
|
||||
import org.w3c.dom.Attr;
|
||||
@@ -27,7 +28,7 @@ public class SceneSaver {
|
||||
private static final String NODEID_ATTR = "nodeID"; // NOI18N
|
||||
private static final String X_NODE = "posX"; // NOI18N
|
||||
private static final String Y_NODE = "posY"; // NOI18N
|
||||
private static final String SOURCE = "source";
|
||||
private static final String TARGETS = "targets";
|
||||
private static final String LOCKED = "locked";
|
||||
private static final String STF = "stf";
|
||||
private static final String OPTION_ID = "optionId";
|
||||
@@ -41,7 +42,8 @@ public class SceneSaver {
|
||||
Node properties = file.createElement("Properties");
|
||||
root.appendChild(properties);
|
||||
|
||||
setTextProperty(properties, file, "name", scene.getSceneName());
|
||||
setTextProperty(properties, file, "zoom", Double.toString(scene.getZoomFactor()));
|
||||
setTextProperty(properties, file, "highestId", String.valueOf(scene.getNextId()));
|
||||
|
||||
Node sceneXMLNode = file.createElement(NODE_ELEMENT);
|
||||
root.appendChild(sceneXMLNode);
|
||||
@@ -49,7 +51,7 @@ public class SceneSaver {
|
||||
setAttribute(file, sceneXMLNode, VERSION_ATTR, VERSION_VALUE_1); // NOI18N
|
||||
|
||||
LinkedHashMap<ConversationNode, ArrayList<ConversationNode>> conversationLinks = scene.getConversationLinks();
|
||||
|
||||
|
||||
for (ConversationNode node : scene.getNodes ()) {
|
||||
Widget widget = scene.findWidget(node);
|
||||
if (widget != null) {
|
||||
@@ -66,8 +68,7 @@ public class SceneSaver {
|
||||
else
|
||||
setAttribute(file, dataXMLNode, TYPE, "begin");
|
||||
|
||||
if (!node.isStartNode())
|
||||
setAttribute(file, dataXMLNode, SOURCE, String.valueOf(getSourceNode(conversationLinks, node).getId()));
|
||||
setAttribute(file, dataXMLNode, TARGETS, getTargets(conversationLinks, node));
|
||||
|
||||
setAttribute(file, dataXMLNode, NODEID_ATTR, String.valueOf(node.getId()));
|
||||
setAttribute(file, dataXMLNode, X_NODE, Integer.toString(location.x));
|
||||
@@ -83,24 +84,19 @@ public class SceneSaver {
|
||||
return root;
|
||||
}
|
||||
|
||||
private ConversationNode getSourceNode(LinkedHashMap<ConversationNode, ArrayList<ConversationNode>> conversationLinks, ConversationNode lookNode) {
|
||||
for (Map.Entry<ConversationNode, ArrayList<ConversationNode>> entry : conversationLinks.entrySet()) {
|
||||
if (entry.getValue().contains(lookNode))
|
||||
return entry.getKey();
|
||||
private String getTargets(LinkedHashMap<ConversationNode, ArrayList<ConversationNode>> conversationLinks, ConversationNode source) {
|
||||
String targets = "";
|
||||
if (!conversationLinks.containsKey(source)) {
|
||||
return targets;
|
||||
}
|
||||
return null;
|
||||
|
||||
for (ConversationNode nodes : conversationLinks.get(source)) {
|
||||
targets += (targets.equals("") ? String.valueOf(nodes.getId()) : "," + String.valueOf(nodes.getId()));
|
||||
}
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
private ConversationNode getTargetNode(LinkedHashMap<ConversationNode, ArrayList<ConversationNode>> conversationLinks, ConversationNode lookNode) {
|
||||
for (Map.Entry<ConversationNode, ArrayList<ConversationNode>> entry : conversationLinks.entrySet()) {
|
||||
if (entry.getValue().contains(lookNode))
|
||||
return entry.getValue().get(entry.getValue().indexOf(lookNode));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns true if deserialization is successfull
|
||||
// sceneXMLNode has to be found in the XML file first
|
||||
public boolean deserializeData(final SceneView scene, final Node sceneXMLNode) {
|
||||
if (!VERSION_VALUE_1.equals(getAttributeValue(sceneXMLNode, VERSION_ATTR)))
|
||||
return false;
|
||||
@@ -108,7 +104,7 @@ public class SceneSaver {
|
||||
SwingUtilities.invokeLater (new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
deserializeDataVersion1(scene, sceneXMLNode);
|
||||
deserializeNodeDataVersion1(scene, sceneXMLNode);
|
||||
scene.validate ();
|
||||
}
|
||||
});
|
||||
@@ -116,19 +112,86 @@ public class SceneSaver {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void deserializeDataVersion1(SceneView scene, Node data) {
|
||||
public void deserializeProperties(SceneView scene, Node node) {
|
||||
System.out.println("Got a node!" + node.getNodeType());
|
||||
Element properties = (Element) node;
|
||||
scene.setId(Integer.valueOf(properties.getElementsByTagName("highestId").item(0).getTextContent()));
|
||||
}
|
||||
|
||||
private void deserializeNodeDataVersion1(SceneView scene, Node data) {
|
||||
HashMap<Integer, ArrayList<Integer>> widgetLinks = new HashMap<>(); // map of what this widget id targets
|
||||
HashMap<Integer, ConversationWidget> widgets = new HashMap<>(); // map of all loaded widget's K = id, V = widget
|
||||
|
||||
for (Node node : getChildNode (data)) {
|
||||
if(NODE_NODE.equals(node.getNodeName())) {
|
||||
String nodeID = getAttributeValue(node, NODEID_ATTR);
|
||||
|
||||
int nodeID = Integer.parseInt(getAttributeValue(node, NODEID_ATTR));
|
||||
int x = Integer.parseInt(getAttributeValue (node, X_NODE));
|
||||
int y = Integer.parseInt(getAttributeValue (node, Y_NODE));
|
||||
Widget widget = scene.findWidget(nodeID);
|
||||
if (widget != null)
|
||||
int optionId = Integer.parseInt(getAttributeValue(node, OPTION_ID));
|
||||
|
||||
boolean locked = Boolean.parseBoolean(getAttributeValue(node, LOCKED));
|
||||
|
||||
String targets = getAttributeValue(node, TARGETS);
|
||||
String stf = getAttributeValue(node, STF);
|
||||
String type = getAttributeValue(node, TYPE);
|
||||
|
||||
ConversationWidget widget = null;
|
||||
// ConversationNode(String stf, boolean isOption, int id, boolean isEndNode, boolean isStartNode, int optionId)
|
||||
switch (type) {
|
||||
case "option":
|
||||
widget = (ConversationWidget) scene.addNode(new ConversationNode(stf, true, nodeID, false, false, optionId));
|
||||
break;
|
||||
case "response":
|
||||
widget = (ConversationWidget) scene.addNode(new ConversationNode(stf, false, nodeID, false, false, optionId));
|
||||
break;
|
||||
case "begin":
|
||||
widget = (ConversationWidget) scene.addNode(new ConversationNode(stf, false, nodeID, false, true, optionId));
|
||||
break;
|
||||
case "end":
|
||||
widget = (ConversationWidget) scene.addNode(new ConversationNode(stf, false, nodeID, true, false, optionId));
|
||||
break;
|
||||
}
|
||||
|
||||
if (widget != null) {
|
||||
widget.getAttachedNode().setLocked(locked);
|
||||
widget.setPreferredLocation (new Point (x, y));
|
||||
widgets.put(nodeID, widget);
|
||||
|
||||
if (!targets.equals("")) {
|
||||
ArrayList<Integer> targetIds = new ArrayList<>();
|
||||
if (targets.contains(",")) {
|
||||
String[] split = targets.split(",");
|
||||
for (String s : split) {
|
||||
targetIds.add(Integer.valueOf(s));
|
||||
}
|
||||
} else {
|
||||
targetIds.add(Integer.valueOf(targets));
|
||||
}
|
||||
widgetLinks.put(nodeID, targetIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
createConnections(widgetLinks, widgets, scene);
|
||||
}
|
||||
|
||||
private void createConnections(HashMap<Integer, ArrayList<Integer>> links, HashMap<Integer, ConversationWidget> widgets, SceneView scene) {
|
||||
for (Map.Entry<Integer, ArrayList<Integer>> entry : links.entrySet()) {
|
||||
//System.out.println("Creating links for " + widgets.get(entry.getKey()).getAttachedNode().getStf());
|
||||
for (Integer targetId : entry.getValue()) {
|
||||
|
||||
ConnectionWidget conn = new ConnectionWidget(scene);
|
||||
conn.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
|
||||
|
||||
conn.setTargetAnchor(AnchorFactory.createRectangularAnchor(widgets.get(targetId)));
|
||||
conn.setSourceAnchor(AnchorFactory.createRectangularAnchor(widgets.get(entry.getKey())));
|
||||
|
||||
scene.getConnectionLayer().addChild(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getAttributeValue(Node node, String attr) {
|
||||
try {
|
||||
if (node != null) {
|
||||
@@ -164,5 +227,5 @@ public class SceneSaver {
|
||||
for (int i = 0; i < nodes.length; i++)
|
||||
nodes[i] = childNodes.item (i);
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.netbeans.api.visual.action.ActionFactory;
|
||||
import org.netbeans.api.visual.graph.GraphScene;
|
||||
@@ -23,6 +22,9 @@ public class SceneView extends GraphScene<ConversationNode, String>{
|
||||
private final ExplorerManager mgr;
|
||||
|
||||
private String name = "";
|
||||
private String scenePath = "";
|
||||
|
||||
private int id = 1;
|
||||
|
||||
public SceneView(ExplorerManager mgr) {
|
||||
setLookFeel(new ConversationLookFeel());
|
||||
@@ -44,6 +46,7 @@ public class SceneView extends GraphScene<ConversationNode, String>{
|
||||
|
||||
@Override
|
||||
protected Widget attachNodeWidget(ConversationNode n) {
|
||||
|
||||
final ConversationWidget widget = new ConversationWidget(this, mgr, n, n.isEndNode());
|
||||
widget.getActions().addAction(createObjectHoverAction());
|
||||
|
||||
@@ -106,6 +109,27 @@ public class SceneView extends GraphScene<ConversationNode, String>{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getScenePath() {
|
||||
return this.scenePath;
|
||||
}
|
||||
|
||||
public void setScenePath(String path) {
|
||||
this.scenePath = path;
|
||||
}
|
||||
|
||||
public ExplorerManager getManager() {
|
||||
return mgr;
|
||||
}
|
||||
|
||||
public int getNextId() {
|
||||
this.id = id +1;
|
||||
return id++;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public LinkedHashMap<ConversationNode, ArrayList<ConversationNode>> getConversationLinks() {
|
||||
List<Widget> connectedNodes = connectionLayer.getChildren();
|
||||
LinkedHashMap<ConversationNode, ArrayList<ConversationNode>> conversationLinks = new LinkedHashMap<>();
|
||||
|
||||
@@ -44,7 +44,7 @@ public final class NewConvEnd implements ActionListener {
|
||||
if (scene == null)
|
||||
return;
|
||||
|
||||
int id = scene.getNodes().size();
|
||||
int id = scene.getNextId();
|
||||
scene.addNode(new ConversationNode("New End Conversation " + String.valueOf(id), false, id, true, false, 0));
|
||||
|
||||
scene.validate();
|
||||
|
||||
@@ -39,7 +39,7 @@ public final class NewConvOption implements ActionListener {
|
||||
if (scene == null)
|
||||
return;
|
||||
|
||||
int id = scene.getNodes().size();
|
||||
int id = scene.getNextId();
|
||||
scene.addNode(new ConversationNode("New Conversation Option " + String.valueOf(id), true, id, false, false, 0));
|
||||
|
||||
scene.validate();
|
||||
|
||||
@@ -44,7 +44,7 @@ public final class NewConvResponse implements ActionListener {
|
||||
if (scene == null)
|
||||
return;
|
||||
|
||||
int id = scene.getNodes().size();
|
||||
int id = scene.getNextId();
|
||||
scene.addNode(new ConversationNode("New Conversation Response " + String.valueOf(id), false, id, false, false, 0));
|
||||
scene.validate();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ public final class NewConversation implements ActionListener {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
EditorTopComponent newEditor = new EditorTopComponent();
|
||||
newEditor.blankSlate();
|
||||
newEditor.getScene().validate();
|
||||
newEditor.open();
|
||||
newEditor.requestActive();
|
||||
}
|
||||
|
||||
@@ -1,22 +1,34 @@
|
||||
package com.projectswg.tools.csc.conversationeditor.actions;
|
||||
|
||||
import com.projectswg.tools.csc.conversationeditor.EditorTopComponent;
|
||||
import com.projectswg.tools.csc.conversationeditor.SceneSaver;
|
||||
import com.projectswg.tools.csc.conversationeditor.SceneView;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionReferences;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.filesystems.FileChooserBuilder;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@ActionID(category = "File", id = "org.mycore.OpenFileAction")
|
||||
@ActionRegistration(displayName = "Open Conversation")
|
||||
@ActionRegistration(displayName = "Open")
|
||||
@ActionReferences({
|
||||
@ActionReference(path = "Menu/File", position = 10, separatorAfter = 11),
|
||||
@ActionReference(path = "Shortcuts", name = "D-O")
|
||||
})
|
||||
@Messages("CTL_OpenFileAction=Open Conversation")
|
||||
@Messages("CTL_OpenFileAction=Open")
|
||||
public final class OpenConversation implements ActionListener {
|
||||
|
||||
@Override
|
||||
@@ -28,8 +40,50 @@ public final class OpenConversation implements ActionListener {
|
||||
setDefaultWorkingDirectory(home).setApproveText("Open").showOpenDialog();
|
||||
//Result will be null if the user clicked cancel or closed the dialog w/o OK
|
||||
if (toAdd != null) {
|
||||
// TODO:
|
||||
EditorTopComponent editor = new EditorTopComponent();
|
||||
open(toAdd, editor);
|
||||
editor.open();
|
||||
editor.requestActive();
|
||||
}
|
||||
}
|
||||
|
||||
public static void open(File openFile, EditorTopComponent editor) {
|
||||
try {
|
||||
if (!openFile.getName().endsWith(".xml")) {
|
||||
System.out.println("Not a valid Conversation Editor file!");
|
||||
return;
|
||||
}
|
||||
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
Document doc = dBuilder.parse(openFile);
|
||||
doc.getDocumentElement().normalize();
|
||||
|
||||
if (!doc.getDocumentElement().getNodeName().equals("Conversation")) {
|
||||
System.out.println("Not a valid Conversation Editor file!");
|
||||
return;
|
||||
}
|
||||
|
||||
SceneSaver saver = new SceneSaver();
|
||||
|
||||
SceneView scene = editor.getScene();
|
||||
|
||||
Node propertiesNode = doc.getElementsByTagName("Properties").item(0);
|
||||
saver.deserializeProperties(scene, propertiesNode);
|
||||
|
||||
Node sceneNode = doc.getElementsByTagName("SceneView").item(0);
|
||||
if (sceneNode == null) {
|
||||
System.out.println("NULL SCENE");
|
||||
return;
|
||||
}
|
||||
scene.setSceneName(openFile.getName().split(".xml")[0]);
|
||||
scene.setScenePath(openFile.getAbsolutePath());
|
||||
|
||||
saver.deserializeData(scene, sceneNode);
|
||||
editor.setName(scene.getSceneName());
|
||||
|
||||
} catch (ParserConfigurationException | SAXException | IOException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@@ -32,7 +34,6 @@ import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.TopComponent;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@@ -42,14 +43,14 @@ import org.xml.sax.SAXException;
|
||||
)
|
||||
@ActionRegistration(
|
||||
iconBase = "com/projectswg/tools/csc/conversationeditor/actions/conversation_tb_save.png",
|
||||
displayName = "Save Conversation"
|
||||
displayName = "Save"
|
||||
)
|
||||
@ActionReferences({
|
||||
@ActionReference(path = "Menu/File", position = -90, separatorBefore = -140),
|
||||
@ActionReference(path = "Toolbars/File", position = 500),
|
||||
@ActionReference(path = "Shortcuts", name = "D-S")
|
||||
})
|
||||
@Messages("CTL_SaveConversation=Save Conversation")
|
||||
@Messages("CTL_SaveConversation=Save")
|
||||
public final class SaveConversation implements ActionListener {
|
||||
|
||||
@Override
|
||||
@@ -58,43 +59,55 @@ public final class SaveConversation implements ActionListener {
|
||||
if (component == null || !(component instanceof EditorTopComponent))
|
||||
return;
|
||||
|
||||
EditorTopComponent editor = (EditorTopComponent) component;
|
||||
final EditorTopComponent editor = (EditorTopComponent) component;
|
||||
final SceneView scene = editor.getScene();
|
||||
|
||||
if (scene == null)
|
||||
return;
|
||||
|
||||
if (scene.getSceneName().equals("")) {
|
||||
File home = new File(System.getProperty("user.home"));
|
||||
File existingFile = null;
|
||||
|
||||
if (!scene.getScenePath().equals(""))
|
||||
existingFile = new File(scene.getScenePath());
|
||||
|
||||
if (existingFile == null || !existingFile.exists()) {
|
||||
saveAs(scene, editor);
|
||||
} else {
|
||||
final String path = existingFile.getAbsolutePath();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
FileChooserBuilder builder = new FileChooserBuilder("user-dir").setTitle("Save Conversation").setDefaultWorkingDirectory(home).setApproveText("Save");
|
||||
builder.setAcceptAllFileFilterUsed(true);
|
||||
|
||||
final File file = builder.showSaveDialog();
|
||||
|
||||
if (file != null) {
|
||||
scene.setSceneName(file.getName().split(".xml")[0]);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
save(scene, file.getAbsolutePath());
|
||||
} catch (ParserConfigurationException | IOException | SAXException | TransformerException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
handleSave(scene, editor, path);
|
||||
} catch (ParserConfigurationException | IOException | SAXException | TransformerException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}
|
||||
});
|
||||
editor.setName("Conversation Editor - " + scene.getSceneName());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void save(SceneView scene, String path) throws ParserConfigurationException, IOException, SAXException, TransformerConfigurationException, TransformerException {
|
||||
public static void handleSave(final SceneView scene, final EditorTopComponent editor, String path)
|
||||
throws ParserConfigurationException, IOException, SAXException, TransformerConfigurationException, TransformerException {
|
||||
SceneSaver saver = new SceneSaver();
|
||||
|
||||
File xmlFile = new File(path + ".xml");
|
||||
if (!xmlFile.exists())
|
||||
if (!path.endsWith(".xml"))
|
||||
path = path + ".xml";
|
||||
|
||||
File xmlFile = new File(path);
|
||||
if (!scene.getScenePath().equals(path) && xmlFile.exists()) {
|
||||
int result = JOptionPane.showConfirmDialog(null, "This file already exists. Do you wish to overwrite it?",
|
||||
"Conversation Script Creator", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||
if (result == JOptionPane.YES_OPTION) {
|
||||
PrintWriter writer = new PrintWriter(xmlFile);
|
||||
writer.print("");
|
||||
writer.flush();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
xmlFile.createNewFile();
|
||||
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
@@ -109,9 +122,38 @@ public final class SaveConversation implements ActionListener {
|
||||
|
||||
DOMSource source = new DOMSource(document);
|
||||
StreamResult result = new StreamResult(xmlFile);
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
|
||||
transformer.transform(source, result);
|
||||
|
||||
if (!scene.getSceneName().equals(xmlFile.getName().split(".xml")[0]))
|
||||
scene.setSceneName(xmlFile.getName().split(".xml")[0]);
|
||||
|
||||
scene.setScenePath(xmlFile.getAbsolutePath());
|
||||
editor.setName(scene.getSceneName());
|
||||
}
|
||||
|
||||
public static void saveAs(final SceneView scene, final EditorTopComponent editor) {
|
||||
File home = new File(System.getProperty("user.home"));
|
||||
|
||||
FileChooserBuilder builder = new FileChooserBuilder("user-dir").setTitle("Save Conversation").setDefaultWorkingDirectory(home).setApproveText("Save");
|
||||
builder.setAcceptAllFileFilterUsed(true);
|
||||
|
||||
final File file = builder.showSaveDialog();
|
||||
|
||||
if (file != null) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
handleSave(scene, editor, file.getAbsolutePath());
|
||||
} catch (ParserConfigurationException | IOException | SAXException | TransformerException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.projectswg.tools.csc.conversationeditor.actions;
|
||||
|
||||
import com.projectswg.tools.csc.conversationeditor.ConversationNode;
|
||||
import com.projectswg.tools.csc.conversationeditor.ConversationWidget;
|
||||
import com.projectswg.tools.csc.conversationeditor.EditorTopComponent;
|
||||
import com.projectswg.tools.csc.conversationeditor.SceneView;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.netbeans.api.visual.widget.ConnectionWidget;
|
||||
import org.netbeans.api.visual.widget.Widget;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionReferences;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.TopComponent;
|
||||
|
||||
@ActionID(
|
||||
category = "Edit",
|
||||
id = "com.projectswg.tools.csc.conversationeditor.actions.TrashConvNode"
|
||||
)
|
||||
@ActionRegistration(
|
||||
iconBase = "com/projectswg/tools/csc/conversationeditor/actions/conversation_tb_trash.png",
|
||||
displayName = "Trash Node"
|
||||
)
|
||||
@ActionReferences({
|
||||
@ActionReference(path = "Menu/Edit", position = 1475),
|
||||
@ActionReference(path = "Toolbars/Edit", position = 450),
|
||||
@ActionReference(path = "Shortcuts", name = "DELETE")
|
||||
})
|
||||
@Messages("CTL_TrashConvNode=Trash Node")
|
||||
public final class TrashConvNode implements ActionListener {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
TopComponent component = TopComponent.getRegistry().getActivated();
|
||||
if (component == null || !(component instanceof EditorTopComponent))
|
||||
return;
|
||||
|
||||
final EditorTopComponent editor = (EditorTopComponent) component;
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
trashActiveNodes(editor);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static void trashActiveNodes(final EditorTopComponent editor) {
|
||||
SceneView scene = editor.getScene();
|
||||
|
||||
if (scene == null)
|
||||
return;
|
||||
|
||||
Node[] selectedNodes = scene.getManager().getSelectedNodes();
|
||||
|
||||
HashMap<ConversationWidget, ConversationNode> widgets = new HashMap<>();
|
||||
|
||||
// Get the nodes widgets & remove from scene
|
||||
for (Node n : selectedNodes) {
|
||||
ConversationWidget found = (ConversationWidget) scene.findWidget(n);
|
||||
if (found == null) {
|
||||
System.err.println("COULDNT FIND WIDGET TO REMOVE");
|
||||
return;
|
||||
}
|
||||
widgets.put(found, (ConversationNode) n);
|
||||
found.removeFromParent();
|
||||
}
|
||||
|
||||
// Remove connections for the node
|
||||
ArrayList<Widget> connections = new ArrayList<>();
|
||||
|
||||
for (Widget child : scene.getConnectionLayer().getChildren()) {
|
||||
if (!(child instanceof ConnectionWidget))
|
||||
continue;
|
||||
|
||||
ConnectionWidget connection = (ConnectionWidget) child;
|
||||
if (widgets.containsKey((ConversationWidget) connection.getTargetAnchor().getRelatedWidget())) {
|
||||
connections.add(child);
|
||||
}
|
||||
|
||||
if (widgets.containsKey((ConversationWidget) connection.getSourceAnchor().getRelatedWidget())) {
|
||||
connections.add(child);
|
||||
}
|
||||
}
|
||||
|
||||
scene.getConnectionLayer().removeChildren(connections);
|
||||
|
||||
for (Node n : selectedNodes) {
|
||||
scene.removeNode((ConversationNode) n);
|
||||
}
|
||||
scene.validate();
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -19,6 +19,18 @@
|
||||
<folder name="Edit">
|
||||
<file name="Separator1.instance_hidden"/>
|
||||
<file name="Separator2.instance_hidden"/>
|
||||
<file name="SeparatorAfterFindPrevious.instance_hidden"/>
|
||||
<file name="SeparatorAfterProjectsSearch.instance_hidden"/>
|
||||
<file name="WhereUsedAction.shadow_hidden"/>
|
||||
<file name="clipboard-history.shadow_hidden"/>
|
||||
<file name="org-netbeans-modules-editor-MainMenuAction$FindNextAction.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-editor-MainMenuAction$FindPreviousAction.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-editor-MainMenuAction$FindSelectionAction.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-editor-MainMenuAction$PasteFormattedAction.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-editor-MainMenuAction$SelectAllAction.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-editor-MainMenuAction$SelectIdentifierAction.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-editor-MainMenuAction$StartMacroRecordingAction.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-editor-MainMenuAction$StopMacroRecordingAction.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-search-FindInFilesAction-separatorBefore.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-search-FindInFilesAction.shadow_hidden"/>
|
||||
<file name="org-netbeans-modules-search-ReplaceInFilesAction.shadow_hidden"/>
|
||||
@@ -66,21 +78,37 @@
|
||||
<file name="RunProject_hidden"/>
|
||||
<file name="Source_hidden"/>
|
||||
<folder name="Tools">
|
||||
<file name="CloudManagerAction3.shadow_hidden"/>
|
||||
<file name="LibrariesCustomizerAction.shadow_hidden"/>
|
||||
<file name="PaletteManager_hidden"/>
|
||||
<file name="Separator1.instance_hidden"/>
|
||||
<file name="Separator2.instance_hidden"/>
|
||||
<file name="ServerManagerAction3.shadow_hidden"/>
|
||||
<file name="VariablesCustomizerAction.shadow_hidden"/>
|
||||
<file name="org-netbeans-modules-autoupdate-ui-actions-PluginManagerAction.shadow_hidden"/>
|
||||
<file name="org-netbeans-modules-options-OptionsWindowAction-separatorBefore.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-templates-actions-TemplatesAction.shadow_hidden"/>
|
||||
<file name="org-netbeans-modules-xml-catalog-CatalogAction.shadow_hidden"/>
|
||||
<file name="org-openide-actions-ToolsAction.shadow_hidden"/>
|
||||
</folder>
|
||||
<file name="Versioning_hidden"/>
|
||||
<folder name="View">
|
||||
<file name="Separator1.instance_hidden"/>
|
||||
<file name="Separator2.instance_hidden"/>
|
||||
<file name="Separator3.instance_hidden"/>
|
||||
<file name="org-netbeans-core-actions-LogAction.shadow_hidden"/>
|
||||
<file name="org-netbeans-core-multiview-EditorsAction.instance_hidden"/>
|
||||
<file name="org-netbeans-core-multiview-SplitAction.instance_hidden"/>
|
||||
<file name="org-netbeans-core-windows-actions-ToolbarsListAction.shadow_hidden"/>
|
||||
<file name="org-netbeans-modules-editor-NbCodeFoldingAction.instance_hidden"/>
|
||||
<file name="org-netbeans-modules-project-ui-SyncEditorWithViewsAction.shadow_hidden"/>
|
||||
<file name="org-netbeans-modules-versioning-core-ShowTextAnnotationsAction.shadow_hidden"/>
|
||||
<file name="org-netbeans-modules-versioning-ui-diff-ShowDiffSidebarAction.shadow_hidden"/>
|
||||
<file name="toggle-breadcrumbs-view.shadow_hidden"/>
|
||||
<file name="toggle-line-numbers.shadow_hidden"/>
|
||||
<file name="toggle-lines-view.shadow_hidden"/>
|
||||
<file name="toggle-non-printable-characters.shadow_hidden"/>
|
||||
<file name="toggle-toolbar.shadow_hidden"/>
|
||||
</folder>
|
||||
<folder name="Window">
|
||||
<file name="CloseAllButThisAction.shadow_hidden"/>
|
||||
|
||||
Reference in New Issue
Block a user