Files
ATCS/src/com/gpl/rpg/atcontentstudio/model/maps/Worldmap.java
Zukero bd8576df0c v0.5.4 released! Keyword is data-protection. Many small bugfixes, but
main changes are:
- Modified marker (* character before name) goes up the project tree by
marking all parents of a modified object as modified.
- Impact management when changing an object's ID. Allows for some
refactoring to occur, while marking the impacted elements as modified,
or aven creating "altered" versions if imapcted element was only in game
source.
2017-04-07 10:01:31 +02:00

290 lines
8.2 KiB
Java

package com.gpl.rpg.atcontentstudio.model.maps;
import java.awt.Image;
import java.awt.Point;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.tree.TreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class Worldmap extends ArrayList<WorldmapSegment> implements ProjectTreeNode {
private static final long serialVersionUID = 4590409256594556179L;
public static final String DEFAULT_REL_PATH_IN_SOURCE = "res/xml/worldmap.xml";
public static final String DEFAULT_REL_PATH_IN_PROJECT = "maps"+File.separator+"worldmap.xml";
public File worldmapFile;
public GameSource parent;
public Map<String, Map<String, Point>> segments = new LinkedHashMap<String, Map<String,Point>>();
public Worldmap(GameSource gameSource) {
this.parent = gameSource;
if (getDataType() == Type.source) {
worldmapFile = new File(parent.baseFolder, DEFAULT_REL_PATH_IN_SOURCE);
} else {
worldmapFile = new File(parent.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
}
if (worldmapFile.exists()) {
loadFromFile(worldmapFile);
}
if (getDataType() == Type.source) {
for (WorldmapSegment segment : this) {
segment.writable = false;
}
} else {
for (WorldmapSegment segment : this) {
segment.writable = true;
}
}
}
private void loadFromFile(File file) {
if (!file.exists()) return;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc;
try {
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource insrc = new InputSource(new FileInputStream(file));
insrc.setSystemId("http://worldmap/");
insrc.setEncoding("UTF-8");
doc = builder.parse(insrc);
Element root = (Element) doc.getElementsByTagName("worldmap").item(0);
if (root != null) {
NodeList segmentsList = root.getElementsByTagName("segment");
if (segmentsList != null) {
for (int i = 0; i < segmentsList.getLength(); i++) {
Element segmentNode = (Element) segmentsList.item(i);
String name = segmentNode.getAttribute("id");
add(new WorldmapSegment(this, name, segmentNode));
}
}
}
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public Enumeration<WorldmapSegment> children() {
return Collections.enumeration(this);
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return get(arg0);
}
@Override
public int getChildCount() {
return size();
}
@Override
public int getIndex(TreeNode arg0) {
return indexOf(arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.getChildCount() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "")+"Worldmap";
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return DefaultIcons.getMapClosedIcon();
}
@Override
public Image getLeafIcon() {
return null;
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getMapClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getMapOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
public void save() {
try {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
doc.setXmlVersion("1.0");
Element root = doc.createElement("worldmap");
doc.appendChild(root);
for (WorldmapSegment segment : this) {
root.appendChild(segment.toXmlElement(doc));
}
saveDocToFile(doc, worldmapFile);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public WorldmapSegment getWorldmapSegment(String id) {
for (WorldmapSegment s : this) {
if (s.id.equals(id)) {
return s;
}
}
return null;
}
public void addSegment(WorldmapSegment node) {
ProjectTreeNode higherEmptyParent = this;
while (higherEmptyParent != null) {
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode)higherEmptyParent.getParent()).isEmpty()) higherEmptyParent = (ProjectTreeNode)higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
add(node);
node.parent = this;
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
}
public static void saveDocToFile(Document doc, File f) {
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
Result output = new StreamResult(new FileOutputStream(f));
Source input = new DOMSource(doc);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
transformer.transform(input, output);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : this) {
if (node.needsSaving()) return true;
}
return false;
}
}