Commit 03583387 authored by Claes Sjofors's avatar Claes Sjofors

Web, open graph from pwg-files as default, methods for pwg-graphs added

parent 5099a6fc
...@@ -2083,6 +2083,9 @@ System.out.println("MainActivity TimerTask " + currentCmn.type()); ...@@ -2083,6 +2083,9 @@ System.out.println("MainActivity TimerTask " + currentCmn.type());
return gdh.isAuthorized(access); return gdh.isAuthorized(access);
} }
public void openPopupMenu( String object, double x, double y) {
}
public void invalidateView() { public void invalidateView() {
view.invalidate(); view.invalidate();
} }
......
...@@ -147,7 +147,7 @@ public class FlowFrame extends JFrame implements JopUtilityIfc, GdhApplIfc { ...@@ -147,7 +147,7 @@ public class FlowFrame extends JFrame implements JopUtilityIfc, GdhApplIfc {
URL fileURL = new URL( filename); URL fileURL = new URL( filename);
InputStream in = fileURL.openStream(); InputStream in = fileURL.openStream();
// in = new BufferedInputStream(in); // in = new BufferedInputStream(in);
InputStreamReader r2 = new InputStreamReader(in); InputStreamReader r2 = new InputStreamReader(in, "ISO-8859-1");
reader = new BufferedReader( r2); reader = new BufferedReader( r2);
} }
catch ( Exception e) { catch ( Exception e) {
......
...@@ -283,14 +283,14 @@ public class JopMethods { ...@@ -283,14 +283,14 @@ public class JopMethods {
CdhrString actionRet = gdh.getObjectInfoString( attr); CdhrString actionRet = gdh.getObjectInfoString( attr);
if ( actionRet.evenSts()) return; if ( actionRet.evenSts()) return;
int idx = actionRet.str.lastIndexOf( '.');
String action; String action;
if ( idx != -1) if ( actionRet.str.endsWith(".class")) {
action = actionRet.str.substring(0,1).toUpperCase() + int idx = actionRet.str.lastIndexOf( '.');
actionRet.str.substring(1, idx); action = actionRet.str.substring(0,1).toUpperCase() + actionRet.str.substring(1, idx);
else }
action = actionRet.str.substring(0,1).toUpperCase() + else {
actionRet.str.substring(1); action = actionRet.str;
}
String instance = null; String instance = null;
attr = xttgraph.str + ".Object"; attr = xttgraph.str + ".Object";
......
...@@ -38,12 +38,12 @@ public class JopOp { ...@@ -38,12 +38,12 @@ public class JopOp {
if ( args.length > 0) if ( args.length > 0)
System.out.println("Arg: " + args[0]); System.out.println("Arg: " + args[0]);
try { try {
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); // UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
// UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} }
catch(Exception e) { catch(Exception e) {
e.printStackTrace(); System.out.println("setLookAndFeel exception");
// e.printStackTrace();
} }
new JopOp(); new JopOp();
byte[] buff = new byte[100]; byte[] buff = new byte[100];
......
...@@ -76,6 +76,9 @@ public class JopSpider { ...@@ -76,6 +76,9 @@ public class JopSpider {
public void frameClosed( Object utility) { public void frameClosed( Object utility) {
session.removeUtility( utility); session.removeUtility( utility);
} }
public void openPopupMenu( String object, Object invoker, int x, int y) {
JopSpider.openPopupMenu( session, object, invoker, x, y);
}
} }
public JopSpider( int op_qcom_qix) { public JopSpider( int op_qcom_qix) {
...@@ -97,16 +100,12 @@ public class JopSpider { ...@@ -97,16 +100,12 @@ public class JopSpider {
// Send qcom qix to jop // Send qcom qix to jop
String set_cmd = "set jop_queid " + qcom_qix; String set_cmd = "set jop_queid " + qcom_qix;
System.out.println( "qcom put");
PwrtStatus sts = qcom.put( op_qcom_qix, op_qcom_nid, set_cmd); PwrtStatus sts = qcom.put( op_qcom_qix, op_qcom_nid, set_cmd);
System.out.println( "qcom put finished");
if ( sts.evenSts()) if ( sts.evenSts())
System.out.println( "Qcom put error: " + sts.getSts()); System.out.println( "Qcom put error: " + sts.getSts());
new JopSpiderCmd( session); new JopSpiderCmd( session);
// loadFrame("Frame");
// loadFrame("Frame");
} }
static public void setSystemName( String systemName) { static public void setSystemName( String systemName) {
...@@ -116,6 +115,11 @@ System.out.println( "qcom put finished"); ...@@ -116,6 +115,11 @@ System.out.println( "qcom put finished");
return systemName; return systemName;
} }
static void openPopupMenu( JopSession session, String object, Object invoker, int x, int y) {
new JopMethodsMenu( session, object, JopUtility.GRAPH, (Component)invoker, x, y);
}
static CliTable[] cliTable = new CliTable[] { static CliTable[] cliTable = new CliTable[] {
new CliTable( "OPEN", new String[] {"cli_arg1", "cli_arg2", "/NAME", new CliTable( "OPEN", new String[] {"cli_arg1", "cli_arg2", "/NAME",
"/FILE", "/SCROLLBAR", "/WIDTH", "/HEIGHT", "/MENU", "/NAVIGATOR", "/FILE", "/SCROLLBAR", "/WIDTH", "/HEIGHT", "/MENU", "/NAVIGATOR",
...@@ -202,6 +206,7 @@ System.out.println( "qcom put finished"); ...@@ -202,6 +206,7 @@ System.out.println( "qcom put finished");
boolean scrollbar = cli.qualifierFound("/SCROLLBAR"); boolean scrollbar = cli.qualifierFound("/SCROLLBAR");
if ( cli.qualifierFound("/OBJECT")) { if ( cli.qualifierFound("/OBJECT")) {
// XttGraph object
String objectValue = cli.getQualValue("/OBJECT"); String objectValue = cli.getQualValue("/OBJECT");
String objectName; String objectName;
String appletName; String appletName;
...@@ -257,76 +262,47 @@ System.out.println( "qcom put finished"); ...@@ -257,76 +262,47 @@ System.out.println( "qcom put finished");
local_cmd = true; local_cmd = true;
} }
else { else {
if ( true /* session.isOpWindowApplet() */) { // No XttGraph
String frameName = null; String frameName = null;
String instanceValue = null; String instanceValue = null;
boolean classGraph = false; boolean classGraph = false;
if ( cli.qualifierFound("/INSTANCE")) { if ( cli.qualifierFound("/INSTANCE")) {
instanceValue = cli.getQualValue("/INSTANCE"); instanceValue = cli.getQualValue("/INSTANCE");
classGraph = cli.qualifierFound("/CLASSGRAPH"); classGraph = cli.qualifierFound("/CLASSGRAPH");
boolean parent = cli.qualifierFound("/PARENT"); boolean parent = cli.qualifierFound("/PARENT");
if ( parent) { if ( parent) {
int idx = instanceValue.lastIndexOf( '.'); int idx = instanceValue.lastIndexOf( '.');
if ( idx != -1 && idx != 0) if ( idx != -1 && idx != 0)
instanceValue = instanceValue.substring( 0, idx); instanceValue = instanceValue.substring( 0, idx);
System.out.println( "open graph /parent: " + instanceValue); System.out.println( "open graph /parent: " + instanceValue);
} }
} }
if ( !classGraph) { if ( !classGraph) {
if ( ! cli.qualifierFound("cli_arg2")) { if ( ! cli.qualifierFound("cli_arg2")) {
System.out.println("Syntax error"); System.out.println("Syntax error");
return 0; return 0;
} }
frameName = cli.getQualValue("cli_arg2").toLowerCase();
frameName = frameName.substring(0,1).toUpperCase() + frameName = cli.getQualValue("cli_arg2");
frameName.substring(1);
System.out.println( "Open frame " + frameName); if ( Character.isUpperCase(frameName.charAt(0))) {
} // If first char is upper, open as java class
session.openGraphFrame( frameName, instanceValue, scrollbar, classGraph); frameName = frameName.toLowerCase();
}
/************* frameName = frameName.substring(0,1).toUpperCase() +
else { frameName.substring(1);
String frameName = null;
if ( ! cli.qualifierFound("cli_arg2")) {
System.out.println("Syntax error");
return 0;
}
frameName = cli.getQualValue("cli_arg2").toLowerCase();
if ( cli.qualifierFound("/INSTANCE")) {
String instanceValue =
cli.getQualValue("/INSTANCE").toLowerCase();
boolean parent = cli.qualifierFound("/PARENT");
if ( parent) {
int idx = instanceValue.lastIndexOf( '.');
if ( idx != -1 && idx != 0)
instanceValue = instanceValue.substring( 0, idx);
System.out.println( "open graph /parent: " + instanceValue);
} }
else {
String tempFile = frameName + "_" + // If first char is lower, open as pwg-file
instanceValue.replace('','a').replace('','a').replace('','o'); if ( frameName.indexOf(".pwg") == -1)
PwrtStatus psts = frameName = frameName + ".pwg";
gdh.createInstanceFile(
"$pwrp_websrv/"+frameName+".html",
tempFile+".html", instanceValue);
if ( psts.evenSts()) {
System.out.println("createInstanceFile error");
return 0;
} }
frameName = tempFile; System.out.println( "Open frame " + frameName);
}
System.out.println( "Loading applet \"" + frameName + "\"");
openURL( session, frameName, newFrame, null, null);
local_cmd = true;
} }
***/ session.openGraphFrame( frameName, instanceValue, scrollbar, classGraph);
} }
} }
else { else {
// Application // Application
...@@ -348,6 +324,7 @@ System.out.println( "qcom put finished"); ...@@ -348,6 +324,7 @@ System.out.println( "qcom put finished");
} }
} }
if ( cli.qualifierFound("/OBJECT")) { if ( cli.qualifierFound("/OBJECT")) {
// XttGraph object
String objectValue = cli.getQualValue("/OBJECT"); String objectValue = cli.getQualValue("/OBJECT");
String objectName; String objectName;
String appletName; String appletName;
...@@ -401,10 +378,20 @@ System.out.println( "qcom put finished"); ...@@ -401,10 +378,20 @@ System.out.println( "qcom put finished");
frameName = frameName + ".pwg"; frameName = frameName + ".pwg";
} }
else if ( cli.qualifierFound("cli_arg2")) { else if ( cli.qualifierFound("cli_arg2")) {
frameName = cli.getQualValue("cli_arg2").toLowerCase(); frameName = cli.getQualValue("cli_arg2");
if ( Character.isUpperCase(frameName.charAt(0))) {
// If first char is upper, open as java class
frameName = frameName.toLowerCase();
frameName = frameName.substring(0,1).toUpperCase() + frameName = frameName.substring(0,1).toUpperCase() +
frameName.substring(1); frameName.substring(1);
}
else {
// If first char is lower, open as pwg-file
if ( frameName.indexOf(".pwg") == -1)
frameName = frameName + ".pwg";
}
} }
else { else {
System.out.println("Syntax error"); System.out.println("Syntax error");
......
...@@ -591,7 +591,7 @@ public class Dyn { ...@@ -591,7 +591,7 @@ public class Dyn {
public static final int ePwrStatus_Error = 3; public static final int ePwrStatus_Error = 3;
public static final int ePwrStatus_Fatal = 4; public static final int ePwrStatus_Fatal = 4;
public static final boolean debug = true; public static final boolean debug = false;
Vector<DynElem> elements = new Vector<DynElem>(); Vector<DynElem> elements = new Vector<DynElem>();
GraphIfc graph; GraphIfc graph;
...@@ -3204,6 +3204,9 @@ public class Dyn { ...@@ -3204,6 +3204,9 @@ public class Dyn {
if ( token.hasMoreTokens()) if ( token.hasMoreTokens())
attribute = token.nextToken(); attribute = token.nextToken();
break; break;
case Dyn.eSave_ValueInput_unselect:
unselect = Integer.valueOf(token.nextToken());
break;
case Dyn.eSave_ValueInput_min_value: case Dyn.eSave_ValueInput_min_value:
min_value = new Double(token.nextToken()).doubleValue(); min_value = new Double(token.nextToken()).doubleValue();
break; break;
...@@ -6314,6 +6317,18 @@ public class Dyn { ...@@ -6314,6 +6317,18 @@ public class Dyn {
ref_object = x.ref_object; ref_object = x.ref_object;
} }
public int action( GlowArrayElem object, GlowEvent e) {
if ( !dyn.graph.isAuthorized( dyn.access))
return 1;
switch ( e.event) {
case Glow.eEvent_MB3Press:
dyn.graph.openPopupMenu( ref_object, e.x, e.y);
break;
}
return 1;
}
public void open( BufferedReader reader) { public void open( BufferedReader reader) {
String line; String line;
StringTokenizer token; StringTokenizer token;
...@@ -7423,9 +7438,8 @@ public class Dyn { ...@@ -7423,9 +7438,8 @@ public class Dyn {
case Glow.eEvent_MB1Click: case Glow.eEvent_MB1Click:
if ( (dyn.action_type1 & Dyn.mActionType1_Confirm) != 0) if ( (dyn.action_type1 & Dyn.mActionType1_Confirm) != 0)
break; break;
String command = null; String command = null;
if ( !graph_object.equals("")) if ( !(graph_object == null || graph_object.equals("")))
command = new String("open graph/object=" + graph_object); command = new String("open graph/object=" + graph_object);
else { else {
// Open classgraph for popup menu object // Open classgraph for popup menu object
......
...@@ -1498,4 +1498,5 @@ public class Glow { ...@@ -1498,4 +1498,5 @@ public class Glow {
public static final int eEvent_SliderMoveStart = 11; public static final int eEvent_SliderMoveStart = 11;
public static final int eEvent_SliderMoved = 12; public static final int eEvent_SliderMoved = 12;
public static final int eEvent_SliderMoveEnd = 13; public static final int eEvent_SliderMoveEnd = 13;
public static final int eEvent_MB3Press = 14;
} }
...@@ -343,7 +343,8 @@ public class Graph implements GraphIfc, GrowApplIfc { ...@@ -343,7 +343,8 @@ public class Graph implements GraphIfc, GrowApplIfc {
while ( (idx = str.indexOf("$object")) != -1) { while ( (idx = str.indexOf("$object")) != -1) {
if ( appl != null) { if ( appl != null) {
String oname = appl.getObject(); // String oname = appl.getObject();
String oname = cmn.getOwner();
str = str.substring(0, idx) + oname + str.substring(idx+7); str = str.substring(0, idx) + oname + str.substring(idx+7);
} }
} }
...@@ -412,6 +413,7 @@ public class Graph implements GraphIfc, GrowApplIfc { ...@@ -412,6 +413,7 @@ public class Graph implements GraphIfc, GrowApplIfc {
// Note! no break // Note! no break
case Glow.eEvent_MB1Up: case Glow.eEvent_MB1Up:
case Glow.eEvent_MB1Down: case Glow.eEvent_MB1Down:
case Glow.eEvent_MB3Press:
case Glow.eEvent_ValueChanged: case Glow.eEvent_ValueChanged:
case Glow.eEvent_SliderMoveStart: case Glow.eEvent_SliderMoveStart:
case Glow.eEvent_SliderMoveEnd: case Glow.eEvent_SliderMoveEnd:
...@@ -492,6 +494,11 @@ public class Graph implements GraphIfc, GrowApplIfc { ...@@ -492,6 +494,11 @@ public class Graph implements GraphIfc, GrowApplIfc {
appl.openValueInputDialog(dyn, text, object); appl.openValueInputDialog(dyn, text, object);
} }
public void openPopupMenu(String object, double x, double y) {
if ( appl != null)
appl.openPopupMenu(object, x, y);
}
public String get_reference_name(String name) { public String get_reference_name(String name) {
// TODO // TODO
return null; return null;
......
...@@ -40,6 +40,7 @@ public interface GraphApplIfc { ...@@ -40,6 +40,7 @@ public interface GraphApplIfc {
public int command(String cmd); public int command(String cmd);
public void openConfirmDialog( Object dyn, String text, Object object); public void openConfirmDialog( Object dyn, String text, Object object);
public void openValueInputDialog( Object dyn, String text, Object object); public void openValueInputDialog( Object dyn, String text, Object object);
public void openPopupMenu( String object, double x, double y);
public int getWidth(); public int getWidth();
public int getHeight(); public int getHeight();
public String getObject(); public String getObject();
......
...@@ -57,6 +57,7 @@ public interface GraphIfc { ...@@ -57,6 +57,7 @@ public interface GraphIfc {
public void closeGraph(); public void closeGraph();
public void openConfirmDialog(Object dyn, String text, Object object); public void openConfirmDialog(Object dyn, String text, Object object);
public void openValueInputDialog(Object dyn, String text, Object object); public void openValueInputDialog(Object dyn, String text, Object object);
public void openPopupMenu(String object, double x, double y);
public String get_reference_name(String name); public String get_reference_name(String name);
public Object getCurrentSlider(); public Object getCurrentSlider();
public void setCurrentSlider(GrowSlider currentSlider); public void setCurrentSlider(GrowSlider currentSlider);
......
...@@ -120,7 +120,7 @@ public class GrowCmn { ...@@ -120,7 +120,7 @@ public class GrowCmn {
public GrowCmn( GrowCtxIfc ctx, GrowApplIfc appl) { public GrowCmn( GrowCtxIfc ctx, GrowApplIfc appl) {
this.ctx = ctx; this.ctx = ctx;
this.appl = appl; this.appl = appl;
this.debug = true; this.debug = false;
this.antiAliasing = true; this.antiAliasing = true;
mw.window_width = getWidth(); mw.window_width = getWidth();
mw.window_height = getHeight(); mw.window_height = getHeight();
...@@ -155,4 +155,5 @@ public class GrowCmn { ...@@ -155,4 +155,5 @@ public class GrowCmn {
public int getAppMotion() { public int getAppMotion() {
return app_motion; return app_motion;
} }
} }
...@@ -788,6 +788,12 @@ public class GrowCtx implements GrowCtxIfc { ...@@ -788,6 +788,12 @@ public class GrowCtx implements GrowCtxIfc {
draw(); draw();
} }
public void zoomAbsolute( double factor) {
cmn.mw.zoom_factor_x = factor;
cmn.mw.zoom_factor_y = factor;
draw();
}
public void scroll( int delta_x, int delta_y) { public void scroll( int delta_x, int delta_y) {
cmn.mw.offset_x += delta_x; cmn.mw.offset_x += delta_x;
cmn.mw.offset_y += delta_y; cmn.mw.offset_y += delta_y;
...@@ -837,6 +843,19 @@ public class GrowCtx implements GrowCtxIfc { ...@@ -837,6 +843,19 @@ public class GrowCtx implements GrowCtxIfc {
public void setSliderActive( boolean active) { public void setSliderActive( boolean active) {
sliderActive = active; sliderActive = active;
} }
public void setDefaultLayout( int width, int height) {
if ( cmn.x0 >= cmn.x1 || cmn.y0 >= cmn.y1)
return;
cmn.mw.zoom_factor_x = Math.min( width/(cmn.x1 - cmn.x0),
height/(cmn.y1 - cmn.y0));
cmn.mw.zoom_factor_y = cmn.mw.zoom_factor_x;
cmn.mw.offset_x = (int)(cmn.x0 * cmn.mw.zoom_factor_x);
cmn.mw.offset_y = (int)(cmn.y0 * cmn.mw.zoom_factor_y);
draw();
}
} }
......
This diff is collapsed.
...@@ -40,4 +40,5 @@ package jpwr.jopg; ...@@ -40,4 +40,5 @@ package jpwr.jopg;
public interface GrowFrameApplIfc { public interface GrowFrameApplIfc {
public int command(String cmd); public int command(String cmd);
public void frameClosed( Object utility); public void frameClosed( Object utility);
public void openPopupMenu( String object, Object invoker, int x, int y);
} }
...@@ -275,7 +275,7 @@ public class GrowWindow extends GrowRect implements GrowScrollBarIfc { ...@@ -275,7 +275,7 @@ public class GrowWindow extends GrowRect implements GrowScrollBarIfc {
windowCmn.mw.subwindow_scale = cmn.mw.subwindow_scale * window_scale; windowCmn.mw.subwindow_scale = cmn.mw.subwindow_scale * window_scale;
windowCmn.mw.zoom_factor_x = windowCmn.mw.zoom_factor_y = windowCmn.mw.zoom_factor_x = windowCmn.mw.zoom_factor_y =
cmn.mw.zoom_factor_x * windowCmn.mw.subwindow_scale; cmn.mw.zoom_factor_x * windowCmn.mw.subwindow_scale;
configureScrollbars(); configureScrollbars();
} }
...@@ -450,6 +450,8 @@ public class GrowWindow extends GrowRect implements GrowScrollBarIfc { ...@@ -450,6 +450,8 @@ public class GrowWindow extends GrowRect implements GrowScrollBarIfc {
v_value = wctx_y0 * windowCmn.mw.subwindow_scale; v_value = wctx_y0 * windowCmn.mw.subwindow_scale;
} }
} }
else
v_value = wctx_y0 * windowCmn.mw.subwindow_scale;
if ( horizontal_scrollbar != 0 && h_scrollbar == null) { if ( horizontal_scrollbar != 0 && h_scrollbar == null) {
x0 = x_left; x0 = x_left;
...@@ -479,6 +481,9 @@ public class GrowWindow extends GrowRect implements GrowScrollBarIfc { ...@@ -479,6 +481,9 @@ public class GrowWindow extends GrowRect implements GrowScrollBarIfc {
h_value = wctx_x0 * windowCmn.mw.subwindow_scale; h_value = wctx_x0 * windowCmn.mw.subwindow_scale;
} }
} }
else
h_value = wctx_x0 * windowCmn.mw.subwindow_scale;
} }
public void verticalScrollValueChanged(double value) { public void verticalScrollValueChanged(double value) {
......
!
! Proview Open Source Process Control.
! Copyright (C) 2005-2014 SSAB EMEA AB.
!
! This file is part of Proview.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with Proview. If not, see <http://www.gnu.org/licenses/>
!
! Linking Proview statically or dynamically with other modules is
! making a combined work based on Proview. Thus, the terms and
! conditions of the GNU General Public License cover the whole
! combination.
!
! In addition, as a special exception, the copyright holders of
! Proview give you permission to, from the build function in the
! Proview Configurator, combine Proview with modules generated by the
! Proview PLC Editor to a PLC program, regardless of the license
! terms of these modules. You may copy and distribute the resulting
! combined work under the terms of your choice, provided that every
! copy of the combined work is accompanied by a complete copy of
! the source code of Proview (the version used to produce the
! combined work), being distributed under the terms of the GNU
! General Public License plus this exception.
!
! pwrb_c_appgraph.wb_load -- Defines the class AppGraph.
!
SObject pwrb:Class
!/**
! @Version 1.0
! @Summary Defines a link in an android application.
! Defines a link in an android application.
! AppLink objects should be positioned as children to a WebHandler object.
!
!
! @b See also
! @classlink WebHandler pwrb_webhandler.html
!*/
Object AppLink $ClassDef 616
Body SysBody
Attr Editor = pwr_eEditor_AttrEd
Attr Method = pwr_eMethod_Standard
Attr PopEditor = 1
EndBody
Object RtBody $ObjBodyDef 1
Body SysBody
Attr StructName = "AppLink"
EndBody
!/**
! The URL.
!*/
Object URL $Attribute 1
Body SysBody
Attr TypeRef = "pwrs:Type-$URL"
EndBody
EndObject
!/**
! Icon text for the link.
!*/
Object Text $Attribute 2
Body SysBody
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! Icon image for the link.
! The default location is $pwrp_exe.
!*/
Object Image $Attribute 3
Body SysBody
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
EndObject
EndObject
EndSObject
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