version 1.1.3

This commit is contained in:
Sampo Niskanen 2010-10-06 05:18:11 +00:00
parent 9e6bea78ad
commit ea3433f704
22 changed files with 555 additions and 268 deletions

View File

@ -1,3 +1,13 @@
2010-10-06 Sampo Niskanen
* Released version 1.1.3
2010-10-05 Sampo Niskanen
* Display comment as tooltip in component tree
* Limited allowed component attachments to those of the component
add buttons
2010-10-03 Sampo Niskanen 2010-10-03 Sampo Niskanen
* Added VBOSE logging level * Added VBOSE logging level

View File

@ -1,3 +1,10 @@
OpenRocket 1.1.3 (2010-10-06):
-------------------------------
Support for drag-drop moving and copying of components. Fixes a
severe bug in the undo system.
OpenRocket 1.1.2 (2010-09-07): OpenRocket 1.1.2 (2010-09-07):
------------------------------- -------------------------------

View File

@ -1,7 +1,7 @@
# The OpenRocket build version # The OpenRocket build version
build.version=1.1.3pre build.version=1.1.3
# The source of the package. When building a package for a specific # The source of the package. When building a package for a specific

View File

@ -9,6 +9,7 @@ import javax.swing.event.ChangeListener;
import net.sf.openrocket.aerodynamics.AerodynamicCalculator; import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
import net.sf.openrocket.aerodynamics.BarrowmanCalculator; import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.masscalc.BasicMassCalculator; import net.sf.openrocket.masscalc.BasicMassCalculator;
import net.sf.openrocket.masscalc.MassCalculator; import net.sf.openrocket.masscalc.MassCalculator;
import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.Configuration;
@ -23,11 +24,13 @@ import net.sf.openrocket.simulation.SimulationStepper;
import net.sf.openrocket.simulation.exception.SimulationException; import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.exception.SimulationListenerException; import net.sf.openrocket.simulation.exception.SimulationListenerException;
import net.sf.openrocket.simulation.listeners.SimulationListener; import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.ChangeSource;
public class Simulation implements ChangeSource, Cloneable { public class Simulation implements ChangeSource, Cloneable {
private static final LogHelper log = Application.getLogger();
public static enum Status { public static enum Status {
/** Up-to-date */ /** Up-to-date */
@ -238,22 +241,16 @@ public class Simulation implements ChangeSource, Cloneable {
throw new SimulationException("Cannot simulate imported simulation."); throw new SimulationException("Cannot simulate imported simulation.");
} }
AerodynamicCalculator aerodynamicCalculator;
SimulationEngine simulator; SimulationEngine simulator;
SimulationStepper stepper;
MassCalculator massCalculator;
try { try {
aerodynamicCalculator = aerodynamicCalculatorClass.newInstance();
simulator = simulationEngineClass.newInstance(); simulator = simulationEngineClass.newInstance();
stepper = simulationStepperClass.newInstance();
massCalculator = massCalculatorClass.newInstance();
} catch (InstantiationException e) { } catch (InstantiationException e) {
throw new IllegalStateException("Cannot instantiate calculator/simulator.", e); throw new IllegalStateException("Cannot instantiate simulator.", e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new IllegalStateException("Cannot access calc/sim instance?! BUG!", e); throw new IllegalStateException("Cannot access simulator instance?! BUG!", e);
} catch (NullPointerException e) { } catch (NullPointerException e) {
throw new IllegalStateException("Calculator or simulator null", e); throw new IllegalStateException("Simulator null", e);
} }
SimulationConditions simulationConditions = conditions.toSimulationConditions(); SimulationConditions simulationConditions = conditions.toSimulationConditions();
@ -274,12 +271,11 @@ public class Simulation implements ChangeSource, Cloneable {
} }
long t1, t2; long t1, t2;
System.out.println("Simulation: calling simulator"); log.debug("Simulation: calling simulator");
t1 = System.currentTimeMillis(); t1 = System.currentTimeMillis();
simulatedData = simulator.simulate(simulationConditions); simulatedData = simulator.simulate(simulationConditions);
t2 = System.currentTimeMillis(); t2 = System.currentTimeMillis();
System.out.println("Simulation: returning from simulator, " + log.debug("Simulation: returning from simulator, simulation took " + (t2 - t1) + "ms");
"simulation took " + (t2 - t1) + "ms");
// Set simulated info after simulation, will not be set in case of exception // Set simulated info after simulation, will not be set in case of exception
simulatedConditions = conditions.clone(); simulatedConditions = conditions.clone();

View File

@ -0,0 +1,86 @@
package net.sf.openrocket.gui.dialogs.optimization;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import javax.swing.JDialog;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.optimization.rocketoptimization.RocketOptimizationParameter;
import net.sf.openrocket.optimization.rocketoptimization.RocketOptimizationParameterService;
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier;
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifierService;
import net.sf.openrocket.util.BugException;
public class GeneralOptimizationDialog extends JDialog {
private final List<RocketOptimizationParameter> optimizationParameters = new ArrayList<RocketOptimizationParameter>();
private final Map<Object, List<SimulationModifier>> simulationModifiers =
new HashMap<Object, List<SimulationModifier>>();
private final OpenRocketDocument document;
public GeneralOptimizationDialog(OpenRocketDocument document, Window parent) {
this.document = document;
loadOptimizationParameters();
loadSimulationModifiers();
}
private void loadOptimizationParameters() {
ServiceLoader<RocketOptimizationParameterService> loader =
ServiceLoader.load(RocketOptimizationParameterService.class);
for (RocketOptimizationParameterService g : loader) {
optimizationParameters.addAll(g.getParameters(document));
}
if (optimizationParameters.isEmpty()) {
throw new BugException("No rocket optimization parameters found, distribution built wrong.");
}
Collections.sort(optimizationParameters, new Comparator<RocketOptimizationParameter>() {
@Override
public int compare(RocketOptimizationParameter o1, RocketOptimizationParameter o2) {
return o1.getName().compareTo(o2.getName());
}
});
}
private void loadSimulationModifiers() {
ServiceLoader<SimulationModifierService> loader = ServiceLoader.load(SimulationModifierService.class);
for (SimulationModifierService g : loader) {
for (SimulationModifier m : g.getModifiers(document)) {
Object key = m.getRelatedObject();
List<SimulationModifier> list = simulationModifiers.get(key);
if (list == null) {
list = new ArrayList<SimulationModifier>();
simulationModifiers.put(key, list);
}
list.add(m);
}
}
for (Object key : simulationModifiers.keySet()) {
List<SimulationModifier> list = simulationModifiers.get(key);
Collections.sort(list, new Comparator<SimulationModifier>() {
@Override
public int compare(SimulationModifier o1, SimulationModifier o2) {
return o1.getName().compareTo(o2.getName());
}
});
}
}
}

View File

@ -9,6 +9,7 @@ import java.awt.Graphics2D;
import javax.swing.DropMode; import javax.swing.DropMode;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JTree; import javax.swing.JTree;
import javax.swing.ToolTipManager;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
@ -41,8 +42,13 @@ public class ComponentTree extends JTree {
// Expand whole tree by default // Expand whole tree by default
expandTree(); expandTree();
// Enable tooltips for this component
ToolTipManager.sharedInstance().registerComponent(this);
} }
public void expandTree() { public void expandTree() {
for (int i = 0; i < getRowCount(); i++) for (int i = 0; i < getRowCount(); i++)
expandRow(i); expandRow(i);

View File

@ -8,6 +8,8 @@ import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeCellRenderer;
import net.sf.openrocket.gui.main.ComponentIcons; import net.sf.openrocket.gui.main.ComponentIcons;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.TextUtil;
public class ComponentTreeRenderer extends DefaultTreeCellRenderer { public class ComponentTreeRenderer extends DefaultTreeCellRenderer {
@ -23,8 +25,20 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
// Set icon
setIcon(ComponentIcons.getSmallIcon(value.getClass())); setIcon(ComponentIcons.getSmallIcon(value.getClass()));
// Set tooltip
RocketComponent c = (RocketComponent) value;
String comment = c.getComment().trim();
if (comment.length() > 0) {
comment = TextUtil.htmlEncode(comment);
comment = "<html>" + comment.replace("\n", "<br>");
this.setToolTipText(comment);
} else {
this.setToolTipText(null);
}
return this; return this;
} }

View File

@ -98,7 +98,7 @@ public class RocketOptimizationFunction implements Function {
return value; return value;
} }
// TODO: CRITICAL: is in domain? // TODO: : is in domain?
return 0; return 0;
} }

View File

@ -0,0 +1,23 @@
package net.sf.openrocket.optimization.rocketoptimization;
import java.util.Collection;
import net.sf.openrocket.document.OpenRocketDocument;
/**
* A service for generating rocket optimization parameters.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public interface RocketOptimizationParameterService {
/**
* Return all available rocket optimization parameters for this document.
* These should be new instances unless the parameter implementation is stateless.
*
* @param document the design document
* @return a collection of the rocket optimization parameters.
*/
public Collection<RocketOptimizationParameter> getParameters(OpenRocketDocument document);
}

View File

@ -1,6 +1,8 @@
package net.sf.openrocket.optimization.rocketoptimization; package net.sf.openrocket.optimization.rocketoptimization;
import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.ChangeSource;
/** /**
* An interface what modifies a single parameter in a rocket simulation * An interface what modifies a single parameter in a rocket simulation
@ -8,14 +10,80 @@ import net.sf.openrocket.document.Simulation;
* *
* @author Sampo Niskanen <sampo.niskanen@iki.fi> * @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/ */
public interface SimulationModifier { public interface SimulationModifier extends ChangeSource {
/**
* Return a name describing this modifier.
* @return a name describing this modifier.
*/
public String getName();
/**
* Return the object this modifier is related to. This is for example the
* rocket component this modifier is modifying. This object can be used by a
* UI to group related modifiers.
*
* @return the object this modifier is related to, or <code>null</code>.
*/
public Object getRelatedObject();
/**
* Return the current value of the modifier in SI units.
* @return the current value of this parameter in SI units.
*/
public double getCurrentValue();
/**
* Return the minimum value (corresponding to scaled value 0) in SI units.
* @return the value corresponding to scaled value 0.
*/
public double getMinValue();
/**
* Set the minimum value (corresponding to scaled value 0) in SI units.
* @param value the value corresponding to scaled value 0.
*/
public void setMinValue(double value);
/**
* Return the maximum value (corresponding to scaled value 1) in SI units.
* @return the value corresponding to scaled value 1.
*/
public double getMaxValue();
/**
* Set the maximum value (corresponding to scaled value 1) in SI units.
* @param value the value corresponding to scaled value 1.
*/
public void setMaxValue(double value);
/**
* Return the unit group used for the values returned by {@link #getCurrentValue()} etc.
* @return the unit group
*/
public UnitGroup getUnitGroup();
/**
* Return the current scaled value. This is normally within the range [0...1], but
* can be outside the range if the current value is outside of the min and max values.
* @return
*/
public double getCurrentScaledValue();
/** /**
* Modify the specified simulation to the corresponding parameter value. * Modify the specified simulation to the corresponding parameter value.
* *
* @param simulation the simulation to modify * @param simulation the simulation to modify
* @param value a value in the range [0...1] * @param scaledValue the scaled value in the range [0...1]
*/ */
public void modify(Simulation simulation, double value); public void modify(Simulation simulation, double scaledValue);
} }

