Commit 8da596f8 authored by Thilo Rörig's avatar Thilo Rörig

updated libraries

fixed related issues
parent 8b440390
...@@ -68,9 +68,12 @@ ...@@ -68,9 +68,12 @@
<path id="junit.libraryclasspath"> <path id="junit.libraryclasspath">
<pathelement location="${lib}/junit/junit-4.11.jar"/> <pathelement location="${lib}/junit/junit-4.11.jar"/>
<pathelement location="${lib}/junit/hamcrest-core-1.3.jar"/> <pathelement location="${lib}/junit/hamcrest-core-1.3.jar"/>
</path> </path>
<path id="commonsio.libraryclasspath">
<target name="create build folders"> <pathelement location="${lib}/commons-io-2.6/commons-io-2.6.jar"/>
</path>
<target name="create build folders">
<mkdir dir="${build}"/> <mkdir dir="${build}"/>
<mkdir dir="${release}"/> <mkdir dir="${release}"/>
</target> </target>
...@@ -88,6 +91,7 @@ ...@@ -88,6 +91,7 @@
<classpath refid="jreality.libraryclasspath"/> <classpath refid="jreality.libraryclasspath"/>
<classpath refid="itext.libraryclasspath"/> <classpath refid="itext.libraryclasspath"/>
<classpath refid="junit.libraryclasspath"/> <classpath refid="junit.libraryclasspath"/>
<classpath refid="commonsio.libraryclasspath"/>
</javac> </javac>
<copy todir="${build}" description="copy resources to output folder"> <copy todir="${build}" description="copy resources to output folder">
<fileset dir="${src}"> <fileset dir="${src}">
......
...@@ -30,11 +30,11 @@ import de.jtem.jrworkspace.plugin.flavor.ToolBarFlavor; ...@@ -30,11 +30,11 @@ import de.jtem.jrworkspace.plugin.flavor.ToolBarFlavor;
public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor { public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor {
private Map<AlgorithmCategory, JComboBox<AlgorithmPlugin>> private Map<String, JComboBox<AlgorithmPlugin>>
comboMap = new HashMap<>(); comboMap = new HashMap<>();
private Map<AlgorithmCategory, Set<AlgorithmPlugin>> private Map<String, Set<AlgorithmPlugin>>
algoMap = new HashMap<AlgorithmCategory, Set<AlgorithmPlugin>>(); algoMap = new HashMap<String, Set<AlgorithmPlugin>>();
private JToolBar private JToolBar
comboToolBar = new JToolBar("Halfedge Algorithms"); comboToolBar = new JToolBar("Halfedge Algorithms");
...@@ -43,15 +43,15 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor { ...@@ -43,15 +43,15 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor {
} }
private void addComboBox(AlgorithmCategory cat) { private void addComboBox(String cat) {
JComboBox<AlgorithmPlugin> catCombo = new JComboBox<>(); JComboBox<AlgorithmPlugin> catCombo = new JComboBox<>();
catCombo.setMaximumRowCount(50); catCombo.setMaximumRowCount(50);
AlgorithmComboModel model = new AlgorithmComboModel(cat); AlgorithmComboModel model = new AlgorithmComboModel(cat);
catCombo.setModel(model); catCombo.setModel(model);
AlgorithmCellRenderer renderer = new AlgorithmCellRenderer(cat); AlgorithmCellRenderer renderer = new AlgorithmCellRenderer(cat);
catCombo.setRenderer(renderer); catCombo.setRenderer(renderer);
comboMap.put(cat, catCombo); comboMap.put(cat.toString(), catCombo);
algoMap.put(cat, new HashSet<AlgorithmPlugin>()); algoMap.put(cat.toString(), new HashSet<AlgorithmPlugin>());
updateComboBoxes(); updateComboBoxes();
} }
...@@ -63,10 +63,10 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor { ...@@ -63,10 +63,10 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor {
private static final long private static final long
serialVersionUID = 1L; serialVersionUID = 1L;
private AlgorithmCategory private String
category = AlgorithmCategory.Custom; category = AlgorithmCategory.Custom.toString();
public AlgorithmCellRenderer(AlgorithmCategory cat) { public AlgorithmCellRenderer(String cat) {
this.category = cat; this.category = cat;
} }
...@@ -92,10 +92,10 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor { ...@@ -92,10 +92,10 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor {
private class AlgorithmComboModel implements ComboBoxModel<AlgorithmPlugin> { private class AlgorithmComboModel implements ComboBoxModel<AlgorithmPlugin> {
private AlgorithmCategory private String
category = AlgorithmCategory.Custom; category = AlgorithmCategory.Custom.toString();
public AlgorithmComboModel(AlgorithmCategory cat) { public AlgorithmComboModel(String cat) {
this.category = cat; this.category = cat;
} }
...@@ -136,7 +136,7 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor { ...@@ -136,7 +136,7 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor {
} }
protected List<AlgorithmPlugin> getAlgorithms(AlgorithmCategory cat) { protected List<AlgorithmPlugin> getAlgorithms(String cat) {
List<AlgorithmPlugin> result = new LinkedList<AlgorithmPlugin>(); List<AlgorithmPlugin> result = new LinkedList<AlgorithmPlugin>();
Set<AlgorithmPlugin> algoSet = algoMap.get(cat); Set<AlgorithmPlugin> algoSet = algoMap.get(cat);
result.addAll(algoSet); result.addAll(algoSet);
...@@ -151,10 +151,10 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor { ...@@ -151,10 +151,10 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor {
c.fill = GridBagConstraints.HORIZONTAL; c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 1; c.gridwidth = 1;
int numCombos = 0; int numCombos = 0;
LinkedList<AlgorithmCategory> algorithmCategories = new LinkedList<>(comboMap.keySet()); LinkedList<String> algorithmCategories = new LinkedList<String>(comboMap.keySet());
Collections.sort(algorithmCategories); Collections.sort(algorithmCategories);
for (AlgorithmCategory cat : algorithmCategories) { for (String cat : algorithmCategories) {
JComboBox<AlgorithmPlugin> combo = comboMap.get(cat); JComboBox<AlgorithmPlugin> combo = comboMap.get(cat);
Set<AlgorithmPlugin> algos = algoMap.get(cat); Set<AlgorithmPlugin> algos = algoMap.get(cat);
if (algos.isEmpty()) continue; if (algos.isEmpty()) continue;
...@@ -183,7 +183,7 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor { ...@@ -183,7 +183,7 @@ public class AlgorithmDropdownToolbar extends Plugin implements ToolBarFlavor {
} }
public void addAlgorithm(AlgorithmPlugin ap) { public void addAlgorithm(AlgorithmPlugin ap) {
AlgorithmCategory algoName = ap.getCategory(); String algoName = ap.getCategory().toString();
if(!algoMap.containsKey(algoName)) { if(!algoMap.containsKey(algoName)) {
addComboBox(algoName); addComboBox(algoName);
} }
......
...@@ -218,9 +218,9 @@ public abstract class AlgorithmPlugin extends Plugin implements Comparable<Algor ...@@ -218,9 +218,9 @@ public abstract class AlgorithmPlugin extends Plugin implements Comparable<Algor
public KeyStroke getKeyboardShortcut() { public KeyStroke getKeyboardShortcut() {
return null; return null;
} }
public AlgorithmCategory getCategory() { public String getCategory() {
return getAlgorithmCategory(); return getAlgorithmCategory().toString();
} }
public AlgorithmCategory getAlgorithmCategory() { public AlgorithmCategory getAlgorithmCategory() {
......
...@@ -18,7 +18,7 @@ public abstract class AbstractCoordinateFactory<T> { ...@@ -18,7 +18,7 @@ public abstract class AbstractCoordinateFactory<T> {
Adapter<T> adapter; Adapter<T> adapter;
public void setAdapter(Adapter adapter) { public void setAdapter(Adapter<T> adapter) {
this.adapter = adapter; this.adapter = adapter;
} }
......
...@@ -8,17 +8,14 @@ import java.awt.GridBagConstraints; ...@@ -8,17 +8,14 @@ import java.awt.GridBagConstraints;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import javax.swing.JCheckBox; import javax.swing.*;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
...@@ -47,12 +44,13 @@ import de.jtem.halfedgetools.plugin.data.DataVisualizerPlugin; ...@@ -47,12 +44,13 @@ import de.jtem.halfedgetools.plugin.data.DataVisualizerPlugin;
import de.jtem.halfedgetools.plugin.image.ImageHook; import de.jtem.halfedgetools.plugin.image.ImageHook;
import de.jtem.jrworkspace.plugin.Controller; import de.jtem.jrworkspace.plugin.Controller;
import de.jtem.jrworkspace.plugin.PluginInfo; import de.jtem.jrworkspace.plugin.PluginInfo;
import org.apache.commons.io.FileUtils;
/** /**
* @author hinzmann * @author hinzmann
* A class intended for the generation of individual text-labels on vertices, edges and faces of a Halfedge-Geometry for Halfedge Data such as Index, Edgelength, Gauss Curvature etc. * A class intended for the generation of individual text-labels on vertices, edges and faces of a Halfedge-Geometry for Halfedge Data such as Index, Edgelength, Gauss Curvature etc.
*/ */
public class LabelVisualizer extends DataVisualizerPlugin implements ActionListener, ChangeListener, ColorChangedListener { public class LabelVisualizer extends DataVisualizerPlugin implements ActionListener, ChangeListener {
private HalfedgeInterface private HalfedgeInterface
hif = null; hif = null;
...@@ -67,7 +65,7 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe ...@@ -67,7 +65,7 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe
labelPositionCombo; //= new JComboBox<>(labelPositions.toArray(new LabelPosition[0])); labelPositionCombo; //= new JComboBox<>(labelPositions.toArray(new LabelPosition[0]));
private SpinnerNumberModel private SpinnerNumberModel
decimalsModel = new SpinnerNumberModel(3.0, 0.0, 100.0, 1.0), decimalsModel = new SpinnerNumberModel(3, 0, 100, 1),
fontSizeModel = new SpinnerNumberModel(0.05, 0.0, 100, 0.01), fontSizeModel = new SpinnerNumberModel(0.05, 0.0, 100, 0.01),
marginFactorModel = new SpinnerNumberModel(1, -10, 10, 0.1), ////factor moving the Label away from its corresponding edge, here 1 as default value in order to have one GUI-element for different LabelPosition classes, but in computation of the matrixTrafo this will be converted to an absolute value using standard-margin (getDefaultMargin()) of the current LabelPosition-class marginFactorModel = new SpinnerNumberModel(1, -10, 10, 0.1), ////factor moving the Label away from its corresponding edge, here 1 as default value in order to have one GUI-element for different LabelPosition classes, but in computation of the matrixTrafo this will be converted to an absolute value using standard-margin (getDefaultMargin()) of the current LabelPosition-class
offsetModel = new SpinnerNumberModel(0.0, -5, 5, 0.01); offsetModel = new SpinnerNumberModel(0.0, -5, 5, 0.01);
...@@ -85,8 +83,8 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe ...@@ -85,8 +83,8 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe
horizontalFlipChecker = new JCheckBox("Flip horizontally"), //gives the possibility to flip the labels (if normals are in the "wrong" direction for it), do this by rotating the label-lineset 180degree around its bb-center-axis (z axis resp. earlier y-axis) horizontalFlipChecker = new JCheckBox("Flip horizontally"), //gives the possibility to flip the labels (if normals are in the "wrong" direction for it), do this by rotating the label-lineset 180degree around its bb-center-axis (z axis resp. earlier y-axis)
verticalFlipChecker = new JCheckBox("Flip vertically"); verticalFlipChecker = new JCheckBox("Flip vertically");
private ColorChooseJButton private JButton
labelColorButton = new ColorChooseJButton(true); //cool color button, true = showing colors to choose in new window labelColorButton = new JButton();
private LabelVisualization private LabelVisualization
activeVisualization = null; // a field holding the current Visualization, needed for interplay with the UI activeVisualization = null; // a field holding the current Visualization, needed for interplay with the UI
...@@ -137,10 +135,10 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe ...@@ -137,10 +135,10 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe
offsetSpinner.addChangeListener(this); offsetSpinner.addChangeListener(this);
// lc.gridwidth = 2; // lc.gridwidth = 2;
labelColorButton.setColor(Color.BLACK); //set the initial color to black labelColorButton.setBackground(Color.BLACK); //set the initial color to black
optionsPanel.add(new JLabel("Color"), lc); optionsPanel.add(new JLabel("Color"), lc);
optionsPanel.add(labelColorButton, rc); optionsPanel.add(labelColorButton, rc);
labelColorButton.addColorChangedListener(this); labelColorButton.addActionListener(this);
} }
@Override @Override
...@@ -169,8 +167,14 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe ...@@ -169,8 +167,14 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe
* @return the corresponding labels as a visualization * @return the corresponding labels as a visualization
*/ */
public DataVisualization createVisualization(HalfedgeLayer layer, NodeType type, Adapter<?> source) { public DataVisualization createVisualization(HalfedgeLayer layer, NodeType type, Adapter<?> source) {
LabelVisualization vis = new LabelVisualization(layer,source, this, type);
// copy last values LabelVisualization vis = null;
try {
vis = new LabelVisualization(layer,source, this, type);
} catch (IOException e) {
System.err.println("Could not create Label visualization for layer " + layer.getName());
}
// copy last values
// vis.decimals = decimalsModel.getNumber().intValue(); // vis.decimals = decimalsModel.getNumber().intValue();
// vis.prefix = prefixTextField.getText(); // vis.prefix = prefixTextField.getText();
vis.setFontSize(fontSizeModel.getNumber().doubleValue()); //stay with the fontsize previously chosen vis.setFontSize(fontSizeModel.getNumber().doubleValue()); //stay with the fontsize previously chosen
...@@ -185,6 +189,13 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe ...@@ -185,6 +189,13 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if(e.getSource() == labelColorButton) {
Color newColor = JColorChooser.showDialog(SwingUtilities.getWindowAncestor(labelColorButton), "LabelColor", labelColorButton.getBackground());
if (newColor != null){
labelColorButton.setBackground(newColor);
setLabelColor(newColor);
}
}
updateVisualization(); updateVisualization();
} }
...@@ -193,17 +204,12 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe ...@@ -193,17 +204,12 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe
updateVisualization(); updateVisualization();
} }
@Override
public void colorChanged(ColorChangedEvent cce) {
setLabelColor(cce.getColor());
}
public Color getLabelColor() { public Color getLabelColor() {
return labelColorButton.getColor(); return labelColorButton.getBackground();
} }
public void setLabelColor(Color c) { public void setLabelColor(Color c) {
labelColorButton.setColor(c); labelColorButton.setBackground(c);
updateLabelColor(); updateLabelColor();
} }
...@@ -250,7 +256,7 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe ...@@ -250,7 +256,7 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe
fontSizeModel.setValue(activeVisualization.getFontSize()); fontSizeModel.setValue(activeVisualization.getFontSize());
marginFactorModel.setValue(activeVisualization.getMarginFactor()); marginFactorModel.setValue(activeVisualization.getMarginFactor());
offsetModel.setValue(activeVisualization.getOffset()); offsetModel.setValue(activeVisualization.getOffset());
labelColorButton.setColor(activeVisualization.getColor()); labelColorButton.setBackground(activeVisualization.getColor());
listenersDisabled = false; listenersDisabled = false;
return optionsPanel; return optionsPanel;
} }
...@@ -465,13 +471,17 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe ...@@ -465,13 +471,17 @@ public class LabelVisualizer extends DataVisualizerPlugin implements ActionListe
Adapter<?> source, Adapter<?> source,
DataVisualizer visualizer, DataVisualizer visualizer,
NodeType type NodeType type
) { ) throws IOException {
super(layer, source, visualizer, type); super(layer, source, visualizer, type);
visualizationRoot.setName("Label for " + source.toString()); visualizationRoot.setName("Label for " + source.toString());
//set initial type and size of labels font //set initial type and size of labels font
ttfLineSetFactory.setTTFFont(LabelVisualizer.class.getResource("Raleway-Thin.ttf").getPath()); InputStream resource = LabelVisualizer.class.getResourceAsStream("Raleway-Thin.ttf");
ttfLineSetFactory.setSingleLineFont(false); File tmpFile = File.createTempFile("Font", "ttf");
FileUtils.copyInputStreamToFile(resource,tmpFile);
ttfLineSetFactory.setTTFFont(tmpFile.getPath());
ttfLineSetFactory.setSingleLineFont(false);
ttfLineSetFactory.setSize(fontSize); ttfLineSetFactory.setSize(fontSize);
labelAppearance = ttfLineSetFactory.getStandardAppearance(); labelAppearance = ttfLineSetFactory.getStandardAppearance();
......
...@@ -158,6 +158,7 @@ public class NodeColorVisualizer extends DataVisualizerPlugin implements ActionL ...@@ -158,6 +158,7 @@ public class NodeColorVisualizer extends DataVisualizerPlugin implements ActionL
} }
@Override @Override
@SuppressWarnings("unchecked")
public void update() { public void update() {
if (!isActive()) { if (!isActive()) {
geomComponent.setVisible(false); geomComponent.setVisible(false);
......
...@@ -42,11 +42,11 @@ public class PointSetVisualizer extends DataVisualizerPlugin { ...@@ -42,11 +42,11 @@ public class PointSetVisualizer extends DataVisualizerPlugin {
private AbstractCoordinateFactory<double[][]> coordinateFactory = new CoordinateFactory(); private AbstractCoordinateFactory<double[][]> coordinateFactory = new CoordinateFactory();
@SuppressWarnings("unchecked")
public PointSetVisualization(HalfedgeLayer layer, Adapter<?> source, PointSetVisualizer pointSetVisualizer, NodeType type) { public PointSetVisualization(HalfedgeLayer layer, Adapter<?> source, PointSetVisualizer pointSetVisualizer, NodeType type) {
super(layer, source, pointSetVisualizer, type); super(layer, source, pointSetVisualizer, type);
coordinateFactory.setAdapter((Adapter<double[][]>) source);
sceneGraphComponent.setName("Points"); sceneGraphComponent.setName("Points");
coordinateFactory.setAdapter(source);
initAppearance(); initAppearance();
} }
...@@ -55,6 +55,7 @@ public class PointSetVisualizer extends DataVisualizerPlugin { ...@@ -55,6 +55,7 @@ public class PointSetVisualizer extends DataVisualizerPlugin {
} }
@Override @Override
@SuppressWarnings("unchecked")
public void updateSceneGraphComponent() { public void updateSceneGraphComponent() {
PointSetFactory psf = new PointSetFactory(); PointSetFactory psf = new PointSetFactory();
HalfEdgeDataStructure<?, ?, ?> hds = getLayer().get(); HalfEdgeDataStructure<?, ?, ?> hds = getLayer().get();
......
...@@ -135,6 +135,7 @@ VectorFieldVisualizer extends DataVisualizerPlugin implements ...@@ -135,6 +135,7 @@ VectorFieldVisualizer extends DataVisualizerPlugin implements
} }
@Override @Override
@SuppressWarnings("unchecked")
public DataVisualization createVisualization(HalfedgeLayer layer, public DataVisualization createVisualization(HalfedgeLayer layer,
NodeType type, Adapter<?> source) { NodeType type, Adapter<?> source) {
VectorFieldVisualization vis = new VectorFieldVisualization(layer, source, this, type); VectorFieldVisualization vis = new VectorFieldVisualization(layer, source, this, type);
...@@ -230,6 +231,7 @@ VectorFieldVisualizer extends DataVisualizerPlugin implements ...@@ -230,6 +231,7 @@ VectorFieldVisualizer extends DataVisualizerPlugin implements
} }
@Override @Override
@SuppressWarnings("unchecked")
public void updateSceneGraphComponent() { public void updateSceneGraphComponent() {
HalfEdgeDataStructure<?, ?, ?> hds = getLayer().get(); HalfEdgeDataStructure<?, ?, ?> hds = getLayer().get();
AdapterSet aSet = getLayer().getEffectiveAdapters(); AdapterSet aSet = getLayer().getEffectiveAdapters();
...@@ -251,6 +253,7 @@ VectorFieldVisualizer extends DataVisualizerPlugin implements ...@@ -251,6 +253,7 @@ VectorFieldVisualizer extends DataVisualizerPlugin implements
sceneGraphComponent.setVisible(true); sceneGraphComponent.setVisible(true);
} }
@SuppressWarnings("unchecked")
private <N extends Node> AbstractVectorCoordinateAndIndexFactory private <N extends Node> AbstractVectorCoordinateAndIndexFactory
createCoordinateAndIndexFactory(List<N> nodes, AdapterSet aSet) { createCoordinateAndIndexFactory(List<N> nodes, AdapterSet aSet) {
......
...@@ -78,6 +78,7 @@ public class LayerComponent extends SceneComponent { ...@@ -78,6 +78,7 @@ public class LayerComponent extends SceneComponent {
updateSelection(); updateSelection();
} }
@SuppressWarnings("unchecked")
public synchronized void updateGeometry() { public synchronized void updateGeometry() {
vertexComponent.getPoints().clear(); vertexComponent.getPoints().clear();
vertexComponent.getAnnotations().clear(); vertexComponent.getAnnotations().clear();
...@@ -119,6 +120,7 @@ public class LayerComponent extends SceneComponent { ...@@ -119,6 +120,7 @@ public class LayerComponent extends SceneComponent {
} }
} }
@SuppressWarnings("unchecked")
public synchronized void updateSelection() { public synchronized void updateSelection() {
if (layer == null) return; if (layer == null) return;
SelectionInterface sif = layer.getHalfedgeInterface().getSelectionInterface(); SelectionInterface sif = layer.getHalfedgeInterface().getSelectionInterface();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment