first attempt to implement an undo

This commit is contained in:
hneemann 2017-05-26 07:37:16 +02:00
parent 30c3d44ab4
commit f252a08363
21 changed files with 769 additions and 34 deletions

View File

@ -8,8 +8,6 @@ package de.neemann.digital.core.element;
public interface AttributeListener {
/**
* Is called if an attribute changes
*
* @param key the key which value has changed
*/
void attributeChanged(Key key);
void attributeChanged();
}

View File

@ -90,15 +90,15 @@ public class ElementAttributes {
attributes = new HashMap<>();
attributes.put(key.getKey(), value);
}
fireValueChanged(key);
fireValueChanged();
}
return this;
}
private void fireValueChanged(Key key) {
private void fireValueChanged() {
if (listeners != null)
for (AttributeListener l : listeners)
l.attributeChanged(key);
l.attributeChanged();
}
/**
@ -221,4 +221,22 @@ public class ElementAttributes {
attributes.put(fileKey, file.getPath());
}
/**
* Apply the given attributes to this set
*
* @param elementAttributes the attributes to use
*/
public void getValuesFrom(ElementAttributes elementAttributes) {
if (attributes != null)
attributes.clear();
else
attributes = new HashMap<>();
if (elementAttributes.attributes != null)
attributes.putAll(elementAttributes.attributes);
if (attributes.isEmpty())
attributes = null;
fireValueChanged();
}
}

View File

