This commit is contained in:
bancika
2009-12-20 17:54:12 +00:00
commit 02d70eae6f
172 changed files with 8291 additions and 0 deletions
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="lib/xstream-1.3.1.jar"/>
<classpathentry kind="lib" path="lib/junit-4.7.jar"/>
<classpathentry kind="lib" path="lib/iText-2.1.7.jar"/>
<classpathentry kind="lib" path="lib/cloning-1.5.jar"/>
<classpathentry kind="lib" path="lib/objenesis-1.1.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/GUI-Framework"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>DIYLC</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
File diff suppressed because one or more lines are too long
@@ -0,0 +1,31 @@
<map>
<entry>
<string>defaults</string>
<map>
<entry>
<string>com.diyfever.diylc.components.MockComponentInstance:C</string>
<com.diyfever.diylc.model.measures.Capacitance>
<value>22.0</value>
<unit class="com.diyfever.diylc.model.measures.CapacitanceUnit">uF</unit>
</com.diyfever.diylc.model.measures.Capacitance>
</entry>
<entry>
<string>com.diyfever.diylc.components.MockComponentInstance:Color</string>
<awt-color>
<red>255</red>
<green>0</green>
<blue>0</blue>
<alpha>255</alpha>
</awt-color>
</entry>
</map>
</entry>
<entry>
<string>lastPath</string>
<string>C:\Documents and Settings\Branislav Stojkovic\Desktop</string>
</entry>
<entry>
<string>metric</string>
<boolean>true</boolean>
</entry>
</map>
@@ -0,0 +1,9 @@
log4j.rootLogger = DEBUG, fileout, stdout
log4j.appender.fileout = com.diyfever.gui.miscutils.NewLogForEachRunFileAppender
log4j.appender.fileout.layout.ConversionPattern = %d{ABSOLUTE} %5p [%t] %c{1} - %m%n
log4j.appender.fileout.layout = org.apache.log4j.PatternLayout
log4j.appender.fileout.File = log/log.log
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p [%t] %c{1} - %m%n
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
@@ -0,0 +1,86 @@
package com.diyfever.diylc;
import javax.swing.UIManager;
import org.apache.log4j.PropertyConfigurator;
import com.diyfever.diylc.gui.MainFrame;
/**
*
* @author Branislav Stojkovic
*/
public class DIYLCStarter {
/**
* @param args
*/
public static void main(String[] args) {
PropertyConfigurator.configure("log4j.properties");
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
MainFrame mainFrame = new MainFrame();
// Presenter p = new Presenter(mainFrame);
//
// p.installPlugin(new ToolBox());
// p.installPlugin(new FileManager());
// p.installPlugin(new ClipboardManager());
// p.installPlugin(new StatusBar());
// p.installPlugin(new CanvasPlugin());
//
// Project project = new Project();
// project.getComponents().add(new MockComponentInstance());
// p.loadProject(project);
// panel.setPreferredSize(new Dimension(2000, 1500));
// RulerScrollPane scrollPane = new RulerScrollPane(panel);
// JFrame f = new JFrame("Test");
// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// f.add(scrollPane);
// f.setPreferredSize(new Dimension(800, 600));
// f.pack();
// f.setLocationRelativeTo(null);
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
// List<Property> properties = ClassProcessor
// .extractProperties(MockComponent.class);
// MockComponent component = new MockComponent();
// for (Property p : properties) {
// try {
// p.readFrom(component);
// } catch (IllegalArgumentException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// PropertyEditorDialog.showFor(null, properties);
// for (Property p : properties) {
// try {
// p.writeTo(component);
// } catch (IllegalArgumentException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println(p);
// }
// System.out.println(p.getComponentTypes());
}
}
@@ -0,0 +1,66 @@
package com.diyfever.diylc.common;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
public class ActivePoint extends Point {
private static final long serialVersionUID = 1L;
private List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
public ActivePoint() {
super();
}
public ActivePoint(int x, int y) {
super(x, y);
}
public ActivePoint(Point p) {
super(p);
}
public void addPropertyChangeListener(PropertyChangeListener element) {
listeners.add(element);
}
public boolean removePropertyChangeListener(Object o) {
return listeners.remove(o);
}
@Override
public void setLocation(double x, double y) {
this.setLocation(new Point2D.Double(x, y));
}
@Override
public void setLocation(int x, int y) {
this.setLocation(new Point(x, y));
}
@Override
public void setLocation(Point p) {
for (PropertyChangeListener listener : listeners) {
listener.propertyChange(new PropertyChangeEvent(this, "value",
this, p));
}
super.setLocation(p);
}
public void setLocationSilent(double x, double y) {
super.setLocation(x, y);
}
public void setLocationSilent(int x, int y) {
super.setLocation(x, y);
}
public void setLocationSilent(Point p) {
super.setLocation(p);
}
}
@@ -0,0 +1,7 @@
package com.diyfever.diylc.common;
public class BadPositionException extends Exception {
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,47 @@
package com.diyfever.diylc.common;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.diyfever.diylc.model.IComponentInstance;
public class ComponentSelection extends ArrayList<IComponentInstance> implements
Transferable {
private static final long serialVersionUID = 1L;
public static final DataFlavor listFlavor = new DataFlavor(List.class,
"Java List");
public ComponentSelection() {
super();
}
public ComponentSelection(Collection<IComponentInstance> selectedComponents) {
super(selectedComponents);
}
@Override
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
if (flavor.equals(listFlavor)) {
return this;
}
throw new UnsupportedFlavorException(flavor);
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { listFlavor };
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(listFlavor);
}
}
@@ -0,0 +1,102 @@
package com.diyfever.diylc.common;
import java.awt.Point;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.diyfever.diylc.model.IComponentInstance;
import com.diyfever.diylc.model.VisibilityPolicy;
public class ControlPointWrapper {
private String name;
private ActivePoint value;
private Method setter;
private Method getter;
private boolean editable;
private boolean sticky;
private VisibilityPolicy visibilityPolicy;
public ControlPointWrapper(String name, Method getter, Method setter,
boolean editable, boolean sticky, VisibilityPolicy visibilityPolicy) {
super();
this.name = name;
this.getter = getter;
this.setter = setter;
this.editable = editable;
this.sticky = sticky;
this.visibilityPolicy = visibilityPolicy;
}
public void readFrom(IComponentInstance component)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
Object object = getter.invoke(component);
if (object instanceof ActivePoint) {
value = (ActivePoint) getter.invoke(component);
} else {
value = new ActivePoint((Point) object);
}
}
public void writeTo(IComponentInstance component)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
setter.invoke(component, value);
}
public String getName() {
return name;
}
public boolean isEditable() {
return editable;
}
public boolean isSticky() {
return sticky;
}
public ActivePoint getValue() {
return value;
}
public void setValue(ActivePoint value) {
this.value = value;
}
public VisibilityPolicy getVisibilityPolicy() {
return visibilityPolicy;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ControlPointWrapper other = (ControlPointWrapper) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
@@ -0,0 +1,6 @@
package com.diyfever.diylc.common;
public enum DrawOption {
SELECTION, ZOOM, GRID, CONTROL_POINTS, ANTIALIASING;
}
@@ -0,0 +1,55 @@
package com.diyfever.diylc.common;
import java.awt.Rectangle;
import com.diyfever.diylc.model.IComponentType;
import com.diyfever.diylc.model.Project;
/**
* Enumerates all possible events between {@link IPlugInPort} and
* {@link IPlugIn}. Some events overlap so be careful which ones you subscribe
* for and how you process them.
*
* @author Branislav Stojkovic
*/
public enum EventType {
/**
* Called when zoom level changes. Typically only one parameter of type
* {@link Double} is passed with new zoom level.
*/
ZOOM_CHANGED,
/**
* Called when a new project is loaded. New {@link Project} is the first
* parameter. Boolean flag is the second parameter and it's true when new
* project is loaded, false when the same project has been either reloaded
* or loaded with undo/redo operations.
*/
PROJECT_LOADED,
/**
* Called when selection rectangle is changed. Object of type
* {@link Rectangle} is the only parameter and it contains the new selection
* rectangle.
*/
SELECTION_RECT_CHANGED,
/**
* Called when component selection is changed. New
* {@link ComponentSelection} is attached as a parameter.
*/
SELECTION_CHANGED,
/**
* Called when display needs to be repainted. No parameters are passed.
*/
REPAINT,
/**
* Called when new component slot has been changed. The only parameter is
* {@link IComponentType} and may be null.
*/
SLOT_CHANGED,
/**
* Called when the current project has been modified. Two instances of
* {@link Project} are passed as parameters, one before and one after the
* change. The third parameter is a string containing change description.
*/
PROJECT_MODIFIED;
}
@@ -0,0 +1,20 @@
package com.diyfever.diylc.common;
import com.diyfever.gui.simplemq.IMessageListener;
/**
* Interface for plug-ins.
*
* @author Branislav Stojkovic
*/
public interface IPlugIn extends IMessageListener<EventType> {
/**
* Method that connects the plug-in with {@link IPlugInPort}. Called by the
* application when plug-in is installed.
*
* @param plugInPort
*/
void connect(IPlugInPort plugInPort);
}
@@ -0,0 +1,277 @@
package com.diyfever.diylc.common;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Area;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.SwingConstants;
import javax.swing.JPopupMenu.Separator;
import com.diyfever.diylc.model.ComponentLayer;
import com.diyfever.diylc.model.IComponentInstance;
import com.diyfever.diylc.model.IComponentType;
import com.diyfever.diylc.model.Project;
import com.diyfever.gui.simplemq.IMessageListener;
import com.diyfever.gui.simplemq.MessageDispatcher;
import com.diyfever.gui.update.VersionNumber;
/**
* Interface for communication between plug-ins and the application. Plug-ins
* may acquire information or make changes through this interface. Application
* events are dispatched to plug-ins through {@link MessageDispatcher}
*
* @author Branislav Stojkovic
*
* @see IPlugIn
* @see MessageDispatcher
* @see IMessageListener
* @see EventType
*/
public interface IPlugInPort {
/**
* Returns size of the canvas that takes project dimensions into account as
* well as zoom level. Each dimension is calculated as the product of the
* actual size and the number of pixels per unit. If <code>useZoom</code> is
* set to true, the result is scaled by zoom factor.
*
* @param useZoom
*
* @return canvas dimensions
*/
Dimension getCanvasDimensions(boolean useZoom);
/**
* Returns an instance of {@link Cursor} that should be used at the
* specified location.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
* @return cursor
*/
Cursor getCursorAt(Point point);
/**
* Returns an instance of currently loaded project.
*
* @return
*/
Project getCurrentProject();
/**
* Loads specified {@link Project}.
*
* @param project
* @param freshStart
*/
void loadProject(Project project, boolean freshStart);
/**
* Returns all available {@link IComponentType}s classified by category.
* Result is a {@link Map} between category name to a {@link List} of all
* {@link IComponentType}s that share that category name.
*
* @return
*/
Map<String, List<IComponentType>> getComponentTypes();
/**
* Draws project on the provided {@link Graphics2D}.
*
* @param g2d
*/
void draw(Graphics2D g2d, EnumSet<DrawOption> drawProperties);
/**
* Injects a custom GUI panels provided by the plug-in and desired position
* in the window. Application will layout plug-in panels accordingly. <br>
* Valid positions are:
* <ul>
* <li> {@link SwingConstants#TOP}</li>
* <li> {@link SwingConstants#BOTTOM}</li>
* <li> {@link SwingConstants#LEFT}</li>
* <li> {@link SwingConstants#RIGHT}</li>
* </ul>
*
* Center position is reserved for the main canvas panel and cannot be used.
*
* @param component
* @param position
* @throws BadPositionException
* in case invalid position is specified
*/
void injectGUIComponent(JComponent component, int position)
throws BadPositionException;
/**
* Injects a custom menu action into application's main menu. If
* <code>action</code> is set to null {@link Separator} will be added. If
* the specified menu does not exist it will be automatically created.
*
* @param action
* {@link Action} to inser
* @param menuName
* name of the menu to insert into
*/
public void injectMenuAction(Action action, String menuName);
/**
* Returns current zoom level where <code>zoomLevel = 1.0d</code> means
* 100%.
*
* @return current zoom level
*/
double getZoomLevel();
/**
* Changes current zoom level where <code>zoomLevel = 1.0d</code> means 100%
*
* @param zoomLevel
* new zoom leve
*/
void setZoomLevel(double zoomLevel);
/**
* Note: point coordinates are scaled for zoom factor.
*
* @param point
*/
void pointClickedOn(Point point, boolean ctrlDown, boolean shiftDown,
boolean altDown);
/**
* Returns a list of currently selected components.
*
* @return
*/
ComponentSelection getSelectedComponents();
/**
* Returns the {@link Area} occupied by the component.
*
* @return
*/
Area getComponentArea(IComponentInstance component);
/**
* Notification that drag has been started from the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
*/
void dragStarted(Point point);
/**
* Checks if it's possible to drop over the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
* @return
*/
boolean dragOver(Point point);
/**
* Notification that drag has been ended in the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
*/
void dragEnded(Point point);
/**
* Returns current version number.
*
* @return
*/
VersionNumber getCurrentVersionNumber();
/**
* Adds a list of components to the project.
*
* @param components
* @param preferredPoint
*/
void addComponents(List<IComponentInstance> components, Point preferredPoint);
/**
* Checks if a certain layer is locked for editing.
*
* @param layer
* @return
*/
boolean isLayerLocked(ComponentLayer layer);
/**
* Changes layer's locked state.
*
* @param layer
* @param locked
*/
void setLayerLocked(ComponentLayer layer, boolean locked);
/**
* Checks if a certain layer is visible.
*
* @param layer
* @return
*/
boolean isLayerVisible(ComponentLayer layer);
/**
* Changes layer visibility.
*
* @param layer
* @param visible
*/
void setLayerVisible(ComponentLayer layer, boolean visible);
/**
* Sets default value for the specified property name for currently selected
* component types.
*
* @param propertyName
* display name for property
* @param value
* new default value, must not be null
*/
void setDefaultPropertyValue(String propertyName, Object value);
/**
* Returns a list of properties that are mutual for all the selected
* components. Resulting list may be empty if selected components do not
* have mutual properties or can be null if the selection is empty.
*
* @return
*/
List<PropertyWrapper> getMutualSelectionProperties();
/**
* Applies specified properties to all the selected components. If some of
* the properties are not applicable to some of the selected components an
* exception will be thrown.
*
* @param properties
* @throws Exception
*/
void applyPropertiesToSelection(List<PropertyWrapper> properties)
throws Exception;
// void setCursorIcon(Icon icon);
/**
* Sets the new component slot. Specified component type will be used to
* instantiate new component.
*/
void setNewComponentSlot(IComponentType componentType);
}
@@ -0,0 +1,139 @@
package com.diyfever.diylc.common;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.diyfever.diylc.model.IComponentInstance;
public class PropertyWrapper implements Cloneable {
private String name;
private Class<?> type;
private Object value;
private Method setter;
private Method getter;
private boolean defaultable;
public PropertyWrapper(String name, Class<?> type, Method getter,
Method setter, boolean defaultable) {
super();
this.name = name;
this.type = type;
this.getter = getter;
this.setter = setter;
this.defaultable = defaultable;
}
public void readFrom(IComponentInstance component)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
this.value = getter.invoke(component);
}
// public void readUniqueFrom(IComponentInstance component)
// throws IllegalArgumentException, IllegalAccessException,
// InvocationTargetException {
// Object newValue = getter.invoke(component);
// if (!newValue.equals(value)) {
// this.value = null;
// }
// }
public void writeTo(IComponentInstance component)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
setter.invoke(component, value);
}
public String getName() {
return name;
}
public Class<?> getType() {
return type;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public boolean isDefaultable() {
return defaultable;
}
public void setDefaultable(boolean defaultable) {
this.defaultable = defaultable;
}
// @Override
// public Object clone() throws CloneNotSupportedException {
// // Try to invoke clone method on value if possible.
// try {
// Method cloneMethod = value.getClass().getMethod("clone");
// return new Property(name, type, cloneMethod.invoke(value));
// } catch (Exception e) {
// }
// return new Property(name, type, value);
// }
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (defaultable ? 1231 : 1237);
result = prime * result + ((getter == null) ? 0 : getter.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((setter == null) ? 0 : setter.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PropertyWrapper other = (PropertyWrapper) obj;
if (defaultable != other.defaultable)
return false;
if (getter == null) {
if (other.getter != null)
return false;
} else if (!getter.equals(other.getter))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (setter == null) {
if (other.setter != null)
return false;
} else if (!setter.equals(other.setter))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
@Override
public String toString() {
return name + " = " + value;
}
}
@@ -0,0 +1,42 @@
package com.diyfever.diylc.gui;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.Icon;
import javax.swing.JComponent;
public class CustomGlassPane extends JComponent {
private static final long serialVersionUID = 1L;
private Icon icon;
public CustomGlassPane() {
super();
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
if (icon != null) {
repaint();
}
}
});
}
public void setCursorIcon(Icon icon) {
this.icon = icon;
}
@Override
public void paint(Graphics g) {
Point cursor = getMousePosition();
if ((icon != null) && (cursor != null)) {
Graphics2D g2d = (Graphics2D) g;
icon.paintIcon(this, g2d, cursor.x + 10, cursor.y + 10);
}
}
}
@@ -0,0 +1,162 @@
package com.diyfever.diylc.gui;
import java.io.File;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileFilter;
import com.diyfever.diylc.common.PropertyWrapper;
import com.diyfever.diylc.gui.components.OverwritePromptFileChooser;
import com.diyfever.diylc.gui.editor.PropertyEditorDialog;
import com.diyfever.diylc.plugins.file.BomDialog;
import com.diyfever.diylc.plugins.file.BomEntry;
import com.diyfever.diylc.plugins.online.view.LoginDialog;
import com.diyfever.diylc.plugins.online.view.NewUserDialog;
import com.diyfever.diylc.plugins.online.view.UploadDialog;
import com.diyfever.gui.AboutDialog;
import com.diyfever.gui.IFileChooserAccessory;
import com.diyfever.gui.ProgressDialog;
import com.diyfever.gui.miscutils.ConfigurationManager;
public class DialogFactory {
private static DialogFactory instance;
private static final String PATH_KEY = "lastPath";
public static DialogFactory getInstance() {
if (instance == null) {
instance = new DialogFactory();
}
return instance;
}
private JFrame mainFrame;
private File lastDirectory;
private DialogFactory() {
}
/**
* Sets the frame to be used as dialog parent. This should be called prior
* to any other methods in this class.
*
* @param mainFrame
*/
public void initialize(JFrame mainFrame) {
this.mainFrame = mainFrame;
String lastDirectoryPath = (String) ConfigurationManager.getInstance()
.getConfigurationItem(PATH_KEY);
if (lastDirectoryPath != null) {
lastDirectory = new File(lastDirectoryPath);
}
}
public PropertyEditorDialog createPropertyEditorDialog(
List<PropertyWrapper> properties) {
PropertyEditorDialog editor = new PropertyEditorDialog(mainFrame,
properties);
return editor;
}
public BomDialog createBomDialog(List<BomEntry> bom) {
BomDialog dialog = new BomDialog(mainFrame, bom);
return dialog;
}
public File showOpenDialog(FileFilter fileFilter, File initialFile,
String defaultExtension, IFileChooserAccessory accessory) {
JFileChooser openFileChooser = new JFileChooser();
initializeFileChooser(openFileChooser, fileFilter, initialFile,
defaultExtension, accessory);
int result = openFileChooser.showOpenDialog(mainFrame);
return processFileChooserResult(result, openFileChooser,
defaultExtension);
}
public File showSaveDialog(FileFilter fileFilter, File initialFile,
String defaultExtension, IFileChooserAccessory accessory) {
JFileChooser saveFileChooser = new OverwritePromptFileChooser();
initializeFileChooser(saveFileChooser, fileFilter, initialFile,
defaultExtension, accessory);
int result = saveFileChooser.showSaveDialog(mainFrame);
return processFileChooserResult(result, saveFileChooser,
defaultExtension);
}
private void initializeFileChooser(JFileChooser fileChooser,
FileFilter fileFilter, File initialFile, String defaultExtension,
IFileChooserAccessory accessory) {
if (accessory != null) {
accessory.install(fileChooser);
}
for (FileFilter filter : fileChooser.getChoosableFileFilters()) {
fileChooser.removeChoosableFileFilter(filter);
}
if (fileChooser instanceof OverwritePromptFileChooser) {
((OverwritePromptFileChooser) fileChooser).setFileFilter(
fileFilter, defaultExtension);
} else {
fileChooser.setFileFilter(fileFilter);
}
if (lastDirectory != null) {
fileChooser.setCurrentDirectory(lastDirectory);
}
fileChooser.setSelectedFile(initialFile);
}
private File processFileChooserResult(int result, JFileChooser fileChooser,
String defaultExtension) {
fileChooser.setAccessory(null);
if (result == JFileChooser.APPROVE_OPTION) {
lastDirectory = fileChooser.getCurrentDirectory();
ConfigurationManager.getInstance().setConfigurationItem(PATH_KEY,
lastDirectory.getAbsolutePath());
if (fileChooser.getSelectedFile().getAbsolutePath().contains(".")) {
return fileChooser.getSelectedFile();
} else {
return new File(fileChooser.getSelectedFile().getAbsoluteFile()
+ "." + defaultExtension);
}
} else {
return null;
}
}
public AboutDialog createAboutDialog(String appName, Icon icon,
String version, String author, String url, String mail,
String htmlContent) {
AboutDialog dialog = new AboutDialog(mainFrame, appName, icon, version,
author, url, mail, htmlContent);
return dialog;
}
public NewUserDialog createNewUserDialog() {
NewUserDialog dialog = new NewUserDialog(mainFrame);
return dialog;
}
public LoginDialog createLoginDialog() {
LoginDialog dialog = new LoginDialog(mainFrame);
return dialog;
}
public UploadDialog createUploadDialog() {
UploadDialog dialog = new UploadDialog(mainFrame);
return dialog;
}
public ProgressDialog createProgressDialog(String title,
String[] buttonCaptions, String description, boolean useProgress) {
ProgressDialog dialog = new ProgressDialog(mainFrame, title,
buttonCaptions, description, useProgress);
return dialog;
}
}
@@ -0,0 +1,44 @@
package com.diyfever.diylc.gui;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JComponent;
import com.diyfever.diylc.common.BadPositionException;
import com.diyfever.diylc.common.IPlugInPort;
/**
* Base interface for the main GUI component.
*
* @author Branislav Stojkovic
*/
public interface IView {
/**
* Adds a component to the view.
*
* @param component
* component to insert
* @param position
* target position
* @throws BadPositionException
*
* @see IPlugInPort#injectGUIComponent
*/
void addComponent(JComponent component, int position)
throws BadPositionException;
/**
* Adds a menu action.
*
* @param action
* action to insert
* @param menuName
* target menu name
*
* @see IPlugInPort#injectMenuAction
*/
void addMenuAction(Action action, String menuName);
void setCursorIcon(Icon icon);
}
@@ -0,0 +1,173 @@
package com.diyfever.diylc.gui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import com.diyfever.diylc.common.BadPositionException;
import com.diyfever.diylc.components.MockComponentInstance;
import com.diyfever.diylc.model.Project;
import com.diyfever.diylc.plugins.canvas.CanvasPlugin;
import com.diyfever.diylc.plugins.clipboard.ClipboardManager;
import com.diyfever.diylc.plugins.file.FileManager;
import com.diyfever.diylc.plugins.help.HelpManager;
import com.diyfever.diylc.plugins.online.OnlineManager;
import com.diyfever.diylc.plugins.statusbar.StatusBar;
import com.diyfever.diylc.plugins.toolbox.ToolBox;
import com.diyfever.diylc.presenter.Presenter;
public class MainFrame extends JFrame implements IView {
private static final long serialVersionUID = 1L;
private JPanel centerPanel;
private JPanel leftPanel;
private JPanel rightPanel;
private JPanel topPanel;
private JPanel bottomPanel;
private Presenter presenter;
private JMenuBar mainMenuBar;
private Map<String, JMenu> menuMap;
public MainFrame() {
super("DIYLC4");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(800, 600));
createBasePanels();
menuMap = new HashMap<String, JMenu>();
DialogFactory.getInstance().initialize(this);
this.presenter = new Presenter(this);
setTitle(getTitle() + " " + presenter.getCurrentVersionNumber());
presenter.installPlugin(new ToolBox());
presenter.installPlugin(new FileManager());
presenter.installPlugin(new ClipboardManager());
presenter.installPlugin(new OnlineManager());
presenter.installPlugin(new HelpManager());
presenter.installPlugin(new StatusBar());
presenter.installPlugin(new CanvasPlugin());
Project project = new Project();
project.getComponents().add(new MockComponentInstance());
presenter.loadProject(project, true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
presenter.dispose();
}
@Override
public void windowClosing(WindowEvent e) {
presenter.dispose();
}
});
// setGlassPane(new CustomGlassPane());
// getGlassPane().setVisible(true);
}
private void createBasePanels() {
Container c = new Container();
c.setLayout(new BorderLayout());
centerPanel = new JPanel(new BorderLayout());
c.add(centerPanel, BorderLayout.CENTER);
topPanel = new JPanel();
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
c.add(topPanel, BorderLayout.NORTH);
leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.X_AXIS));
c.add(leftPanel, BorderLayout.WEST);
bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
c.add(bottomPanel, BorderLayout.SOUTH);
rightPanel = new JPanel();
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.X_AXIS));
c.add(rightPanel, BorderLayout.EAST);
setContentPane(c);
}
private JMenuBar getMainMenuBar() {
if (mainMenuBar == null) {
mainMenuBar = new JMenuBar();
setJMenuBar(mainMenuBar);
}
return mainMenuBar;
}
// IView
@Override
public void addComponent(JComponent component, int position)
throws BadPositionException {
switch (position) {
case SwingConstants.TOP:
topPanel.add(component);
break;
case SwingConstants.LEFT:
leftPanel.add(component);
break;
case SwingConstants.BOTTOM:
bottomPanel.add(component);
break;
case SwingConstants.RIGHT:
rightPanel.add(component);
break;
case SwingConstants.CENTER:
centerPanel.add(component, BorderLayout.CENTER);
break;
default:
throw new BadPositionException();
}
pack();
}
@Override
public void addMenuAction(Action action, String menuName) {
JMenu menu;
if (menuMap.containsKey(menuName)) {
menu = menuMap.get(menuName);
} else {
menu = new JMenu(menuName);
menuMap.put(menuName, menu);
getMainMenuBar().add(menu);
}
if (action == null) {
menu.addSeparator();
} else {
menu.add(action);
}
}
@Override
public void setCursorIcon(Icon icon) {
// TODO Auto-generated method stub
}
}
@@ -0,0 +1,41 @@
package com.diyfever.diylc.gui.components;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
public class OverwritePromptFileChooser extends JFileChooser {
private static final long serialVersionUID = 1L;
private String defaultExtension;
public void approveSelection() {
File lSelectedFile;
if (getSelectedFile().getAbsolutePath().contains(".")) {
lSelectedFile = getSelectedFile();
} else {
lSelectedFile = new File(getSelectedFile().getAbsoluteFile() + "."
+ defaultExtension);
}
if (lSelectedFile != null && lSelectedFile.exists()) {
int lResponse = JOptionPane.showConfirmDialog(this, lSelectedFile
.getAbsolutePath()
+ " already exists.\nDo you " + "want to replace it?",
"Warning", JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE);
if (lResponse != JOptionPane.YES_OPTION) {
return;
}
}
super.approveSelection();
}
public void setFileFilter(FileFilter filter, String defaultExtension) {
this.defaultExtension = defaultExtension;
super.setFileFilter(filter);
}
}
@@ -0,0 +1,39 @@
package com.diyfever.diylc.gui.editor;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import com.diyfever.diylc.common.PropertyWrapper;
public class ColorEditor extends JLabel {
private static final long serialVersionUID = 1L;
public ColorEditor(final PropertyWrapper property) {
super("Click to edit");
setOpaque(true);
setHorizontalAlignment(SwingConstants.CENTER);
setBorder(BorderFactory.createEtchedBorder());
setBackground((Color) property.getValue());
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Color newColor = JColorChooser.showDialog(ColorEditor.this,
"Choose Color", getBackground());
if (newColor != null) {
property.setValue(newColor);
setBackground(newColor);
}
}
});
}
}
@@ -0,0 +1,26 @@
package com.diyfever.diylc.gui.editor;
import java.awt.Color;
import java.awt.Component;
import com.diyfever.diylc.common.PropertyWrapper;
import com.diyfever.diylc.model.measures.AbstractMeasure;
public class FieldEditorFactory {
public static Component createFieldEditor(PropertyWrapper property) {
if (property.getType().equals(String.class)) {
StringEditor editor = new StringEditor(property);
return editor;
}
if (property.getType().equals(Color.class)) {
ColorEditor editor = new ColorEditor(property);
return editor;
}
if (AbstractMeasure.class.isAssignableFrom(property.getType())) {
MeasureEditor editor = new MeasureEditor(property);
return editor;
}
return null;
}
}
@@ -0,0 +1,66 @@
package com.diyfever.diylc.gui.editor;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.JComboBox;
import com.diyfever.diylc.common.PropertyWrapper;
import com.diyfever.diylc.model.measures.AbstractMeasure;
import com.diyfever.gui.DoubleTextField;
public class MeasureEditor extends Container {
private static final long serialVersionUID = 1L;
@SuppressWarnings("unchecked")
public MeasureEditor(final PropertyWrapper property) {
setLayout(new BorderLayout());
final AbstractMeasure measure = ((AbstractMeasure) property.getValue());
DoubleTextField valueField = new DoubleTextField(measure.getValue());
valueField.addPropertyChangeListener(DoubleTextField.VALUE_PROPERTY,
new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
measure.setValue((Double) evt.getNewValue());
}
});
add(valueField, BorderLayout.CENTER);
try {
Method method = measure.getUnit().getClass().getMethod("values");
final JComboBox unitBox = new JComboBox((Object[]) method
.invoke(measure.getUnit()));
unitBox.setSelectedItem(measure.getUnit());
unitBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
measure.setUnit((Enum) unitBox.getSelectedItem());
}
});
add(unitBox, BorderLayout.EAST);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@@ -0,0 +1,140 @@
package com.diyfever.diylc.gui.editor;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import com.diyfever.diylc.common.PropertyWrapper;
import com.diyfever.gui.ButtonDialog;
public class PropertyEditorDialog extends ButtonDialog {
private static final Logger LOG = Logger
.getLogger(PropertyEditorDialog.class);
private static final long serialVersionUID = 1L;
private static final String DEFAULT_BOX_TOOLTIP = "<html>If this box is checked application will use the current value as a<br>default when creating new components of the same type</html>";
private List<PropertyWrapper> properties;
private Set<PropertyWrapper> defaultedProperties;
public PropertyEditorDialog(JFrame owner, List<PropertyWrapper> properties) {
super(owner, "Editor", new String[] { ButtonDialog.OK,
ButtonDialog.CANCEL });
LOG.debug("Creating property editor for: " + properties);
this.properties = properties;
this.defaultedProperties = new HashSet<PropertyWrapper>();
setMinimumSize(new Dimension(240, 40));
layoutGui();
setLocationRelativeTo(owner);
//
// setModal(true);
//
// JPanel holderPanel = new JPanel();
// holderPanel.setLayout(new BorderLayout());
// holderPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
//
// holderPanel.add(createEditorFields(), BorderLayout.CENTER);
// holderPanel.add(createButtonPanel(), BorderLayout.SOUTH);
//
// setContentPane(holderPanel);
//
//
// pack();
// setLocationRelativeTo(owner);
}
private JPanel createEditorFields() {
JPanel editorPanel = new JPanel(new GridBagLayout());
editorPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = GridBagConstraints.LINE_START;
for (PropertyWrapper property : properties) {
gbc.gridx = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
editorPanel.add(new JLabel(property.getName() + ": "), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
editorPanel
.add(FieldEditorFactory.createFieldEditor(property), gbc);
if (property.isDefaultable()) {
gbc.gridx = 2;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
editorPanel.add(createDefaultCheckBox(property), gbc);
}
gbc.gridy++;
}
return editorPanel;
}
private JCheckBox createDefaultCheckBox(final PropertyWrapper property) {
final JCheckBox checkBox = new JCheckBox();
checkBox.setToolTipText(DEFAULT_BOX_TOOLTIP);
checkBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (checkBox.isSelected()) {
defaultedProperties.add(property);
} else {
defaultedProperties.remove(property);
}
}
});
return checkBox;
}
public Set<PropertyWrapper> getDefaultedProperties() {
return defaultedProperties;
}
public static boolean showFor(JFrame owner, List<PropertyWrapper> properties) {
PropertyEditorDialog editor = new PropertyEditorDialog(owner,
properties);
editor.setVisible(true);
if (OK.equals(editor.getSelectedButtonCaption())) {
return true;
}
return false;
}
@Override
protected JComponent getMainComponent() {
return createEditorFields();
}
}
@@ -0,0 +1,40 @@
package com.diyfever.diylc.gui.editor;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import com.diyfever.diylc.common.PropertyWrapper;
public class StringEditor extends JTextField {
private static final long serialVersionUID = 1L;
private final PropertyWrapper property;
public StringEditor(PropertyWrapper property) {
super(property.getValue() == null ? "" : (String) property.getValue());
this.property = property;
getDocument().addDocumentListener(new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
textChanged();
}
@Override
public void insertUpdate(DocumentEvent e) {
textChanged();
}
@Override
public void removeUpdate(DocumentEvent e) {
textChanged();
}
});
}
private void textChanged() {
property.setValue(getText());
}
}
@@ -0,0 +1,71 @@
package com.diyfever.diylc.images;
import javax.swing.Icon;
import javax.swing.ImageIcon;
/**
* Loads image resources as Icons.
*
* @author Branislav Stojkovic
*/
public enum IconLoader {
Delete("delete.png"),
Add("add.png"),
FolderOut("folder_out.png"),
Garbage("garbage.png"),
DiskBlue("disk_blue.png"),
SaveAs("save_as.png"),
Exit("exit.png"),
DocumentPlainYellow("document_plain_yellow.png"),
PhotoScenery("photo_scenery.png"),
LightBulbOn("lightbulb_on.png"),
LightBulbOff("lightbulb_off.png"),
NotebookAdd("notebook_add.png"),
FormGreen("form_green.png"),
Gears("gears.png"),
About("about.png"),
Donate("donate.gif"),
WindowColors("window_colors.png"),
WindowGear("window_gear.png"),
NavigateCheck("navigate_check.png"),
Undo("undo.png"),
Error("error.png"),
Warning("warning.png"),
ZoomSmall("zoom_small.png"),
MoveSmall("move_small.png"),
Print("print.png"),
PDF("pdf.png"),
Excel("excel.png"),
CSV("csv.png"),
HTML("html.png"),
Image("image.png"),
Cut("cut.png"),
Copy("copy.png"),
Paste("paste.png"),
Selection("selection.png"),
BOM("bom.png"),
BlackBoard("blackboard.png"),
IdCard("id_card.png"),
IdCardAdd("id_card_add.png"),
Chest("chest.png"),
Upload("upload.png"),
Wrench("wrench.png"),
;
protected String name;
private IconLoader(String name) {
this.name = name;
}
public Icon getIcon() {
java.net.URL imgURL = getClass().getResource(name);
if (imgURL != null) {
return new ImageIcon(imgURL, name);
} else {
System.err.println("Couldn't find file: " + name);
return null;
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

Some files were not shown because too many files have changed in this diff Show More