View File

@ -0,0 +1,23 @@
package net.sf.openrocket.optimization.rocketoptimization;
import java.util.Collection;
import net.sf.openrocket.document.OpenRocketDocument;
/**
* A service for generating simulation modifiers.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public interface SimulationModifierService {
/**
* Return all available simulation modifiers for this document.
*
* @param document the design document
* @return a collection of the rocket optimization parameters.
*/
public Collection<SimulationModifier> getModifiers(OpenRocketDocument document);
}

View File

@ -64,20 +64,4 @@ public abstract class BodyComponent extends ExternalComponent {
return true; return true;
} }
/**
* Check whether the given type can be added to this component. BodyComponents allow any
* InternalComponents or ExternalComponents, excluding BodyComponents, to be added.
*
* @param type The RocketComponent class type to add.
* @return Whether such a component can be added.
*/
@Override
public boolean isCompatible(Class<? extends RocketComponent> type) {
if (InternalComponent.class.isAssignableFrom(type))
return true;
if (ExternalComponent.class.isAssignableFrom(type) &&
!BodyComponent.class.isAssignableFrom(type))
return true;
return false;
}
} }

View File

@ -281,6 +281,24 @@ public class BodyTube extends SymmetricComponent implements MotorMount {
} }
/**
* Check whether the given type can be added to this component. BodyTubes allow any
* InternalComponents or ExternalComponents, excluding BodyComponents, to be added.
*
* @param type The RocketComponent class type to add.
* @return Whether such a component can be added.
*/
@Override
public boolean isCompatible(Class<? extends RocketComponent> type) {
if (InternalComponent.class.isAssignableFrom(type))
return true;
if (ExternalComponent.class.isAssignableFrom(type) &&
!BodyComponent.class.isAssignableFrom(type))
return true;
return false;
}
//////////////// Motor mount ///////////////// //////////////// Motor mount /////////////////
@Override @Override