@ -146,6 +146,25 @@ public class Circuit {
wires = new ArrayList<>();
}
/**
* Creates a copy of the given circuit
*
* @param original the original
*/
public Circuit(Circuit original) {
this();
for (VisualElement ve : original.visualElements)
visualElements.add(new VisualElement(ve));
for (Wire w : original.wires)
wires.add(new Wire(w));
if (original.attributes != null)
attributes = new ElementAttributes(original.attributes);
measurementOrdering = new ArrayList<>();
if (original.measurementOrdering != null)
measurementOrdering.addAll(original.measurementOrdering);
}
/**
* returns the elements attributes
*

View File

@ -1,7 +1,9 @@
package de.neemann.digital.draw.elements;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.gui.components.CircuitComponent;
import de.neemann.digital.gui.components.ElementOrderer;
import de.neemann.digital.gui.components.modification.Modification;
import java.util.ArrayList;
@ -15,16 +17,16 @@ public class ElementOrder implements ElementOrderer.OrderInterface<String> {
private final ArrayList<Entry> entries;
private final ArrayList<VisualElement> elements;
private final Circuit circuit;
private final CircuitComponent circuitComponent;
/**
* Creates a new instance
*
* @param circuit the circuit witch components are to order
* @param description the description of the elements to order
* @param circuitComponent the circuit witch components are to order
* @param description the description of the elements to order
*/
public ElementOrder(Circuit circuit, ElementTypeDescription description) {
this(circuit, element -> {
public ElementOrder(CircuitComponent circuitComponent, ElementTypeDescription description) {
this(circuitComponent, element -> {
return element.equalsDescription(description);
});
}
@ -32,12 +34,12 @@ public class ElementOrder implements ElementOrderer.OrderInterface<String> {
/**
* Creates a new instance
*
* @param circuit the circuit witch components are to order
* @param filter the filter to select the entries to order
* @param circuitComponent the circuitComponent witch components are to order
* @param filter the filter to select the entries to order
*/
public ElementOrder(Circuit circuit, ElementFilter filter) {
this.circuit = circuit;
this.elements = circuit.getElements();
public ElementOrder(CircuitComponent circuitComponent, ElementFilter filter) {
this.circuitComponent = circuitComponent;
this.elements = circuitComponent.getCircuit().getElements();
entries = new ArrayList<>();
for (int i = 0; i < elements.size(); i++)
if (filter.accept(elements.get(i))) {
@ -59,9 +61,8 @@ public class ElementOrder implements ElementOrderer.OrderInterface<String> {
@Override
public void swap(int i, int j) {
VisualElement y = elements.get(entries.get(i).i);
elements.set(entries.get(i).i, elements.get(entries.get(j).i));
elements.set(entries.get(j).i, y);
int index1 = entries.get(i).i;
int index2 = entries.get(j).i;
int z = entries.get(i).i;
entries.get(i).i = entries.get(j).i;
@ -71,7 +72,11 @@ public class ElementOrder implements ElementOrderer.OrderInterface<String> {
entries.set(i, entries.get(j));
entries.set(j, x);
circuit.modified();
circuitComponent.modify(circuit -> {
VisualElement y = elements.get(index1);
elements.set(index1, elements.get(index2));
elements.set(index2, y);
});
}
private final static class Entry {

View File

@ -61,6 +61,7 @@ public class VisualElement implements Drawable, Movable, AttributeListener {
this.elementName = proto.elementName;
this.elementAttributes = new ElementAttributes(proto.elementAttributes);
setPos(new Vector(proto.pos));
this.shapeFactory=proto.shapeFactory;
}
/**
@ -82,7 +83,7 @@ public class VisualElement implements Drawable, Movable, AttributeListener {
}
@Override
public void attributeChanged(Key key) {
public void attributeChanged() {
shape = null;
resetGeometry();
}

View File

@ -104,6 +104,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
private static final Icon ICON_ZOOM_IN = IconCreator.create("View-zoom-in.png");
private static final Icon ICON_ZOOM_OUT = IconCreator.create("View-zoom-out.png");
private static final Icon ICON_HELP = IconCreator.create("help.png");
private final CircuitComponent circuitComponent;
private final ToolTipAction save;
private final ElementLibrary library;
@ -193,6 +194,8 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
createEditMenu(menuBar);
toolBar.add(circuitComponent.getUndoAction().createJButtonNoText());
toolBar.add(circuitComponent.getRedoAction().createJButtonNoText());
toolBar.add(circuitComponent.getDeleteAction().createJButtonNoText());
toolBar.addSeparator();
@ -473,7 +476,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
ToolTipAction orderInputs = new ToolTipAction(Lang.get("menu_orderInputs")) {
@Override
public void actionPerformed(ActionEvent e) {
ElementOrder o = new ElementOrder(circuitComponent.getCircuit(),
ElementOrder o = new ElementOrder(circuitComponent,
element -> element.equalsDescription(In.DESCRIPTION)
|| element.equalsDescription(Clock.DESCRIPTION));
new ElementOrderer<>(Main.this, Lang.get("menu_orderInputs"), o).showDialog();
@ -483,7 +486,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
ToolTipAction orderOutputs = new ToolTipAction(Lang.get("menu_orderOutputs")) {
@Override
public void actionPerformed(ActionEvent e) {
ElementOrder o = new ElementOrder(circuitComponent.getCircuit(),
ElementOrder o = new ElementOrder(circuitComponent,
element -> element.equalsDescription(Out.DESCRIPTION)
|| element.equalsDescription(Out.LEDDESCRIPTION));
new ElementOrderer<>(Main.this, Lang.get("menu_orderOutputs"), o).showDialog();

View File

@ -6,6 +6,7 @@ import de.neemann.digital.core.io.Out;
import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.gui.components.CircuitComponent;
import de.neemann.digital.gui.components.modification.ModifyAttribute;
import de.neemann.digital.lang.Lang;
import de.neemann.gui.Screen;
@ -71,11 +72,9 @@ public class NumberingWizard extends JDialog implements CircuitComponent.WizardN
if (clicked.equalsDescription(In.DESCRIPTION)
|| clicked.equalsDescription(Clock.DESCRIPTION)
|| clicked.equalsDescription(Out.DESCRIPTION)) {
clicked.getElementAttributes().set(Keys.PINNUMBER, pinNumber);
circuitComponent.modify(new ModifyAttribute<>(clicked, Keys.PINNUMBER, pinNumber));
pinNumber++;
setPinNumber(pinNumber);
circuitComponent.hasChanged();
circuitComponent.getCircuit().modified();
}
}

View File

@ -89,7 +89,7 @@ public final class Settings implements AttributeListener {
}
@Override
public void attributeChanged(Key key) {
public void attributeChanged() {
XStream xStream = Circuit.getxStream();
try (Writer out = new OutputStreamWriter(new FileOutputStream(filename), "utf-8")) {
out.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");

View File

@ -8,6 +8,8 @@ import de.neemann.digital.core.element.ImmutableList;
import de.neemann.digital.core.element.Key;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.*;
import de.neemann.digital.gui.components.modification.Modification;
import de.neemann.digital.gui.components.modification.ModifyAttribute;
import de.neemann.digital.draw.graphics.*;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.library.ElementNotFoundException;
@ -16,6 +18,7 @@ import de.neemann.digital.draw.library.LibraryNode;
import de.neemann.digital.draw.shapes.Drawable;
import de.neemann.digital.draw.shapes.ShapeFactory;
import de.neemann.digital.gui.Main;
import de.neemann.digital.gui.components.modification.ModifyAttributes;
import de.neemann.digital.gui.sync.NoSync;
import de.neemann.digital.gui.sync.Sync;
import de.neemann.digital.lang.Lang;
@ -53,6 +56,9 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
* The delete icon, also used from {@link de.neemann.digital.gui.components.terminal.TerminalDialog}
*/
public static final Icon ICON_DELETE = IconCreator.create("delete.png");
private static final Icon ICON_UNDO = IconCreator.create("edit-undo.png");
private static final Icon ICON_REDO = IconCreator.create("edit-redo.png");
private static final String DEL_ACTION = "myDelAction";
private static final String ESC_ACTION = "myEscAction";
private static final int MOUSE_BORDER_SMALL = 10;
@ -76,6 +82,8 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
private final AbstractAction copyAction;
private final AbstractAction pasteAction;
private final AbstractAction rotateAction;
private final ToolTipAction undoAction;
private final ToolTipAction redoAction;
private Circuit circuit;
private MouseController activeMouseController;
@ -89,6 +97,10 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
private boolean lockMessageShown = false;
private boolean antiAlias = true;
private ArrayList<Modification> modifications;
private Circuit initialCircuit;
private int undoPosition;
/**
* Creates a new instance
@ -162,6 +174,20 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
}
}.setToolTip(Lang.get("menu_delete_tt"));
undoAction = new ToolTipAction(Lang.get("menu_undo"), ICON_UNDO) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
undo();
}
}.setToolTip(Lang.get("menu_undo_tt"));
redoAction = new ToolTipAction(Lang.get("menu_redo"), ICON_REDO) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
redo();
}
}.setToolTip(Lang.get("menu_redo_tt"));
Action escapeAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
@ -244,12 +270,36 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
VisualElement ve = circuit.getElementAt(pos);
if (ve != null && library.isProgrammable(ve.getElementName())) {
boolean blown = ve.getElementAttributes().get(Keys.BLOWN);
ve.getElementAttributes().set(Keys.BLOWN, !blown);
circuit.modified();
hasChanged();
modify(new ModifyAttribute<>(ve, Keys.BLOWN, !blown));
}
}
/**
* Apply a modification
*
* @param modification the modification
*/
public void modify(Modification modification) {
modification.modify(circuit);
addModificationAlreadyMade(modification);
}
/**
* Add a modification already made
*
* @param modification the modification
*/
public void addModificationAlreadyMade(Modification modification) {
while (modifications.size() > undoPosition)
modifications.remove(modifications.size() - 1);
redoAction.setEnabled(false);
modifications.add(modification);
undoPosition = modifications.size();
undoAction.setEnabled(true);
circuit.modified();
hasChanged();
}
/**
* invalidates the image buffer and calls repaint();
*/
@ -258,6 +308,38 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
repaint();
}
/**
* undo last action
*/
public void undo() {
if (undoPosition > 0) {
circuit = new Circuit(initialCircuit);
undoPosition--;
for (int i = 0; i < undoPosition; i++)
modifications.get(i).modify(circuit);
redoAction.setEnabled(true);
if (undoPosition == 0)
undoAction.setEnabled(false);
circuit.modified();
hasChanged();
}
}
/**
* redo last undo
*/
public void redo() {
if (undoPosition < modifications.size()) {
modifications.get(undoPosition).modify(circuit);
undoPosition++;
if (undoPosition == modifications.size())
redoAction.setEnabled(false);
undoAction.setEnabled(true);
hasChanged();
}
}
/**
* @return the main frame
*/
@ -559,6 +641,11 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
}
this.circuit = circuit;
modifications = new ArrayList<>();
initialCircuit = new Circuit(circuit);
undoPosition = 0;
undoAction.setEnabled(false);
redoAction.setEnabled(false);
circuit.addListener(this);
@ -646,10 +733,8 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
}
}
}.setToolTip(Lang.get("attr_help_tt")));
if (attributeDialog.showDialog()) {
circuit.modified();
hasChanged();
}
if (attributeDialog.showDialog())
addModificationAlreadyMade(new ModifyAttributes(vp));
}
} catch (ElementNotFoundException ex) {
// do nothing if element not found!
@ -679,6 +764,20 @@ public class CircuitComponent extends JComponent implements Circuit.ChangedListe
return locked;
}
/**
* @return undo action
*/
public ToolTipAction getUndoAction() {
return undoAction;
}
/**
* @return redo action
*/
public ToolTipAction getRedoAction() {
return redoAction;
}
private class MouseDispatcher extends MouseAdapter implements MouseMotionListener {
private Vector pos;
private boolean isMoved;

View File

@ -0,0 +1,12 @@
package de.neemann.digital.gui.components.modification;
import de.neemann.digital.draw.elements.Circuit;
/**
* Created by hneemann on 25.05.17.
*/
public interface Modification {
void modify(Circuit circuit);
}

View File

@ -0,0 +1,27 @@
package de.neemann.digital.gui.components.modification;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.graphics.Vector;
/**
* Created by hneemann on 25.05.17.
*/
public abstract class ModificationOfVisualElement implements Modification {
private final Vector pos;
private final String name;
public ModificationOfVisualElement(VisualElement ve) {
pos = ve.getPos();
name = ve.getElementName();
}
public VisualElement getVisualElement(Circuit circuit) {
for (VisualElement ve : circuit.getElements()) {
if (ve.getPos().equals(pos) && ve.getElementName().equals(name))
return ve;
}
throw new RuntimeException("internal error: Element not found!");
}
}

View File

@ -0,0 +1,39 @@
package de.neemann.digital.gui.components.modification;
import de.neemann.digital.draw.elements.Circuit;
import java.util.ArrayList;
/**
* Created by hneemann on 25.05.17.
*/
public final class Modifications implements Modification {
private final ArrayList<Modification> modifications;
private Modifications(ArrayList<Modification> modifications) {
this.modifications = modifications;
}
@Override
public void modify(Circuit circuit) {
for (Modification m : modifications)
m.modify(circuit);
}
public static final class Builder {
private final ArrayList<Modification> list;
public Builder() {
list = new ArrayList<>();
}
public Builder add(Modification m) {
list.add(m);
return this;
}
public Modification build() {
return new Modifications(list);
}
}
}

View File

@ -0,0 +1,26 @@
package de.neemann.digital.gui.components.modification;
import de.neemann.digital.core.element.Key;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
/**
* Created by hneemann on 25.05.17.
*/
public class ModifyAttribute<VALUE> extends ModificationOfVisualElement {
private final Key<VALUE> key;
private final VALUE value;
public ModifyAttribute(VisualElement ve, Key<VALUE> key, VALUE value) {
super(ve);
this.key = key;
this.value = value;
}
@Override
public void modify(Circuit circuit) {
VisualElement ve = getVisualElement(circuit);
ve.getElementAttributes().set(key, value);
}
}

View File

@ -0,0 +1,24 @@
package de.neemann.digital.gui.components.modification;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
/**
* Created by hneemann on 25.05.17.
*/
public class ModifyAttributes extends ModificationOfVisualElement {
private final ElementAttributes attributes;
public ModifyAttributes(VisualElement ve) {
super(ve);
attributes = new ElementAttributes(ve.getElementAttributes());
}
@Override
public void modify(Circuit circuit) {
VisualElement ve = getVisualElement(circuit);
ve.getElementAttributes().getValuesFrom(attributes);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

231
src/main/svg/edit-redo.svg Normal file
View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:export-ydpi="90.000000"
inkscape:export-xdpi="90.000000"
inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
width="48px"
height="48px"
id="svg11300"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/actions"
sodipodi:docname="edit-redo.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs3">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 24 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="48 : 24 : 1"
inkscape:persp3d-origin="24 : 16 : 1"
id="perspective31" />
<linearGradient
inkscape:collect="always"
id="linearGradient2240">
<stop
style="stop-color:#99b00b;stop-opacity:1;"
offset="0"
id="stop2242" />
<stop
style="stop-color:#99b00b;stop-opacity:0;"
offset="1"
id="stop2244" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2232">
<stop
style="stop-color:#788600;stop-opacity:1;"
offset="0"
id="stop2234" />
<stop
style="stop-color:#788600;stop-opacity:0;"
offset="1"
id="stop2236" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4991">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4993" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop4995" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient8662">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop8664" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop8666" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8662"
id="radialGradient8668"
cx="24.837126"
cy="36.421127"
fx="24.837126"
fy="36.421127"
r="15.644737"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.536723,-5.825329e-14,16.87306)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient2187"
inkscape:collect="always">
<stop
id="stop2189"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop2191"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2187"
id="linearGradient1764"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.813471e-16,-1.171926,1.171926,1.813471e-16,1.782801,54.10111)"
x1="17.060806"
y1="11.39502"
x2="12.624337"
y2="12.583769" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4991"
id="radialGradient4997"
cx="16.563837"
cy="11.132236"
fx="16.563837"
fy="11.132236"
r="19.0625"
gradientTransform="matrix(-1.290127e-2,1.685197,1.713082,1.311475e-2,-1.041499,-10.11571)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2232"
id="linearGradient2238"
x1="33"
y1="35.75"
x2="31.5"
y2="42.5"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2240"
id="linearGradient2246"
x1="33"
y1="35.75"
x2="31.5"
y2="42.5"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
stroke="#788600"
fill="#99b00b"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.25490196"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="12.500477"
inkscape:cy="33.008096"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:showpageshadow="false"
inkscape:window-width="892"
inkscape:window-height="818"
inkscape:window-x="368"
inkscape:window-y="30" />
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:source>http://jimmac.musichall.cz</dc:source>
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
<dc:title>Edit Redo</dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>edit</rdf:li>
<rdf:li>redo</rdf:li>
<rdf:li>again</rdf:li>
<rdf:li>reapply</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
transform="matrix(1.489736,0.000000,0.000000,-1.001252,-12.64716,75.31260)"
d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
sodipodi:ry="8.3968935"
sodipodi:rx="15.644737"
sodipodi:cy="36.421127"
sodipodi:cx="24.837126"
id="path8660"
style="opacity:0.14117647;color:#000000;fill:url(#radialGradient8668);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
style="opacity:1;color:#000000;fill:url(#linearGradient2246);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient2238);stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
d="M 38.37476,45.034369 C -1.6510486,46.355509 4.6747954,12.29355 25.49479,12.49765 L 25.49479,3.1222396 L 42.143271,17.708819 L 25.49479,33.006349 C 25.49479,33.006349 25.49479,23.337969 25.49479,23.337969 C 11.43168,22.751999 7.3172614,44.770549 38.37476,45.034369 z "
id="path1432"
sodipodi:nodetypes="ccccccc" />
<path
sodipodi:nodetypes="ccccccc"
id="path2177"
d="M 16.92492,39.315519 C 5.2018204,33.235892 8.7371274,13.087489 26.5085,13.549959 L 26.5085,5.4508678 C 26.5085,5.4508678 40.556238,17.714589 40.556238,17.714589 L 26.5085,30.658617 C 26.5085,30.658617 26.5085,22.380979 26.5085,22.380979 C 11.66865,22.032709 12.34859,35.138579 16.92492,39.315519 z "
style="opacity:0.69886361;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1764);stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
<path
style="opacity:0.49431817;color:#000000;fill:url(#radialGradient4997);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 26.036989,4.5686095 L 36.723727,14.798241 C 29.786227,14.79824 32.036989,23.735424 25.911989,26.610424 L 25.974489,22.943609 C 10.786989,22.881109 11.661989,38.443609 22.724489,42.693609 C 3.6363414,37.811681 6.2869904,13.381109 25.911989,12.88111 L 26.036989,4.5686095 z "
id="path4989"
sodipodi:nodetypes="ccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.1 KiB

232
src/main/svg/edit-undo.svg Normal file
View File

@ -0,0 +1,232 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:export-ydpi="45"
inkscape:export-xdpi="45"
inkscape:export-filename="/home/hneeman/Dokumente/Java/Journal/res/drawable-ldpi/undo.png"
width="48px"
height="48px"
id="svg11300"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="edit-undo.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs3">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 24 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="48 : 24 : 1"
inkscape:persp3d-origin="24 : 16 : 1"
id="perspective31" />
<linearGradient
inkscape:collect="always"
id="linearGradient2326">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2328" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop2330" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2316">
<stop
style="stop-color:#c4a000;stop-opacity:1;"
offset="0"
id="stop2318" />
<stop
style="stop-color:#c4a000;stop-opacity:0;"
offset="1"
id="stop2320" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2308">
<stop
style="stop-color:#edd400;stop-opacity:1;"
offset="0"
id="stop2310" />
<stop
style="stop-color:#edd400;stop-opacity:0;"
offset="1"
id="stop2312" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient8662">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop8664" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop8666" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8662"
id="radialGradient8668"
cx="24.837126"
cy="36.421127"
fx="24.837126"
fy="36.421127"
r="15.644737"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.536723,-6.227265e-14,16.87306)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient2187"
inkscape:collect="always">
<stop
id="stop2189"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop2191"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2187"
id="linearGradient1764"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.813471e-16,-1.171926,-1.171926,1.813471e-16,46.17440,54.10111)"
x1="17.060806"
y1="11.39502"
x2="12.624337"
y2="12.583769" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2308"
id="linearGradient2314"
x1="26.5"
y1="34.25"
x2="26.25"
y2="43.571831"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2316"
id="linearGradient2322"
x1="26.5"
y1="34.25"
x2="26.25"
y2="43.571831"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2326"
id="radialGradient2332"
cx="15.09403"
cy="13.282721"
fx="15.09403"
fy="13.282721"
r="10.16466"
gradientTransform="matrix(2.496031,-1.151905e-16,1.061756e-16,2.300689,-25.12402,-17.82636)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
stroke="#c4a000"
fill="#edd400"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.25490196"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8284271"
inkscape:cx="-19.855325"
inkscape:cy="-15.183692"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:showpageshadow="false"
inkscape:window-width="891"
inkscape:window-height="818"
inkscape:window-x="0"
inkscape:window-y="30"
inkscape:window-maximized="0" />
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:source>http://jimmac.musichall.cz</dc:source>
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
<dc:title>Edit Undo</dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>edit</rdf:li>
<rdf:li>undo</rdf:li>
<rdf:li>revert</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
transform="matrix(-1.489736,0.000000,0.000000,-1.001252,60.60436,75.31260)"
d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
sodipodi:ry="8.3968935"
sodipodi:rx="15.644737"
sodipodi:cy="36.421127"
sodipodi:cx="24.837126"
id="path8660"
style="opacity:0.14117647;color:#000000;fill:url(#radialGradient8668);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
style="opacity:1;color:#000000;fill:url(#linearGradient2314);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient2322);stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
d="M 9.582441,45.034369 C 49.608249,46.355509 43.282405,12.29355 22.462411,12.49765 L 22.462411,3.1222396 L 5.8139298,17.708819 L 22.462411,33.006349 C 22.462411,33.006349 22.462411,23.337969 22.462411,23.337969 C 36.525521,22.751999 40.639939,44.770549 9.582441,45.034369 z "
id="path1432"
sodipodi:nodetypes="ccccccc" />
<path
sodipodi:nodetypes="ccccccc"
id="path2177"
d="M 31.032281,39.315519 C 42.75538,33.235892 39.220073,13.087489 21.448701,13.549959 L 21.448701,5.4508678 C 21.448701,5.4508678 7.4009628,17.714589 7.4009628,17.714589 L 21.448701,30.658617 C 21.448701,30.658617 21.448701,22.380979 21.448701,22.380979 C 36.288551,22.032709 35.608611,35.138579 31.032281,39.315519 z "
style="opacity:0.69886361;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1764);stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
<path
style="opacity:0.51136364;color:#000000;fill:url(#radialGradient2332);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 6.6291261,17.682797 L 12.28598,23.074486 C 18.561553,22.897709 15.733126,16.710525 26.958446,13.616933 L 22.008699,12.998214 L 21.92031,4.3361562 L 6.6291261,17.682797 z "
id="path2324"
sodipodi:nodetypes="cccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -16,6 +16,8 @@
./expicon.sh View-zoom-fit
./expicon.sh View-zoom-in
./expicon.sh View-zoom-out
./expicon.sh edit-redo
./expicon.sh edit-undo
./exptest.sh testFailed
./exptest.sh testPassed