package org.geogebra.common.kernel.commands; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.arithmetic.Command; import org.geogebra.common.kernel.arithmetic.FunctionalNVar; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.kernelND.GeoElementND; import org.geogebra.common.kernel.kernelND.GeoRayND; import org.geogebra.common.kernel.kernelND.GeoSegmentND; import org.geogebra.common.main.MyError; /** * CopyFreeObject */ public class CmdCopyFreeObject extends CommandProcessor { /** * Create new command processor * * @param kernel * kernel */ public CmdCopyFreeObject(Kernel kernel) { super(kernel); } @Override final public GeoElement[] process(Command c) throws MyError { int n = c.getArgumentNumber(); GeoElement[] arg; arg = resArgs(c); switch (n) { // FunctionalNVar case 1: GeoElement geo; String label = c.getLabel(); if (arg[0] instanceof FunctionalNVar) { return copyFunction(arg[0], c, label); } if (arg[0] instanceof GeoSegmentND) { geo = ((GeoSegmentND) arg[0]).copyFreeSegment(); } else if (arg[0] instanceof GeoRayND) { geo = ((GeoRayND) arg[0]).copyFreeRay(); } else { // changed to deepCopyGeo() so that it works for lists // https://www.geogebra.org/forum/viewtopic.php?f=8&t=26356 geo = arg[0].deepCopyGeo(); } geo.setVisualStyle(arg[0]); geo.setLabel(label); GeoElement[] ret = { geo }; if (!arg[0].isLabelSet()) { arg[0].remove(); } return ret; // more than one argument default: throw argNumErr(app, c, n); } } private GeoElement[] copyFunction(GeoElement geoElement, Command c, String label) { FunctionalNVar f = (FunctionalNVar) geoElement; StringBuilder command = new StringBuilder(); // eg f(x,y)= if (label != null) { command.append(label); } else { // add label explicitly to make sure this works for f(t) or f(a,b) command.append(geoElement.getFreeLabel(null)); } command.append('('); command.append(f.getVarString(StringTemplate.defaultTemplate)); command.append(")="); StringTemplate highPrecision = StringTemplate.maxPrecision; if (f.getFunctionExpression().isSecret()) { command.append(geoElement.getParentAlgorithm().getClassName()); command.append("["); command.append(geoElement.getParentAlgorithm().getInput(0) .toOutputValueString(highPrecision)); command.append("]"); } else { command.append(geoElement.toOutputValueString(highPrecision)); } try { GeoElementND[] ret = kernelA.getAlgebraProcessor() .processAlgebraCommandNoExceptions(command.toString(), true); ret[0].setVisualStyle(geoElement); if (!geoElement.isLabelSet()) { geoElement.remove(); } return ret[0].toGeoElement().asArray(); } catch (Exception e) { if (!geoElement.isLabelSet()) { geoElement.remove(); } e.printStackTrace(); throw argErr(geoElement, c); } } }