    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}