001package org.vishia.guiInspc; 002 003import java.util.Locale; 004 005import org.vishia.gral.base.GralButton; 006import org.vishia.gral.base.GralMng; 007import org.vishia.gral.base.GralTable; 008import org.vishia.gral.base.GralTextField; 009import org.vishia.gral.base.GralWidget; 010import org.vishia.gral.base.GralWindow; 011import org.vishia.gral.ifc.GralColor; 012import org.vishia.gral.ifc.GralTableLine_ifc; 013import org.vishia.gral.ifc.GralUserAction; 014import org.vishia.gral.ifc.GralWidget_ifc; 015import org.vishia.gral.ifc.GralWindow_ifc; 016import org.vishia.inspcPC.InspcPlugUser_ifc; 017import org.vishia.inspcPC.accTarget.InspcTargetAccessor; 018import org.vishia.inspcPC.mng.InspcMng; 019import org.vishia.msgDispatch.LogMessage; 020import org.vishia.msgDispatch.LogMessageFile; 021import org.vishia.util.Debugutil; 022import org.vishia.util.KeyCode; 023import org.vishia.util.StringFunctions_C; 024 025/**This class contains some status and control widgets for the Inspector Gui to show the status of communication. 026 * The communication itself is organized in {@link org.vishia.inspcPC.accTarget.InspcTargetAccessor} in the software component javaSrc_vishiaRun. 027 * @author Hartmut Schorrig 028 * 029 */ 030public class InspcViewTargetComm 031{ 032 /**Version, history and license. 033 * <ul> 034 * <li>2018-10-19 chg: The Log on/off button is related to the target direct, not to the gui. Therefore handler implemented here. 035 * <li>2018-10-19 new {@link #windTargetSettings} for target settings, better handling of timeout, password-setting. 036 * Better handling of clearReq: Now it works with timeout=0 and manual clearRequest on stepbystep-debugging of the target. 037 * <li>2015-05-30 Created. 038 * </ul> 039 * 040 * <b>Copyright/Copyleft</b>: 041 * For this source the LGPL Lesser General Public License, 042 * published by the Free Software Foundation is valid. 043 * It means: 044 * <ol> 045 * <li> You can use this source without any restriction for any desired purpose. 046 * <li> You can redistribute copies of this source to everybody. 047 * <li> Every user of this source, also the user of redistribute copies 048 * with or without payment, must accept this license for further using. 049 * <li> But the LPGL is not appropriate for a whole software product, 050 * if this source is only a part of them. It means, the user 051 * must publish this part of source, 052 * but don't need to publish the whole source of the own product. 053 * <li> You can study and modify (improve) this source 054 * for own using or for redistribution, but you have to license the 055 * modified sources likewise under this LGPL Lesser General Public License. 056 * You mustn't delete this Copyright/Copyleft inscription in this source file. 057 * </ol> 058 * If you are intent to use this sources without publishing its usage, you can get 059 * a second license subscribing a special contract with the author. 060 * 061 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 062 * 063 */ 064 //@SuppressWarnings("hiding") 065 protected final static String sVersion = "2018-10-19"; 066 067 068 /**The window to present. */ 069 private final GralWindow windStateOfTarget; 070 071 /**The window to input passwords. */ 072 private final GralWindow windTargetSettings; 073 074 /**Shows the path in target to this struct. */ 075 //private final GralTextField widgPath; 076 077 /**Table of fields, type and value. */ 078 private final GralTable<InspcTargetAccessor> widgTable; 079 080 081 private final GralButton wdgBtnLog, wdgBtnRetry, wdgBtnClearReq, wdgBtnPerHandle, wdgBtnTargetSettings; 082 083 084 private final GralTextField wdgPwdAccess, wdgAccLevels; //, wdgPwdAccess1, wdgPwdChg1, wdgPwdAccess2, wdgPwdChg2, wdgPwdAccess3, wdgPwdChg3; 085 086 private final GralTextField wdgTargetIdent, wdgTimeout, wdgTimeCycle; 087 088 private final GralButton wdgBtnTargetSettingsOk; 089 090 private GralColor colorInactive = GralColor.getColor("wh") 091 , colorIdle = GralColor.getColor("lgn") 092 , colorWait = GralColor.getColor("lrd") 093 , color2 = GralColor.getColor("or"); 094 095 096 String targetKeySettingwindow = ""; 097 098 LogMessage logTelg; 099 100 101 final InspcGui gui; 102 103 104 InspcTargetAccessor targetForSettingsWindow; 105 106 public InspcViewTargetComm(InspcGui gui) 107 { //inspcMng.addUserOrder(this); //invoke run in any communication step. 108 this.gui = gui; 109 this.windStateOfTarget = new GralWindow("@primaryWindow,-21..0,-50..0", "InspcCtrlStatusWind", "State of targets", GralWindow_ifc.windOnTop | GralWindow_ifc.windResizeable); 110 this.widgTable = new GralTable<InspcTargetAccessor>("@InspcCtrlStatusWind,0..-3,0..0=TargetTable", new int[]{3, 0,-6,-6}); 111 this.widgTable.setColumnEditable(2, true); 112 this.widgTable.setColumnEditable(3, true); 113 //this.widgTable.setColumnEditable(2, true); 114 this.widgTable.setHtmlHelp("HelpInspc.html#Topic.HelpInspc.ctrlStatus."); 115 this.wdgBtnLog = new GralButton("@InspcCtrlStatusWind,-2..0,0..8=BtnLog", "Enable Log", null); 116 this.wdgBtnLog.setSwitchMode("? Log", "Log ?off"); 117 this.wdgBtnLog.setSwitchMode(GralColor.getColor("wh"), GralColor.getColor("am")); 118 this.wdgBtnLog.specifyActionChange("switch log telg", actionEnableLog, null); 119 this.wdgBtnRetry = new GralButton("@InspcCtrlStatusWind,-2..0,9..17=BtnRetry", "Retry", null); 120 this.wdgBtnRetry.setSwitchMode("? Retry", "Retry ?off"); 121 this.wdgBtnRetry.setSwitchMode(GralColor.getColor("wh"), GralColor.getColor("am")); 122 this.wdgBtnRetry.specifyActionChange("retry variables", gui.actionSetRetryDisabledVariable, null); 123 this.wdgBtnClearReq = new GralButton("@InspcCtrlStatusWind,-2..0,18..27=BtnClearReq", "ClearReq", null); 124 this.wdgBtnClearReq.specifyActionChange("retry variables", actionClearReq, null); 125 this.wdgBtnPerHandle = new GralButton("@InspcCtrlStatusWind,-2..0,28..37=BtnLog", "Enable Log", null); 126 this.wdgBtnPerHandle.setSwitchMode("? use Handle", "use Handle ?off"); 127 this.wdgBtnPerHandle.setSwitchMode(GralColor.getColor("wh"), GralColor.getColor("gn")); 128 this.wdgBtnPerHandle.specifyActionChange("use handle", gui.actionUseGetValueByHandle, null); 129 this.wdgBtnTargetSettings = new GralButton("@InspcCtrlStatusWind,-2..0,38..47=BtnTargetSettings", "@Settings", null); 130 this.wdgBtnTargetSettings.specifyActionChange("openPwd", actionOpenWindowTargetSettings, null); 131 132 this.windTargetSettings = new GralWindow("@primaryWindow,-36..-18,-30..0", "InspcTargetPwdWind", "Passwords for Target", GralWindow_ifc.windOnTop); 133 134 this.wdgTargetIdent = new GralTextField("@InspcTargetPwdWind, 2-2,1+20=targetident"); 135 this.wdgTimeCycle = new GralTextField("@InspcTargetPwdWind, 6-4,1+10=timeCycle", GralTextField.Type.editable); 136 this.wdgTimeout = new GralTextField("@InspcTargetPwdWind, 6-4,12+10=timeout", GralTextField.Type.editable); 137 this.wdgTimeCycle.setPrompt("cycle [s]", "t"); 138 this.wdgTimeout.setPrompt("timeout [s] 0-debug", "t"); 139 140 this.wdgPwdAccess = new GralTextField("@InspcTargetPwdWind, 10-4,1+10=PwdAccess0", GralTextField.Type.editable); 141 this.wdgAccLevels = new GralTextField("@InspcTargetPwdWind, 10-4,12+10=PwdChg0"); 142 this.wdgPwdAccess.setPrompt("pwd", "t"); 143 this.wdgAccLevels.setPrompt("access levels", "t"); 144 // this.wdgPwdAccess1 = new GralTextField("@InspcTargetPwdWind, 6-2,5+10=PwdAccess1", GralTextField.Type.editable); 145// this.wdgPwdChg1 = new GralTextField("@InspcTargetPwdWind, 6-2,17+10=PwdChg1", GralTextField.Type.editable); 146// this.wdgPwdAccess2 = new GralTextField("@InspcTargetPwdWind, 8-2,5+10=PwdAccess2", GralTextField.Type.editable); 147// this.wdgPwdChg2 = new GralTextField("@InspcTargetPwdWind, 8-2,17+10=PwdChg2", GralTextField.Type.editable); 148// this.wdgPwdAccess3 = new GralTextField("@InspcTargetPwdWind, 10-2,5+10=PwdAccess3", GralTextField.Type.editable); 149// this.wdgPwdChg3 = new GralTextField("@InspcTargetPwdWind, 10-2,17+10=PwdChg3", GralTextField.Type.editable); 150 this.wdgBtnTargetSettingsOk = new GralButton("@InspcTargetPwdWind, 14-3,16+6=BtnSettingsOk", "ok", null); 151 this.wdgBtnTargetSettingsOk.specifyActionChange("openPwd", actionSetTargetSettings, null); 152 153 154 } 155 156 157 /**Invoked in the graphic thread. 158 */ 159 public void setToPanel(){ 160 GralMng mng = GralMng.get(); 161 windStateOfTarget.setToPanel(mng); 162 windTargetSettings.createImplWidget_Gthread(); 163 //mng.setPosition(0, 2, 0, 3, 0, 'd'); 164 //mng.setPosition(0, 2, 3, 0, 0, 'd'); 165 //mng.setPosition(2, -4, 0, 0, 0, 'd'); 166 widgTable.setToPanel(mng); 167 //mng.setPosition(-2, 0, 0, 7, 0, 'd'); 168 } 169 170 171 GralUserAction setVisible = new GralUserAction("") 172 { public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params) { 173 windStateOfTarget.setFocus(); //Visible(true); 174 return true; 175 } 176 }; 177 178 179 public void addTarget(String key, String info, float cycle, float timeout){ 180// GralTableLine_ifc<InspcTargetAccessor> line = widgTable.addLine(key, null, null); 181// line.setCellText(key + "@" + info, 1); 182// line.setCellText(String.format(Locale.US, "%1.1f", cycle), 2); //use a 0.2 and not 0,2 in a german installation 183// line.setCellText(String.format(Locale.US, "%3.1f", timeout), 3); 184 } 185 186 187 188 void registerTarget(String name, String sAddr, InspcTargetAccessor targetAcc) { 189 GralTableLine_ifc<InspcTargetAccessor> line = widgTable.addLine(name, null, targetAcc); 190 line.setCellText(name + "@" + sAddr, 1); 191 line.setCellText(String.format(Locale.US, "%1.1f", targetAcc.cycle_timeout[0]), 2); //use a 0.2 and not 0,2 in a german installation 192 line.setCellText(String.format(Locale.US, "%3.1f", targetAcc.cycle_timeout[1]), 3); 193 } 194 195 196 public void setStateInfo(String key, InspcPlugUser_ifc.TargetState state, int count, int accLevels, float[] cycle_timeout){ 197 GralColor color; 198 switch(state) { 199 case idle: color = colorIdle; break; 200 case inactive: color = colorInactive; break; 201 case waitReceive: color = colorWait; break; 202 case receive: color = color2; break; 203 default: color = color2; 204 } 205 if(key.equals(targetKeySettingwindow)) { 206 wdgAccLevels.setText(Integer.toHexString(accLevels & 0xffff)); 207 if((accLevels & 0x10000) !=0) { 208 wdgPwdAccess.setBackColor(GralColor.getColor("lrd"), 0); 209 } else { 210 wdgPwdAccess.setBackColor(GralColor.getColor("wh"), 0); 211 } 212 } 213 GralTableLine_ifc<InspcTargetAccessor> line = widgTable.getLine(key); 214 if(line !=null) { 215 line.setCellText(Integer.toHexString(count & 0xff), 0); 216 line.setBackColor(color, 0); 217 line.setCellText(Float.toString(cycle_timeout[0]), 2); 218 line.setCellText(Float.toString(cycle_timeout[1]), 3); 219// if(cycle_timeout !=null) { 220// String sLine = line.getCellText(3); 221// float timeout = StringFunctions_C.parseFloat(sLine, 0, -1, null); 222// if(timeout > 0){ 223// //cycle_timeout[1] = timeout; 224// } 225// } 226 } else { 227 System.err.println("InspcViewTargetComm - unknown target, "+ key); 228 } 229 } 230 231 232 public boolean isLogOn() { return wdgBtnLog.getState()== GralButton.State.On; } 233 234 float getTimeout(String target){ 235 float timeout; 236 GralTableLine_ifc<InspcTargetAccessor> line = widgTable.getLine(target); 237 if(line !=null) { 238 String sLine = line.getCellText(3); 239 timeout = StringFunctions_C.parseFloat(sLine, 0, -1, null); 240 if(timeout <= 0){ 241 timeout = 1.0f; 242 } 243 } else { 244 System.err.println("InspcViewTargetComm - unknown target, "+ target); 245 timeout = 5.0f; 246 } 247 return timeout; 248 } 249 250 /**Action for button log. It switches on or off the logging functionality to log the telegram traffic 251 * for debugging. */ 252 GralUserAction actionOpenWindowTargetSettings = new GralUserAction("InspcGui - OpenPwd"){ 253 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params) { 254 if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){ 255 InspcViewTargetComm.this.targetForSettingsWindow = widgTable.getCurrentLine().data; 256 InspcViewTargetComm.this.targetKeySettingwindow = InspcViewTargetComm.this.targetForSettingsWindow.name; 257 windTargetSettings.setVisible(true); 258 wdgTargetIdent.setText(InspcViewTargetComm.this.targetKeySettingwindow); 259 wdgTimeCycle.setText("" + targetForSettingsWindow.cycle_timeout[0]); 260 wdgTimeout.setText("" + targetForSettingsWindow.cycle_timeout[1]); 261 wdgPwdAccess.setText(""); 262 } 263 return true; 264 } 265 }; 266 267 268 269 /**Action for button log. It switches on or off the logging functionality to log the telegram traffic 270 * for debugging. */ 271 GralUserAction actionSetTargetSettings = new GralUserAction("InspcGui - OpenPwd"){ 272 @Override public boolean exec(int actionCode, GralWidget_ifc widgi, Object... params) { 273 if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){ 274 String pwdAccess = wdgPwdAccess.getText().trim(); 275 String pwdChange = wdgAccLevels.getText().trim(); 276 String sTimeCycle = wdgTimeCycle.getText(); 277 float timeCycle = StringFunctions_C.parseFloat(sTimeCycle, 0, -1, null); 278 String sTimeout = wdgTimeout.getText(); 279 float timeout = StringFunctions_C.parseFloat(sTimeout, 0, -1, null); 280 281 targetForSettingsWindow.setPwdCycle(pwdAccess, timeCycle, timeout); 282 } 283 return true; 284 } 285 }; 286 287 288 /**Action for button log. It switches on or off the logging functionality to log the telegram traffic 289 * for debugging. */ 290 GralUserAction actionClearReq = new GralUserAction("InspcGui - clearReq"){ 291 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params) { 292 if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){ 293 gui.inspcMng.clearRequestedVariables(); 294 InspcTargetAccessor target = widgTable.getCurrentLine().getUserData(); 295 target.setReady(); 296 297 } 298 return true; 299 } 300 }; 301 302 303 304 305 /**Action for button log. It switches on or off the logging functionality to log the telegram traffic 306 * for debugging. */ 307 GralUserAction actionEnableLog = new GralUserAction("InspcGui - enableLog"){ 308 @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params) { 309 if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){ 310 InspcTargetAccessor target = widgTable.getCurrentLine().getUserData(); 311 GralButton widgButton = (GralButton)widgd; 312 if(widgButton.isOn()){ 313 if(logTelg == null){ 314 logTelg = new LogMessageFile("telgLog.csv", 10, 1, null, null, null); 315 } 316 target.setLog(logTelg, 1000); 317 318 } else { 319 if(logTelg !=null){ 320 logTelg.close(); 321 logTelg = null; 322 } 323 target.setLog(null, 1000); 324 } 325 } 326 return true; 327 } 328 }; 329 330 331 332 333}