View File

@ -107,7 +107,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable,
private String comment = ""; private String comment = "";
// Unique ID of the component // Unique ID of the component
// TODO: CRITICAL: Sort out usage of ID and undo defect
private String id = null; private String id = null;
/** /**

View File

@ -498,6 +498,21 @@ public class Transition extends SymmetricComponent {
} }
/**
* Check whether the given type can be added to this component. Transitions allow any
* InternalComponents to be added.
*
* @param type The RocketComponent class type to add.
* @return Whether such a component can be added.
*/
@Override
public boolean isCompatible(Class<? extends RocketComponent> type) {
if (InternalComponent.class.isAssignableFrom(type))
return true;
return false;
}
/** /**
* An enumeration listing the possible shapes of transitions. * An enumeration listing the possible shapes of transitions.
@ -539,10 +554,12 @@ public class Transition extends SymmetricComponent {
public boolean usesParameter() { public boolean usesParameter() {
return true; // Range 0...1 is default return true; // Range 0...1 is default
} }
@Override @Override
public double defaultParameter() { public double defaultParameter() {
return 1.0; // Tangent ogive by default return 1.0; // Tangent ogive by default
} }
@Override @Override
public double getRadius(double x, double radius, double length, double param) { public double getRadius(double x, double radius, double length, double param) {
assert x >= 0; assert x >= 0;
@ -608,10 +625,12 @@ public class Transition extends SymmetricComponent {
public boolean usesParameter() { // Range 0...1 public boolean usesParameter() { // Range 0...1
return true; return true;
} }
@Override @Override
public double defaultParameter() { public double defaultParameter() {
return 0.5; return 0.5;
} }
@Override @Override
public double getRadius(double x, double radius, double length, double param) { public double getRadius(double x, double radius, double length, double param) {
assert x >= 0; assert x >= 0;
@ -649,10 +668,12 @@ public class Transition extends SymmetricComponent {
public boolean usesParameter() { // Range 0...1 public boolean usesParameter() { // Range 0...1
return true; return true;
} }
@Override @Override
public double defaultParameter() { public double defaultParameter() {
return 1.0; return 1.0;
} }
@Override @Override
public double getRadius(double x, double radius, double length, double param) { public double getRadius(double x, double radius, double length, double param) {
assert x >= 0; assert x >= 0;
@ -681,10 +702,12 @@ public class Transition extends SymmetricComponent {
public boolean usesParameter() { public boolean usesParameter() {
return true; return true;
} }
@Override @Override
public double maxParameter() { public double maxParameter() {
return 1.0 / 3.0; // Range 0...1/3 return 1.0 / 3.0; // Range 0...1/3
} }
@Override @Override
public double getRadius(double x, double radius, double length, double param) { public double getRadius(double x, double radius, double length, double param) {
assert x >= 0; assert x >= 0;

View File

@ -156,4 +156,12 @@ public class TextUtil {
return sb.toString(); return sb.toString();
} }
public static String htmlEncode(String s) {
s = s.replace("&", "&amp;");
s = s.replace("\"", "&quot;");
s = s.replace("<", "&lt;");
s = s.replace(">", "&gt;");
return s;
}
} }

View File

@ -80,16 +80,18 @@ header("Content-type: text/plain");
$version = $_GET["version"]; $version = $_GET["version"];
$updates = ""; $updates = "";
$unstable = "1.1.2"; $unstable = "1.1.3";
$stable = "1.0.0"; $stable = "1.0.0";
if (preg_match("/^1\.1\.1/", $version)) { if (preg_match("/^1\.1\.[12]/", $version)) {
$updates = "Version: " . $unstable . "\n" . $updates = "Version: " . $unstable . "\n" .
"4: Fixed bug preventing addition of stages\n"; "5: Initial drag-and-drop support\n" .
"4: Bug fixes\n";
} else if (preg_match("/^1\.1\.0/", $version)) { } else if (preg_match("/^1\.1\.0/", $version)) {
$updates = "Version: " . $unstable . "\n" . $updates = "Version: " . $unstable . "\n" .
"6: Enhanced motor selection\n" . "6: Enhanced motor selection\n" .
"5: Rewritten simulation code\n" . "5: Rewritten simulation code\n" .
"5: Drag-and-drop support\n" .
"4: Bug fixes"; "4: Bug fixes";
} else if (preg_match("/^0\.9\.6/", $version)) { } else if (preg_match("/^0\.9\.6/", $version)) {
$updates = "Version: " . $stable . "\n" . $updates = "Version: " . $stable . "\n" .

View File

@ -45,6 +45,12 @@
<div class="content"> <div class="content">
<div class="news"> <div class="news">
<h2>Recent news:</h2> <h2>Recent news:</h2>
<p><span class="date">6.10.2010:</span> Version 1.1.3 is
<a href="download.html">released</a>!</p>
<p>This release includes support for moving and copying components
in the component tree using drag-and-drop. Use normal DnD for
moving, and control-drag for copy. This release also fixes a
severe bug in the undo system.</p>
<p><span class="date">7.9.2010:</span> A bug-fix version 1.1.2 is <p><span class="date">7.9.2010:</span> A bug-fix version 1.1.2 is
<a href="download.html">released</a>!</p> <a href="download.html">released</a>!</p>
<p>This release fixes a severe bug in 1.1.1 that prevented adding stages <p>This release fixes a severe bug in 1.1.1 that prevented adding stages
@ -82,13 +88,13 @@
<a href="http://sourceforge.net/donate/index.php?group_id=260357"><img src="project-support.jpg" width="88" height="32" alt="Support This Project" /></a> <a href="http://sourceforge.net/donate/index.php?group_id=260357"><img src="project-support.jpg" width="88" height="32" alt="Support This Project" /></a>
</div> </div>
<div class="downloadbox"> <div class="downloadbox">
<a class="main" href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.2/OpenRocket-1.1.2.jar/download"> <a class="main" href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.3/OpenRocket-1.1.3.jar/download">
<strong>Download now!</strong> <strong>Download now!</strong>
<span>OpenRocket-1.1.2.jar</span> <span>OpenRocket-1.1.3.jar</span>
</a> </a>
<span class="alternative"> <span class="alternative">
<a href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.2/ReleaseNotes/view">Release notes</a> | <a href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.3/ReleaseNotes/view">Release notes</a> |
<a href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.2/OpenRocket-1.1.2-src.zip/download">Source code</a> <a href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.3/OpenRocket-1.1.3-src.zip/download">Source code</a>
</span> </span>
</div> </div>
<h3>Stable release</h3> <h3>Stable release</h3>
@ -105,7 +111,7 @@
Windows) by double-clicking the package icon. No installation is Windows) by double-clicking the package icon. No installation is
required.</p> required.</p>
<p>From the command line OpenRocket can be started by <p>From the command line OpenRocket can be started by
<span class="command">java -jar OpenRocket-1.1.2.jar</span></p> <span class="command">java -jar OpenRocket-1.1.3.jar</span></p>
</div> </div>
<div class="clear"></div> <div class="clear"></div>

View File

@ -46,12 +46,12 @@
<h2>Introduction</h2> <h2>Introduction</h2>
<div class="rightpane"> <div class="rightpane">
<div class="downloadbox"> <div class="downloadbox">
<a class="main" href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.2/OpenRocket-1.1.2.jar/download"> <a class="main" href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.3/OpenRocket-1.1.3.jar/download">
<strong>Download now!</strong> <strong>Download now!</strong>
<span>OpenRocket-1.1.2.jar</span> <span>OpenRocket-1.1.3.jar</span>
</a> </a>
<span class="alternative"> <span class="alternative">
<a href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.2/ReleaseNotes/view">Release notes</a> | <a href="https://sourceforge.net/projects/openrocket/files/openrocket/1.1.3/ReleaseNotes/view">Release notes</a> |
<a href="download.html">Other versions</a> <a href="download.html">Other versions</a>
</span> </span>
</div> </div>
@ -88,6 +88,12 @@
<div class="clear"></div> <div class="clear"></div>
<div class="news"> <div class="news">
<h2>News</h2> <h2>News</h2>
<p><span class="date">6.10.2010:</span> Version 1.1.3 is
<a href="download.html">released</a>!</p>
<p>This release includes support for moving and copying components
in the component tree using drag-and-drop. Use normal DnD for
moving, and control-drag for copy. This release also fixes a
severe bug in the undo system.</p>
<p><span class="date">7.9.2010:</span> A bug-fix version 1.1.2 is <p><span class="date">7.9.2010:</span> A bug-fix version 1.1.2 is
<a href="download.html">released</a>!</p> <a href="download.html">released</a>!</p>
<p>This release fixes a severe bug in 1.1.1 that prevented adding stages <p>This release fixes a severe bug in 1.1.1 that prevented adding stages

View File

@ -1,5 +1,5 @@
<set stableversion="1.0.0"> <set stableversion="1.0.0">
<set developmentversion="1.1.2"> <set developmentversion="1.1.3">
<set version="${developmentversion}"> <set version="${developmentversion}">
<def name="downloadbox"> <def name="downloadbox">

View File

@ -9,6 +9,14 @@
<!--- Remember to move the position of "onlyrecent" below! ---> <!--- Remember to move the position of "onlyrecent" below! --->
<p><span class="date">6.10.2010:</span> Version 1.1.3 is
<a href="download.html">released</a>!</p>
<p>This release includes support for moving and copying components
in the component tree using drag-and-drop. Use normal DnD for
moving, and control-drag for copy. This release also fixes a
severe bug in the undo system.</p>
<p><span class="date">7.9.2010:</span> A bug-fix version 1.1.2 is <p><span class="date">7.9.2010:</span> A bug-fix version 1.1.2 is
<a href="download.html">released</a>!</p> <a href="download.html">released</a>!</p>