mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
refactored file management out of presenter
This commit is contained in:
@@ -13,5 +13,6 @@
|
|||||||
<classpathentry kind="lib" path="lib/HttpProxy.jar"/>
|
<classpathentry kind="lib" path="lib/HttpProxy.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/jettison-1.0.1.jar"/>
|
<classpathentry kind="lib" path="lib/jettison-1.0.1.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/poi-3.5-FINAL-20090928.jar"/>
|
<classpathentry kind="lib" path="lib/poi-3.5-FINAL-20090928.jar"/>
|
||||||
|
<classpathentry kind="lib" path="library/main.jar"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
Binary file not shown.
+1
-1
@@ -15,7 +15,7 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
|
|||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
protected String name;
|
protected String name = "";
|
||||||
|
|
||||||
@EditableProperty(defaultable = false)
|
@EditableProperty(defaultable = false)
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+10
@@ -18,4 +18,14 @@ public class Capacitance extends AbstractMeasure<CapacitanceUnit> {
|
|||||||
public Capacitance clone() throws CloneNotSupportedException {
|
public Capacitance clone() throws CloneNotSupportedException {
|
||||||
return new Capacitance(value, unit);
|
return new Capacitance(value, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Capacitance parseCapacitance(String value) {
|
||||||
|
for (CapacitanceUnit unit : CapacitanceUnit.values()) {
|
||||||
|
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||||
|
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||||
|
return new Capacitance(Double.parseDouble(value), unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Could not parse capacitance: " + value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -18,4 +18,14 @@ public class Inductance extends AbstractMeasure<InductanceUnit> {
|
|||||||
public Inductance clone() throws CloneNotSupportedException {
|
public Inductance clone() throws CloneNotSupportedException {
|
||||||
return new Inductance(value, unit);
|
return new Inductance(value, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Inductance parseCapacitance(String value) {
|
||||||
|
for (InductanceUnit unit : InductanceUnit.values()) {
|
||||||
|
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||||
|
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||||
|
return new Inductance(Double.parseDouble(value), unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Could not parse inductance: " + value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -18,4 +18,14 @@ public class Resistance extends AbstractMeasure<ResistanceUnit> {
|
|||||||
public Resistance clone() throws CloneNotSupportedException {
|
public Resistance clone() throws CloneNotSupportedException {
|
||||||
return new Resistance(value, unit);
|
return new Resistance(value, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Resistance parseResistance(String value) {
|
||||||
|
for (ResistanceUnit unit : ResistanceUnit.values()) {
|
||||||
|
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||||
|
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||||
|
return new Resistance(Double.parseDouble(value), unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Could not parse resistance: " + value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -29,4 +29,14 @@ public class Size extends AbstractMeasure<SizeUnit> {
|
|||||||
public Size clone() throws CloneNotSupportedException {
|
public Size clone() throws CloneNotSupportedException {
|
||||||
return new Size(value, unit);
|
return new Size(value, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Size parseSize(String value) {
|
||||||
|
for (SizeUnit unit : SizeUnit.values()) {
|
||||||
|
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||||
|
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||||
|
return new Size(Double.parseDouble(value), unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Could not parse size: " + value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-40
@@ -7,10 +7,6 @@ import java.awt.Point;
|
|||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.geom.Area;
|
import java.awt.geom.Area;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -51,8 +47,6 @@ import com.diyfever.gui.miscutils.Utils;
|
|||||||
import com.diyfever.gui.simplemq.MessageDispatcher;
|
import com.diyfever.gui.simplemq.MessageDispatcher;
|
||||||
import com.diyfever.gui.update.VersionNumber;
|
import com.diyfever.gui.update.VersionNumber;
|
||||||
import com.rits.cloning.Cloner;
|
import com.rits.cloning.Cloner;
|
||||||
import com.thoughtworks.xstream.XStream;
|
|
||||||
import com.thoughtworks.xstream.io.xml.DomDriver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main presenter class, contains core app logic and drawing routines.
|
* The main presenter class, contains core app logic and drawing routines.
|
||||||
@@ -72,8 +66,6 @@ public class Presenter implements IPlugInPort {
|
|||||||
|
|
||||||
private double zoomLevel = ConfigurationManager.getInstance().readDouble(ZOOM_KEY, 1d);
|
private double zoomLevel = ConfigurationManager.getInstance().readDouble(ZOOM_KEY, 1d);
|
||||||
private Project currentProject;
|
private Project currentProject;
|
||||||
private String currentFileName = null;
|
|
||||||
private boolean modified = false;
|
|
||||||
private Map<String, List<ComponentType>> componentTypes;
|
private Map<String, List<ComponentType>> componentTypes;
|
||||||
// Maps component class names to ComponentType objects.
|
// Maps component class names to ComponentType objects.
|
||||||
private Map<String, ComponentType> componentTypeMap;
|
private Map<String, ComponentType> componentTypeMap;
|
||||||
@@ -86,8 +78,8 @@ public class Presenter implements IPlugInPort {
|
|||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
private Cloner cloner;
|
private Cloner cloner;
|
||||||
private XStream xStream = new XStream(new DomDriver());
|
|
||||||
private ProjectPainter projectPainter;
|
private ProjectPainter projectPainter;
|
||||||
|
private ProjectFileManager projectFileManager;
|
||||||
|
|
||||||
private Rectangle selectionRect;
|
private Rectangle selectionRect;
|
||||||
|
|
||||||
@@ -121,6 +113,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
currentProject = new Project();
|
currentProject = new Project();
|
||||||
cloner = new Cloner();
|
cloner = new Cloner();
|
||||||
projectPainter = new ProjectPainter();
|
projectPainter = new ProjectPainter();
|
||||||
|
projectFileManager = new ProjectFileManager();
|
||||||
|
|
||||||
// lockedLayers = EnumSet.noneOf(ComponentLayer.class);
|
// lockedLayers = EnumSet.noneOf(ComponentLayer.class);
|
||||||
// visibleLayers = EnumSet.allOf(ComponentLayer.class);
|
// visibleLayers = EnumSet.allOf(ComponentLayer.class);
|
||||||
@@ -203,8 +196,6 @@ public class Presenter implements IPlugInPort {
|
|||||||
Project project = new Project();
|
Project project = new Project();
|
||||||
setDefaultProperties(project);
|
setDefaultProperties(project);
|
||||||
loadProject(project, true);
|
loadProject(project, true);
|
||||||
this.currentFileName = null;
|
|
||||||
this.modified = false;
|
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Could not create new file", e);
|
LOG.error("Could not create new file", e);
|
||||||
@@ -217,18 +208,10 @@ public class Presenter implements IPlugInPort {
|
|||||||
public void loadProjectFromFile(String fileName) {
|
public void loadProjectFromFile(String fileName) {
|
||||||
LOG.info(String.format("loadProjectFromFile(%s)", fileName));
|
LOG.info(String.format("loadProjectFromFile(%s)", fileName));
|
||||||
try {
|
try {
|
||||||
FileInputStream fis = new FileInputStream(fileName);
|
Project project = (Project) projectFileManager.deserializeProjectFromFile(fileName);
|
||||||
Project project = (Project) xStream.fromXML(fis);
|
|
||||||
loadProject(project, true);
|
loadProject(project, true);
|
||||||
fis.close();
|
|
||||||
this.currentFileName = fileName;
|
|
||||||
this.modified = false;
|
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (Exception ex) {
|
||||||
LOG.error("Could not load file", ex);
|
|
||||||
view.showMessage("Could not open file, " + fileName + " does not exist.", "Error",
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOG.error("Could not load file", ex);
|
LOG.error("Could not load file", ex);
|
||||||
view.showMessage("Could not open file " + fileName + ". Check the log for details.",
|
view.showMessage("Could not open file " + fileName + ". Check the log for details.",
|
||||||
"Error", JOptionPane.ERROR_MESSAGE);
|
"Error", JOptionPane.ERROR_MESSAGE);
|
||||||
@@ -237,7 +220,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allowFileAction() {
|
public boolean allowFileAction() {
|
||||||
if (this.modified) {
|
if (projectFileManager.isModified()) {
|
||||||
int response = view.showConfirmDialog(
|
int response = view.showConfirmDialog(
|
||||||
"There are unsaved changes. Are you sure you want to abandon these changes?",
|
"There are unsaved changes. Are you sure you want to abandon these changes?",
|
||||||
"Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
"Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||||
@@ -249,13 +232,8 @@ public class Presenter implements IPlugInPort {
|
|||||||
@Override
|
@Override
|
||||||
public void saveProjectToFile(String fileName) {
|
public void saveProjectToFile(String fileName) {
|
||||||
LOG.info(String.format("saveProjectToFile(%s)", fileName));
|
LOG.info(String.format("saveProjectToFile(%s)", fileName));
|
||||||
FileOutputStream fos;
|
|
||||||
try {
|
try {
|
||||||
fos = new FileOutputStream(fileName);
|
projectFileManager.serializeProjectToFile(currentProject, fileName);
|
||||||
xStream.toXML(currentProject, fos);
|
|
||||||
fos.close();
|
|
||||||
this.currentFileName = fileName;
|
|
||||||
this.modified = false;
|
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.error("Could not save file", ex);
|
LOG.error("Could not save file", ex);
|
||||||
@@ -266,12 +244,12 @@ public class Presenter implements IPlugInPort {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCurrentFileName() {
|
public String getCurrentFileName() {
|
||||||
return this.currentFileName;
|
return projectFileManager.getCurrentFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isProjectModified() {
|
public boolean isProjectModified() {
|
||||||
return this.modified;
|
return projectFileManager.isModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -749,7 +727,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
if (!preDragProject.equals(currentProject)) {
|
if (!preDragProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, preDragProject, cloner
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, preDragProject, cloner
|
||||||
.deepClone(currentProject), "Drag");
|
.deepClone(currentProject), "Drag");
|
||||||
this.modified = true;
|
projectFileManager.notifyFileChange();
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
}
|
}
|
||||||
fireSelectionChanged();
|
fireSelectionChanged();
|
||||||
@@ -774,7 +752,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
selectedComponents.addAll(components);
|
selectedComponents.addAll(components);
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
||||||
.deepClone(currentProject), "Add");
|
.deepClone(currentProject), "Add");
|
||||||
this.modified = true;
|
projectFileManager.notifyFileChange();
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
fireSelectionChanged();
|
fireSelectionChanged();
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
@@ -794,7 +772,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
this.selectedComponents.clear();
|
this.selectedComponents.clear();
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
||||||
.deepClone(currentProject), "Delete");
|
.deepClone(currentProject), "Delete");
|
||||||
this.modified = true;
|
projectFileManager.notifyFileChange();
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
fireSelectionChanged();
|
fireSelectionChanged();
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
@@ -839,7 +817,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
||||||
.deepClone(currentProject), "Group");
|
.deepClone(currentProject), "Group");
|
||||||
this.modified = true;
|
projectFileManager.notifyFileChange();
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -854,7 +832,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
||||||
.deepClone(currentProject), "Group");
|
.deepClone(currentProject), "Group");
|
||||||
this.modified = true;
|
projectFileManager.notifyFileChange();
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -876,8 +854,8 @@ public class Presenter implements IPlugInPort {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fireFileStatusChanged() {
|
private void fireFileStatusChanged() {
|
||||||
messageDispatcher.dispatchMessage(EventType.FILE_STATUS_CHANGED, this.currentFileName,
|
messageDispatcher.dispatchMessage(EventType.FILE_STATUS_CHANGED, getCurrentFileName(),
|
||||||
this.modified);
|
isProjectModified());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1025,7 +1003,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
||||||
.deepClone(currentProject), "Add " + componentType.getName());
|
.deepClone(currentProject), "Add " + componentType.getName());
|
||||||
this.modified = true;
|
projectFileManager.notifyFileChange();
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1096,7 +1074,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
||||||
.deepClone(currentProject), "Edit Selection");
|
.deepClone(currentProject), "Edit Selection");
|
||||||
this.modified = true;
|
projectFileManager.notifyFileChange();
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
}
|
}
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
@@ -1138,7 +1116,7 @@ public class Presenter implements IPlugInPort {
|
|||||||
if (!oldProject.equals(currentProject)) {
|
if (!oldProject.equals(currentProject)) {
|
||||||
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
|
||||||
.deepClone(currentProject), "Edit Project");
|
.deepClone(currentProject), "Edit Project");
|
||||||
this.modified = true;
|
projectFileManager.notifyFileChange();
|
||||||
fireFileStatusChanged();
|
fireFileStatusChanged();
|
||||||
}
|
}
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
|
|||||||
+291
@@ -0,0 +1,291 @@
|
|||||||
|
package org.diylc.presenter;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.diylc.common.Orientation;
|
||||||
|
import org.diylc.components.boards.AbstractBoard;
|
||||||
|
import org.diylc.components.boards.BlankBoard;
|
||||||
|
import org.diylc.components.boards.PerfBoard;
|
||||||
|
import org.diylc.components.boards.VeroBoard;
|
||||||
|
import org.diylc.components.connectivity.CopperTrace;
|
||||||
|
import org.diylc.components.connectivity.Jumper;
|
||||||
|
import org.diylc.components.connectivity.SolderPad;
|
||||||
|
import org.diylc.components.passive.RadialFilmCapacitor;
|
||||||
|
import org.diylc.components.passive.Resistor;
|
||||||
|
import org.diylc.components.semiconductors.DIL_IC;
|
||||||
|
import org.diylc.core.IDIYComponent;
|
||||||
|
import org.diylc.core.Project;
|
||||||
|
import org.diylc.core.measures.Capacitance;
|
||||||
|
import org.diylc.core.measures.Resistance;
|
||||||
|
import org.diylc.core.measures.Size;
|
||||||
|
import org.diylc.core.measures.SizeUnit;
|
||||||
|
import org.diylc.utils.Constants;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.thoughtworks.xstream.XStream;
|
||||||
|
import com.thoughtworks.xstream.io.xml.DomDriver;
|
||||||
|
|
||||||
|
public class ProjectFileManager {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(ProjectFileManager.class);
|
||||||
|
|
||||||
|
private static final int V1_PIXELS_PER_INCH = 200;
|
||||||
|
private static final Size V1_GRID_SPACING = new Size(0.1d, SizeUnit.in);
|
||||||
|
|
||||||
|
private XStream xStream = new XStream(new DomDriver());
|
||||||
|
|
||||||
|
private String currentFileName = null;
|
||||||
|
private boolean modified = false;
|
||||||
|
|
||||||
|
public void serializeProjectToFile(Project project, String fileName) throws IOException {
|
||||||
|
LOG.info(String.format("saveProjectToFile(%s)", fileName));
|
||||||
|
FileOutputStream fos;
|
||||||
|
fos = new FileOutputStream(fileName);
|
||||||
|
xStream.toXML(project, fos);
|
||||||
|
fos.close();
|
||||||
|
this.currentFileName = fileName;
|
||||||
|
this.modified = false;
|
||||||
|
// fireFileStatusChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Project deserializeProjectFromFile(String fileName) throws SAXException, IOException,
|
||||||
|
ParserConfigurationException {
|
||||||
|
LOG.info(String.format("loadProjectFromFile(%s)", fileName));
|
||||||
|
Project project;
|
||||||
|
File file = new File(fileName);
|
||||||
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||||
|
Document doc = db.parse(file);
|
||||||
|
doc.getDocumentElement().normalize();
|
||||||
|
if (doc.getDocumentElement().getNodeName().equalsIgnoreCase(Project.class.getName())) {
|
||||||
|
project = parseV3File(fileName);
|
||||||
|
} else {
|
||||||
|
if (!doc.getDocumentElement().getNodeName().equalsIgnoreCase("layout")) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Could not open DIY file. Root node is not named 'Layout'.");
|
||||||
|
}
|
||||||
|
String formatVersion = doc.getDocumentElement().getAttribute("formatVersion");
|
||||||
|
if (formatVersion == null || formatVersion.trim().isEmpty()) {
|
||||||
|
LOG.debug("Detected v1 file.");
|
||||||
|
project = parseV1File(doc.getDocumentElement());
|
||||||
|
} else if (formatVersion.equals("2.0")) {
|
||||||
|
LOG.debug("Detected v2 file.");
|
||||||
|
project = parseV2File(doc.getDocumentElement());
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unknown file format version: " + formatVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.currentFileName = fileName;
|
||||||
|
this.modified = false;
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyFileChange() {
|
||||||
|
this.modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentFileName() {
|
||||||
|
return currentFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isModified() {
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Project parseV1File(Element root) {
|
||||||
|
Project project = new Project();
|
||||||
|
project.setTitle(root.getAttribute("Project"));
|
||||||
|
project.setAuthor(root.getAttribute("Credits"));
|
||||||
|
project.setGridSpacing(V1_GRID_SPACING);
|
||||||
|
String type = root.getAttribute("Type");
|
||||||
|
|
||||||
|
// Create the board.
|
||||||
|
int width = Integer.parseInt(root.getAttribute("Width")) + 1;
|
||||||
|
int height = Integer.parseInt(root.getAttribute("Height")) + 1;
|
||||||
|
int boardWidth = (int) (width * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue());
|
||||||
|
int boardHeight = (int) (height * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue());
|
||||||
|
int projectWidth = project.getWidth().convertToPixels();
|
||||||
|
int projectHeight = project.getHeight().convertToPixels();
|
||||||
|
int x = (projectWidth - boardWidth) / 2;
|
||||||
|
int y = (projectHeight - boardHeight) / 2;
|
||||||
|
AbstractBoard board;
|
||||||
|
if (type.equalsIgnoreCase("pcb")) {
|
||||||
|
board = new BlankBoard();
|
||||||
|
board.setBoardColor(Color.white);
|
||||||
|
board.setBorderColor(Color.black);
|
||||||
|
} else if (type.equalsIgnoreCase("perfboard")) {
|
||||||
|
board = new PerfBoard();
|
||||||
|
} else if (type.equalsIgnoreCase("stripboard")) {
|
||||||
|
board = new VeroBoard();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unrecognized board type: " + type);
|
||||||
|
}
|
||||||
|
board.setName("Main board");
|
||||||
|
Point referencePoint = new Point(roundToGrid(x, V1_GRID_SPACING), roundToGrid(y,
|
||||||
|
V1_GRID_SPACING));
|
||||||
|
board.setControlPoint(referencePoint, 0);
|
||||||
|
board.setControlPoint(new Point(roundToGrid(x + boardWidth, V1_GRID_SPACING), roundToGrid(y
|
||||||
|
+ boardHeight, V1_GRID_SPACING)), 1);
|
||||||
|
project.getComponents().add(board);
|
||||||
|
|
||||||
|
NodeList childNodes = root.getChildNodes();
|
||||||
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
|
Node node = childNodes.item(i);
|
||||||
|
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
String nodeName = node.getNodeName();
|
||||||
|
String nameAttr = node.getAttributes().getNamedItem("Name").getNodeValue();
|
||||||
|
Node valueNode = node.getAttributes().getNamedItem("Value");
|
||||||
|
String valueAttr = valueNode == null ? null : valueNode.getNodeValue();
|
||||||
|
int x1Attr = Integer.parseInt(node.getAttributes().getNamedItem("X1")
|
||||||
|
.getNodeValue());
|
||||||
|
int y1Attr = Integer.parseInt(node.getAttributes().getNamedItem("Y1")
|
||||||
|
.getNodeValue());
|
||||||
|
Point point1 = convertV1CoordinatesToV3Point(referencePoint, x1Attr, y1Attr);
|
||||||
|
Point point2 = null;
|
||||||
|
Integer x2Attr = null;
|
||||||
|
Integer y2Attr = null;
|
||||||
|
if (node.getAttributes().getNamedItem("X2") != null
|
||||||
|
&& node.getAttributes().getNamedItem("Y2") != null) {
|
||||||
|
x2Attr = Integer.parseInt(node.getAttributes().getNamedItem("X2")
|
||||||
|
.getNodeValue());
|
||||||
|
y2Attr = Integer.parseInt(node.getAttributes().getNamedItem("Y2")
|
||||||
|
.getNodeValue());
|
||||||
|
point2 = convertV1CoordinatesToV3Point(referencePoint, x2Attr, y2Attr);
|
||||||
|
}
|
||||||
|
IDIYComponent<?> component = null;
|
||||||
|
if (nodeName.equalsIgnoreCase("pad")) {
|
||||||
|
LOG.debug("Recognized " + nodeName);
|
||||||
|
String colorAttr = node.getAttributes().getNamedItem("Color").getNodeValue();
|
||||||
|
SolderPad pad = new SolderPad();
|
||||||
|
pad.setName(nameAttr);
|
||||||
|
// pad.setColor(Color.getColor(colorAttr));
|
||||||
|
pad.setControlPoint(convertV1CoordinatesToV3Point(referencePoint, x1Attr,
|
||||||
|
y1Attr), 0);
|
||||||
|
component = pad;
|
||||||
|
} else if (nodeName.equalsIgnoreCase("trace")) {
|
||||||
|
LOG.debug("Recognized " + nodeName);
|
||||||
|
String colorAttr = node.getAttributes().getNamedItem("Color").getNodeValue();
|
||||||
|
CopperTrace trace = new CopperTrace();
|
||||||
|
trace.setName(nameAttr);
|
||||||
|
trace.setControlPoint(point1, 0);
|
||||||
|
trace.setControlPoint(point2, 1);
|
||||||
|
component = trace;
|
||||||
|
} else if (nodeName.equalsIgnoreCase("jumper")) {
|
||||||
|
LOG.debug("Recognized " + nodeName);
|
||||||
|
Jumper jumper = new Jumper();
|
||||||
|
jumper.setName(nameAttr);
|
||||||
|
jumper.setControlPoint(point1, 0);
|
||||||
|
jumper.setControlPoint(point2, 1);
|
||||||
|
component = jumper;
|
||||||
|
} else if (nodeName.equalsIgnoreCase("resistor")) {
|
||||||
|
LOG.debug("Recognized " + nodeName);
|
||||||
|
Resistor resistor = new Resistor();
|
||||||
|
resistor.setName(nameAttr);
|
||||||
|
try {
|
||||||
|
resistor.setValue(Resistance.parseResistance(valueAttr));
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.debug("Could not set value of " + nameAttr);
|
||||||
|
}
|
||||||
|
resistor.setWidth(new Size(6d, SizeUnit.mm));
|
||||||
|
resistor.setHeight(new Size(2d, SizeUnit.mm));
|
||||||
|
resistor.setControlPoint(point1, 0);
|
||||||
|
resistor.setControlPoint(point2, 1);
|
||||||
|
component = resistor;
|
||||||
|
} else if (nodeName.equalsIgnoreCase("capacitor")) {
|
||||||
|
LOG.debug("Recognized " + nodeName);
|
||||||
|
RadialFilmCapacitor capacitor = new RadialFilmCapacitor();
|
||||||
|
capacitor.setName(nameAttr);
|
||||||
|
try {
|
||||||
|
capacitor.setValue(Capacitance.parseCapacitance(valueAttr));
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.debug("Could not set value of " + nameAttr);
|
||||||
|
}
|
||||||
|
capacitor.setWidth(new Size(6d, SizeUnit.mm));
|
||||||
|
capacitor.setHeight(new Size(2d, SizeUnit.mm));
|
||||||
|
capacitor.setControlPoint(point1, 0);
|
||||||
|
capacitor.setControlPoint(point2, 1);
|
||||||
|
component = capacitor;
|
||||||
|
} else if (nodeName.equalsIgnoreCase("ic")) {
|
||||||
|
LOG.debug("Recognized " + nodeName);
|
||||||
|
DIL_IC ic = new DIL_IC();
|
||||||
|
if (x1Attr + 3 == x2Attr) {
|
||||||
|
if (y1Attr < y2Attr) {
|
||||||
|
ic
|
||||||
|
.setPinCount(DIL_IC.PinCount.valueOf("_" + 2
|
||||||
|
* (y2Attr - y1Attr + 1)));
|
||||||
|
} else {
|
||||||
|
ic.setOrientation(Orientation._180);
|
||||||
|
ic
|
||||||
|
.setPinCount(DIL_IC.PinCount.valueOf("_" + 2
|
||||||
|
* (y1Attr - y2Attr + 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ic.setName(nameAttr);
|
||||||
|
ic.setControlPoint(point1, 0);
|
||||||
|
ic.setValue(valueAttr);
|
||||||
|
component = ic;
|
||||||
|
} else {
|
||||||
|
LOG.debug("Could not recognize component type " + nodeName);
|
||||||
|
}
|
||||||
|
if (component != null) {
|
||||||
|
project.getComponents().add(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point convertV1CoordinatesToV3Point(Point reference, int x, int y) {
|
||||||
|
Point point = new Point(reference);
|
||||||
|
point.translate((int) (x * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue()),
|
||||||
|
(int) (y * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue()));
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Project parseV2File(Element root) {
|
||||||
|
Project project = new Project();
|
||||||
|
String projectName = root.getAttribute("projectName");
|
||||||
|
String credits = root.getAttribute("credits");
|
||||||
|
String width = root.getAttribute("width");
|
||||||
|
String height = root.getAttribute("height");
|
||||||
|
NodeList childNodes = root.getChildNodes();
|
||||||
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
|
Node node = childNodes.item(i);
|
||||||
|
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
if (node.getNodeName().equalsIgnoreCase("component")) {
|
||||||
|
LOG.debug(node.getAttributes().getNamedItem("name").getNodeValue());
|
||||||
|
} else {
|
||||||
|
LOG.debug("Unrecognized node name found: " + node.getNodeName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Project parseV3File(String fileName) throws IOException {
|
||||||
|
Project project;
|
||||||
|
FileInputStream fis = new FileInputStream(fileName);
|
||||||
|
project = (Project) xStream.fromXML(fis);
|
||||||
|
fis.close();
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int roundToGrid(int x, Size gridSpacing) {
|
||||||
|
int grid = gridSpacing.convertToPixels();
|
||||||
|
return (Math.round(1f * x / grid) * grid);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user