CaRMtl/rene/zirkel/macro/Macro.java
2018-09-04 22:51:42 -04:00

376 lines
9.5 KiB
Java

/*
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
This file is part of C.a.R. software.
C.a.R. is a free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.
C.a.R. 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 General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package rene.zirkel.macro;
import java.util.Enumeration;
import java.util.Vector;
import rene.util.xml.XmlTag;
import rene.util.xml.XmlTagText;
import rene.util.xml.XmlTree;
import rene.util.xml.XmlWriter;
import rene.zirkel.ZirkelCanvas;
import rene.zirkel.construction.Construction;
import rene.zirkel.construction.ConstructionException;
import rene.zirkel.objects.ConstructionObject;
/**
* Macros are stored as constructions. Some of the construction objects are
* parameters, which divide into two groups: primary parapemers and secondary
* parameters (e.g. endpoints of a segment). Moreover, there is a separate list
* of the primary parameters and the prompts to display to the user at each
* primary parameter. Some objects are marked as targets.
*/
public class Macro extends Construction implements Cloneable {
public String Name;
public String Prompts[];
public ConstructionObject Params[];
public String PromptFor[] = new String[0];
public String PromptName[] = new String[0];
public String LastParams[];
public boolean Fixed[];
// public boolean createDPLineObjects=false;
boolean Protected = false;
boolean HideDuplicates = true;
// Macro renvoyant un dp_mode (voir la classe ConstructionObject).
// 0 pour un objet non-DP, sinon
// ConstructionObject.DP_LINE ou ConstructionObject.DP_SEGMENT :
public int createDPObjects=0;
/**
* @param zc
* The ZirkelCanvas.
* @param name
* The name of this macro
* @param comment
* The macro comment.
* @param e
* The parameter prompt strings.
*/
public Macro(final ZirkelCanvas zc, final String name,
final String comment, final String s[]) {
Name = name;
Comment = comment;
Prompts = s;
}
public String getName() {
return Name;
}
public void setName(final String name) {
Name = name;
}
@Override
public String getComment() {
return Comment;
}
public String[] getPrompts() {
return Prompts;
}
/**
* Set the list of parameters. The setup of the macro is done in a function
* in ZirkelCanvas.defineMacro().
*/
public void setParams(final ConstructionObject p[]) {
Params = p;
}
public ConstructionObject[] getParams() {
return Params;
}
/**
* Denote and recall previously set parameters.
*/
public void initLast() {
LastParams = new String[Params.length];
}
public void setLast(final String name, final int i) {
try {
LastParams[i] = name;
} catch (final Exception e) {
}
}
public String getLast(final int i) {
if (LastParams != null && LastParams[i] != null)
return LastParams[i];
else
return "";
}
public void setPromptFor(final String s[]) {
PromptFor = s;
PromptName = new String[PromptFor.length];
for (int i = 0; i < PromptFor.length; i++)
PromptName[i] = PromptFor[i];
}
public void setPromptName(final int i, final String s) {
PromptName[i] = s;
}
public boolean promptFor(final String s) {
return getPromptFor(s) >= 0;
}
public int getPromptFor(final String s) {
for (int i = 0; i < PromptFor.length; i++)
if (PromptFor[i].equals(s))
return i;
return -1;
}
public String getPromptName(final String s) {
for (int i = 0; i < PromptFor.length; i++)
if (PromptFor[i].equals(s))
return PromptName[i];
return "";
}
public int countPrompts() {
return PromptFor.length;
}
/**
* Save a macro.
*/
public void saveMacro(final XmlWriter xml) { // Start the macro with its
// name as parameter
xml.startTagStart("Macro");
xml.printArg("Name", Name);
if (!HideDuplicates)
xml.printArg("showduplicates", "true");
xml.startTagEndNewLine();
// Write the parameters and their prompts
for (int i = 0; i < Params.length; i++) {
xml.startTagStart("Parameter");
xml.printArg("name", Params[i].getName());
if (Fixed != null && Fixed[i] && LastParams != null
&& LastParams[i] != null)
xml.printArg("fixed", LastParams[i]);
xml.startTagEnd();
xml.print(Prompts[i]);
xml.endTagNewLine("Parameter");
}
// Write a comment
if (!getComment().equals("")) {
xml.startTagNewLine("Comment");
xml.printParagraphs(getComment(), 60);
xml.endTagNewLine("Comment");
}
// Write the objects. I.e., secondary parameters, primary
// parameters and constructed things, including targets as in
// any other construction.
xml.startTagNewLine("Objects");
save(xml);
xml.endTagNewLine("Objects");
// Save the objects prompted for
if (PromptFor.length > 0) {
xml.startTagStart("PromptFor");
for (int i = 0; i < PromptFor.length; i++) {
xml.printArg("object" + i, PromptFor[i]);
xml.printArg("prompt" + i, PromptName[i]);
}
xml.finishTagNewLine();
}
// End the macro
xml.endTagNewLine("Macro");
}
/**
* Read a macro (implemented as a constructor).
*/
public Macro(final ZirkelCanvas zc, XmlTree tree)
throws ConstructionException { // See, if this is a macro tree, and
// has a name.
XmlTag tag = tree.getTag();
if (!tag.name().equals("Macro"))
throw new ConstructionException("No macro!");
if (!tag.hasParam("Name"))
throw new ConstructionException("Name missing!");
Name = tag.getValue("Name");
if (tag.hasParam("showduplicates"))
HideDuplicates = false;
// Walk through content
Enumeration e = tree.getContent();
while (e.hasMoreElements()) {
final XmlTree t = (XmlTree) e.nextElement();
tag = t.getTag();
// Read the objects, the comment
if (tag.name().equals("Objects")) // Objects
{
readConstruction(t, false);
break;
} else if (tag.name().equals("Comment")) // Comment
{
try {
setComment(t.parseComment());
} catch (final Exception ex) {
throw new ConstructionException("Illegal Comment");
}
}
}
// Read the parameters.
int ParamCount = 0;
// First count the paramters.
e = tree.getContent();
while (e.hasMoreElements()) {
final XmlTree t = (XmlTree) e.nextElement();
tag = t.getTag();
if (tag.name().equals("Parameter")) {
if (!tag.hasParam("name"))
throw new ConstructionException("Parameter name missing!");
ParamCount++;
} else if (tag.name().equals("PromptFor")) {
if (tag.hasParam("object")) {
final String s[] = new String[1];
s[0] = tag.getValue("object");
setPromptFor(s);
if (tag.hasParam("prompt"))
setPromptName(0, tag.getValue("prompt"));
} else {
int n = 0;
while (tag.hasParam("object" + n))
n++;
final String s[] = new String[n];
for (int i = 0; i < n; i++) {
s[i] = tag.getValue("object" + i);
}
setPromptFor(s);
for (int i = 0; i < n; i++) {
if (tag.hasParam("prompt" + i))
setPromptName(i, tag.getValue("prompt" + i));
}
}
}
}
// Then read the parameters.
Params = new ConstructionObject[ParamCount];
initLast();
Prompts = new String[ParamCount];
for (int pr = 0; pr < ParamCount; pr++)
Prompts[pr] = "";
int i = 0;
e = tree.getContent();
while (e.hasMoreElements()) {
final XmlTree t = (XmlTree) e.nextElement();
tag = t.getTag();
if (tag.name().equals("Parameter")) { // Search a parameter by this
// name
Params[i] = find(tag.getValue("name"));
if (Params[i] == null)
throw new ConstructionException("Illegal parameter "
+ tag.getValue("name") + "!");
if (tag.hasParam("fixed")) {
if (Fixed == null) {
Fixed = new boolean[ParamCount];
for (int j = 0; j < ParamCount; j++)
Fixed[j] = false;
}
Fixed[i] = true;
LastParams[i] = tag.getValue("fixed");
}
final Enumeration en = t.getContent();
while (en.hasMoreElements()) {
tree = (XmlTree) en.nextElement();
if (tree.getTag() instanceof XmlTagText) {
Prompts[i] = ((XmlTagText) tree.getTag()).getContent();
}
}
i++;
}
}
}
/**
* @return A list of targets.
*/
@Override
public Vector getTargets() {
final Vector v = new Vector();
final Enumeration e = V.elements();
while (e.hasMoreElements()) {
final ConstructionObject o = (ConstructionObject) e.nextElement();
if (o.isTarget())
v.addElement(o);
}
return v;
}
public boolean hasFixed() {
for (final String prompt : Prompts)
if (prompt.startsWith("="))
return true;
if (Fixed == null)
return false;
for (final boolean element : Fixed)
if (element)
return true;
return false;
}
public boolean isFixed(final int i) {
if (Fixed == null)
return false;
return Fixed[i];
}
public void setFixed(final int i, final boolean f) {
if (Fixed == null)
return;
Fixed[i] = f;
}
@Override
public Object clone() {
try {
return super.clone();
} catch (final Exception e) {
}
return null;
}
public boolean isProtected() {
return Protected;
}
public void setProtected(final boolean flag) {
Protected = flag;
}
public boolean hideDuplicates() {
return HideDuplicates;
}
public void hideDuplicates(final boolean flag) {
HideDuplicates = flag;
}
}