    001package org.vishia.guiInspc;
    002
    003import java.io.File;
    004import java.io.FileWriter;
    005import java.io.Writer;
    006import java.util.List;
    007import java.util.Map;
    008
    009import org.vishia.byteData.VariableContainer_ifc;
    010import org.vishia.curves.WriteCurveCsv;
    011import org.vishia.curves.WriteCurve_ifc;
    012import org.vishia.fileRemote.FileRemote;
    013import org.vishia.gral.base.GralButton;
    014import org.vishia.gral.base.GralCurveView;
    015import org.vishia.gral.base.GralMenu;
    016import org.vishia.gral.base.GralPos;
    017import org.vishia.gral.base.GralTable;
    018import org.vishia.gral.base.GralTable.TableLineData;
    019import org.vishia.gral.base.GralTextField;
    020import org.vishia.gral.base.GralWidget;
    021import org.vishia.gral.base.GralMng;
    022import org.vishia.gral.base.GralWindow;
    023import org.vishia.gral.ifc.GralColor;
    024import org.vishia.gral.ifc.GralCurveViewTrack_ifc;
    025import org.vishia.gral.ifc.GralCurveView_ifc;
    026import org.vishia.gral.ifc.GralPrimaryWindow_ifc;
    027import org.vishia.gral.ifc.GralTableLine_ifc;
    028import org.vishia.gral.ifc.GralUserAction;
    029import org.vishia.gral.ifc.GralWidget_ifc;
    030import org.vishia.gral.ifc.GralWindow_ifc;
    031import org.vishia.gral.widget.GralColorSelector;
    032import org.vishia.gral.widget.GralFileSelectWindow;
    033import org.vishia.gral.widget.GralColorSelector.SetColorFor;
    034import org.vishia.gral.widget.GralFileSelector;
    035import org.vishia.inspcPC.mng.InspcFieldOfStruct;
    036import org.vishia.util.Assert;
    037import org.vishia.util.Debugutil;
    038import org.vishia.util.FileSystem;
    039import org.vishia.util.KeyCode;
    040import org.vishia.util.StringFormatter;
    041
    042/**A curve view window inside the inspector.
    043 * @author hartmut Schorrig
    044 *
    045 */
    046public final class InspcCurveView
    047{
    048
    049  /**Version, history and license.
    050   * <ul>
    051   * <li>2018-01-08 Hartmut refactoring
    052   *   <ul>
    053   *   <li>private class TrackValues removed, it hasn't any specific content, replaced by {@link GralCurveViewTrack_ifc}
    054   *   which refers a {@link GralCurveView.Track}.
    055   *   <li> new {@link #fillTableTracks()}, content from {@link #actionReadCfg(int, GralWidget_ifc, Object...)}
    056   *     but also invoked in {@link #actionReadValues(int, GralWidget_ifc, Object...)}. That may add tracks.
    057   *   </ul>
    058   * <li>2018-01-08 Hartmut new: If a datapath was written in a cell of variable paths which is not part of table, especially on an clean or small table,
    059   *   than the routine {@link GralTable#getCellTextFocus()} is called to get the datapath as text. This is a new line, it is added.
    060   *   Therewith now it is easy to add lines to an empty table via path in clibboard.
    061   * <li>2016-05-03 Hartmut chg: Selection of file in this window instead an own dialog window:
    062   *   Advantage: This window is always on top. A opened dialog window may be in background - fatal.
    063   *   It is well to use.
    064   * <li>2015-07-12 Hartmut new: switch on and off for curves.
    065   * <li>2015-07-12 Hartmut new: Better usability for scaling. [+] and [-] - Buttons works correctly.
    066   *   Enter in field for scaling values has an effect immediately.
    067   *   Support for more as one track with the same scaling.
    068   * <li>2013-05-19 Hartmut new: {@link #actionTrackSelected} with ctrl and left mouse pressed
    069   * <li>2013-05-15 Hartmut new: Presentation of value on cursor
    070   * <li>2013-05-14 Hartmut chg: 12 Tracks instead 10. A variableWindowSize cause problems (TODO)
    071   * <li>2013-05-14 Hartmut progress: {@link #actionSwapVariable}, {@link #actionShiftVariable}
    072   * <li>2013-05-13 Hartmut new: {@link #actionSwapVariable}, {@link #actionSelectOrChgVarPath}
    073   * <li>2013-03-28 Hartmut adapt new {@link GralFileSelectWindow}
    074   * <li>2013-03-27 Hartmut improved/bugfix: The {@link TrackValues#trackView} is the reference to the track in the
    075   *   {@link GralCurveView} instance. If a new config is loaded all tracks in {@link GralCurveView#getTrackInfo()}
    076   *   are created newly using {@link GralCurveView#addTrack(String, String, GralColor, int, int, float, float)}.
    077   *   Therefore the {@link TrackValues#trackView} should be updated.
    078   * <li>2012-10-09 Hartmut now ctrl-mouse down sets the scale settings for the selected channel. Faster user operation.
    079   * <li>2012-08-10 Hartmut now uses a default directory for config file given in constructor.
    080   * <li>2012-07-06 Hartmut now read and save of the file works.
    081   * <li>2012-06-29 Hartmut new open file dialog
    082   * <li>2012-06-08 Hartmut: new Buttons for read and save the configuration (setting). Yet only a simple file is used.
    083   *   TODO: File selection.
    084   * <li>2012-03-17 Hartmut creating using the {@link GralCurveView} in a special window
    085   *   with the communication in {@link InspcMng}.
    086   * </ul>
    087   * <br><br>
    088   *
    089   * <b>Copyright/Copyleft</b>:
    090   * For this source the LGPL Lesser General Public License,
    091   * published by the Free Software Foundation is valid.
    092   * It means:
    093   * <ol>
    094   * <li> You can use this source without any restriction for any desired purpose.
    095   * <li> You can redistribute copies of this source to everybody.
    096   * <li> Every user of this source, also the user of redistribute copies
    097   *    with or without payment, must accept this license for further using.
    098   * <li> But the LPGL is not appropriate for a whole software product,
    099   *    if this source is only a part of them. It means, the user
    100   *    must publish this part of source,
    101   *    but don't need to publish the whole source of the own product.
    102   * <li> You can study and modify (improve) this source
    103   *    for own using or for redistribution, but you have to license the
    104   *    modified sources likewise under this LGPL Lesser General Public License.
    105   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
    106   * </ol>
    107   * If you are intent to use this sources without publishing its usage, you can get
    108   * a second license subscribing a special contract with the author.
    109   *
    110   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
    111   */
    112  //@SuppressWarnings("hiding")
    113  public final static String sVersion = "2014-01-10";
    114
    115  //boolean bTabWidget = true;
    116
    117  public static String sBtnReadCfg = "read cfg";
    118
    119  public static String sBtnSaveCfg = "save cfg";
    120
    121  public static String sBtnReadValues = "read data";
    122
    123  public static String sBtnSaveValues = "save data";
    124
    125
    126  protected final String sName;
    127
    128  private final Map<String, String> curveExporterClasses;
    129
    130  private final WriteCurve_ifc writerCurveCsv = new WriteCurveCsv();
    131
    132  /**The window for curve view. */
    133  GralWindow windCurve;
    134
    135  /**Used for read/write config and for read/write data*/
    136  private final GralFileSelector widgFileSelector;
    137
    138  private String sWhatTodoWithFile;
    139
    140  /**Shows the name and input name for read/write config and data. */
    141  private final GralTextField widgFilename;
    142
    143
    144
    145  final GralMng gralMng;
    146
    147  final VariableContainer_ifc variables;
    148
    149  private final static String[] colorCurveDefault = new String[]{"rd", "gn", "lbl", "or", "ma", "bn", "dgn", "drd", "cy", "bl", "gn2", "pu"};
    150
    151
    152  /**The input field which is the current scaling field. */
    153  GralCurveViewTrack_ifc trackScale;
    154  int ixTrackScale;
    155
    156  //GralColor colorLineTrackSelected;
    157
    158  final GralColor colorBlack = GralColor.getColor("bk");
    159
    160  GralColor colorTrackSameScale = GralColor.getColor("pgn");
    161
    162  GralColor colorTrackSameScaleSelected = GralColor.getColor("lgn");
    163
    164  GralColor colorTrackOtherScaleSelected = GralColor.getColor("lam");
    165
    166  GralColor colorTrackOtherScale = GralColor.getColor("wh");
    167
    168  GralColor colorTrackNotShown = GralColor.getColor("lgr");
    169
    170  GralColor colorTrackNotShownSelected = GralColor.getColor("gr");
    171
    172  GralColor colorBtnFileActive = GralColor.getColor("am");
    173
    174  GralColor colorBtnFileInactive = GralColor.getColor("wh");
    175
    176  GralTable<GralCurveViewTrack_ifc> widgTableVariables;
    177
    178  GralTextField widgScale, widgScale0, widgline0;
    179
    180  /**The one of {@link #widgScale0}, {@link #widgScale0} or {@link #widgline0} which was focused lastly.
    181   * To use for [+] and [-] button.
    182   */
    183  GralTextField scalingWidg;
    184
    185  GralTextField widgValCursorLeft, widgValCursorRight; ///
    186
    187  GralButton widgBtnUp, widgBtnDn, widgBtnScale, widgBtnReadCfg, widgBtnSaveCfg;
    188
    189  GralButton widgBtnReadValues, widgBtnSaveValues, wdgButtonAutosave, widgBtnColor;
    190
    191
    192  GralButton widgBtnOff;
    193
    194  /**The currently loaded file for curve settings. */
    195  FileRemote fileCurveCfg;
    196
    197  FileRemote dirCurveSave;
    198
    199  //long timeLastSave;
    200
    201  //long timePeriodSave = 1000L * 60 * 2;
    202
    203  //boolean hasDataTosave;
    204
    205  /**Temporary used formatter. */
    206  StringFormatter sFormatter = new StringFormatter(50);
    207
    208  /**Common ColorSelector for all curve views. */
    209  GralColorSelector colorSelector;
    210
    211
    212
    213  //final InspcGuiComm comm;
    214
    215  GralCurveView widgCurve;
    216
    217  /**Creates the instance. The graphical appearance will not be created.
    218   * Call {@link #buildGraphic(GralPrimaryWindow_ifc, GralColorSelector)} to do that.
    219   * @param sName Name shown in title bar
    220   * @param variables Container to find variables
    221   * @param gralMng The Gral Graphic Manager
    222   * @param defaultDir
    223   * @param curveExporterClasses Class which is used to export curves.
    224   */
    225  InspcCurveView(String sName, VariableContainer_ifc variables, GralMng gralMng, FileRemote defaultDirCfg, FileRemote defaultDirSave, Map<String, String> curveExporterClasses){
    226    //this.comm = comm;
    227    this.sName = sName;
    228    this.curveExporterClasses = curveExporterClasses;
    229    this.variables = variables;
    230    this.gralMng = gralMng;
    231    fileCurveCfg = defaultDirCfg;
    232    dirCurveSave = defaultDirSave;
    233    widgFileSelector = new GralFileSelector("-selectFile", 100, new int[]{2,0,-6,-12}, null);
    234    widgFileSelector.specifyActionOnFileSelected(actionSelectFile);
    235    widgFileSelector.setActionOnEnterFile(actionEnterFile);
    236
    237    widgFilename = new GralTextField("-filename", GralTextField.Type.editable);
    238
    239  }
    240
    241
    242  /**Builds the graphic, it should be called only one time on startup in the graphic thread
    243   * @param wind The main window where the menu to open will be added
    244   * @param sName The name, used for menu entry too, sample "curve A"
    245   */
    246  public void buildGraphic(GralWindow_ifc wind, GralColorSelector colorSelector, GralCurveView.CommonCurve common)
    247  {
    248    this.colorSelector = colorSelector;
    249    gralMng.selectPanel("primaryWindow");
    250    //gralMng.setPosition(4, 0, 4, 0, 0, '.');
    251    gralMng.setPosition(4, 56, 4, 104, 0, '.');
    252    //int windProps = GralWindow.windConcurrently | GralWindow.windOnTop | GralWindow.windResizeable;
    253    int windProps = GralWindow.windConcurrently | GralWindow.windOnTop; // | GralWindow.windResizeable;
    254    windCurve = gralMng.createWindow("windMapVariables", sName, windProps);
    255    //gralMng.setPosition(2, GralGridPos.size-1.6f, 0, 3.8f, 0, 'd');
    256    buildGraphicInCurveWindow(common);
    257    GralMenu menu = wind.getMenuBar();
    258    menu.addMenuItem("&Window/open " + sName, actionOpenWindow);
    259  }
    260
    261
    262
    263  void buildGraphicInCurveWindow(GralCurveView.CommonCurve common)
    264  {
    265    int posright = -20;
    266    gralMng.setPosition(0, -4, 0, posright, 0, 'd');
    267    widgFileSelector.createImplWidget_Gthread();
    268    widgFileSelector.setVisible(false);
    269    //widgFileSelector.set
    270    //widgFileSelector.specifyActionOnFileSelected(actionSelectFile);
    271    //widgFileSelector.setActionOnEnterFile(actionOk);
    272    gralMng.setPosition(-4, -2, 0, posright, 0, 'd');
    273    widgFilename.createImplWidget_Gthread();
    274    widgFilename.setVisible(false);
    275    widgFilename.setText("TEST xyz");
    276    gralMng.setPosition(0, -2, 0, posright, 0, 'd');
    277    widgCurve = gralMng.addCurveViewY(sName, 15000, common);
    278    widgCurve.setActionMoveCursor(actionShowCursorValues);
    279    widgCurve.setActionTrackSelected(actionTrackSelectedFromGralCurveViewCtrlMousePressed);
    280    gralMng.setPosition(0, GralPos.size +2, posright, 0, 0, 'd', 0);
    281    gralMng.addText("curve variable");
    282    widgTableVariables = new GralTable<GralCurveViewTrack_ifc>("variables", new int[]{-posright});
    283    gralMng.setPosition(2, GralPos.size +20, posright, 0, 0, 'd', 0);
    284    widgTableVariables.setColumnEditable(0, true);
    285    widgTableVariables.setToPanel(gralMng);
    286    widgTableVariables.specifyActionOnLineSelected(actionSelectVariableInTable);
    287    widgTableVariables.setActionChange(actionKeyHandlingTable);
    288    //widgTableVariables.set
    289    widgTableVariables.addContextMenuEntryGthread(0, null, "switch on-off <F2>", actionOnOffTrack);
    290    widgTableVariables.addContextMenuEntryGthread(0, null, "insert variable", actionInsertVariable);
    291    widgTableVariables.addContextMenuEntryGthread(0, null, "replace variable", actionReplaceVariable);
    292    widgTableVariables.addContextMenuEntryGthread(0, null, "swap variable", actionSwapVariable);
    293    widgTableVariables.addContextMenuEntryGthread(0, null, "delete variable", actionDeleteVariable);
    294    widgTableVariables.addContextMenuEntryGthread(0, null, "shift variable", actionShiftVariable);
    295    widgTableVariables.addContextMenuEntryGthread(0, null, "set color", actionColorSelectorOpen);
    296    widgTableVariables.addContextMenuEntryGthread(0, null, "group scale", actionShareScale);
    297    widgTableVariables.addContextMenuEntryGthread(0, null, "ungroup scale", actionUnshareScale);
    298    gralMng.setPosition(/*22*/-19, GralPos.size +3, -8, 0, 0, 'd', 0);
    299    widgScale = gralMng.addTextField("scale", true, "scale/div", "t");
    300    widgScale.setActionFocused(actionFocusScaling);         //store which field, set color
    301    widgScale.setActionChange(actionSetScaleValues2Track);  //on enter
    302    scalingWidg = widgScale;  //set which is focused
    303    widgScale0 = gralMng.addTextField("scale0", true, "mid", "t");
    304    widgScale0.setActionFocused(actionFocusScaling);        //store which field, set color
    305    widgScale0.setActionChange(actionSetScaleValues2Track);  //on enter
    306    widgline0 = gralMng.addTextField("line0", true, "line-%", "t");
    307    widgline0.setActionFocused(actionFocusScaling);         //store which field, set color
    308    widgline0.setActionChange(actionSetScaleValues2Track);  //on enter
    309    gralMng.setPosition(/*32*/-9, GralPos.size +2, -10, GralPos.size +2, 0, 'r', 1);
    310    /*
    311    gralMng.setPosition(-23, GralPos.size +1, -10, 0, 0, 'd', 2);
    312    gralMng.addText("scale/div");
    313    gralMng.addText("mid");
    314    gralMng.addText("line-%");
    315    gralMng.setPosition(-22, GralPos.size +2, -10, 0, 0, 'd', 1);
    316    widgScale = gralMng.addTextField("scale", true, null, "t");
    317    widgScale0 = gralMng.addTextField("scale0", true, null, "t");
    318    widgline0 = gralMng.addTextField("line0", true, null, "t");
    319    gralMng.setPosition(-12, GralPos.size +2, -10, GralPos.size +2, 0, 'r', 1);
    320    */
    321    widgBtnDn = gralMng.addButton("btnDn", actionSetScaleValues2Track, "-", null,  "-");
    322    widgBtnUp = gralMng.addButton("btnUp", actionSetScaleValues2Track, "+", null, "+");
    323    gralMng.setPosition(GralPos.same, GralPos.size +2, GralPos.next, GralPos.size +4, 0, 'r', 1);
    324    gralMng.addButton("btnScale", actionColorSelectorOpen, "!", null,  "color");
    325    gralMng.setPosition(/*35*/ -6, GralPos.size +2, -10, GralPos.size +6, 0, 'r', 1);
    326    widgBtnScale = gralMng.addButton("btnScale", actionSetScaleValues2Track, "!", null,  "set");
    327    gralMng.setPosition(-22, GralPos.size +3, posright, GralPos.size +11, 0, 'd', 0);
    328    widgValCursorLeft = gralMng.addTextField(null, true, "cursor left", "t");
    329    widgValCursorRight = gralMng.addTextField(null, true, "cursor right", "t");
    330    gralMng.setPosition(-15, GralPos.size +2, posright, GralPos.size +8, 0, 'd', 1);
    331    widgBtnReadCfg = gralMng.addButton("btnReadCfg", actionOpenFileDialog, sBtnReadCfg, null, sBtnReadCfg);
    332    widgBtnSaveCfg = gralMng.addButton("btnSaveCfg", actionOpenFileDialog, sBtnSaveCfg, null, sBtnSaveCfg);
    333    widgBtnReadValues = gralMng.addButton("btnReadValues", actionOpenFileDialog, sBtnReadValues, null, sBtnReadValues);
    334    widgBtnSaveValues = gralMng.addButton("btnSaveValues", actionOpenFileDialog, sBtnSaveValues, null, sBtnSaveValues);
    335    wdgButtonAutosave = gralMng.addSwitchButton("btnAutoSaveValues", "off-autosave", "on-autosave", GralColor.getColor("lgn"), GralColor.getColor("am") );
    336
    337    gralMng.setPosition(-3, GralPos.size +2, -9, -1, 0, 'd', 0);
    338    widgBtnOff = gralMng.addSwitchButton(sName + "btnOff", "off / ?on", "on / ?off", GralColor.getColor("lgn"), GralColor.getColor("am"));
    339
    340
    341  }
    342
    343
    344
    345
    346  void fillTableTracks() {
    347    Iterable<? extends GralCurveViewTrack_ifc> listTracks = widgCurve.getTrackInfo();
    348    widgTableVariables.clearTable();
    349    int iTrack = 0;
    350    for(GralCurveViewTrack_ifc track: listTracks){
    351      String sDataPath = track.getDataPath();
    352      String[] sCellTexts = new String[1];
    353      sCellTexts[0] = sDataPath;
    354      GralTableLine_ifc<GralCurveViewTrack_ifc> line = widgTableVariables.addLine(sDataPath, sCellTexts, track);
    355      line.setTextColor(track.getLineColor());
    356      iTrack +=1;
    357    }
    358    widgTableVariables.setVisible(true);
    359    widgTableVariables.repaint(500,500);
    360
    361  }
    362
    363
    364
    365  void refreshCurve(){
    366    if(widgCurve !=null && widgBtnOff !=null){
    367      GralButton.State state = widgBtnOff.getState();
    368      boolean bActive = state == GralButton.State.On;
    369      widgCurve.activate( bActive);
    370      if(bActive){
    371        //hasDataTosave = true;
    372        widgCurve.refreshFromVariable(variables);
    373      }
    374    }
    375    actionShowCursorValues.exec(0, widgCurve);
    376  }
    377
    378
    379
    380  protected boolean dropVariable(int actionCode, GralWidget widgd, boolean bInsert){
    381    if(actionCode == KeyCode.menuEntered){
    382      GralWidget_ifc variableWidget = gralMng.getLastClickedWidget();
    383      if(variableWidget == null) {
    384        System.err.println("No variable clicked");
    385        return false;
    386      }
    387      String sPath;
    388      if(variableWidget instanceof TableLineData) {
    389        Object data = variableWidget.getData();
    390        if(data instanceof InspcFieldOfStruct) {
    391          @SuppressWarnings("unchecked")
    392          GralTable<InspcFieldOfStruct>.TableLineData line = (GralTable<InspcFieldOfStruct>.TableLineData)variableWidget;
    393          sPath = InspcFieldTable.getDataPath(line); //((InspcFieldOfStruct)data).
    394        } else {
    395          sPath = null;
    396        }
    397      }
    398      else {
    399        sPath = variableWidget.getDataPath();
    400      }
    401      if(sPath !=null) {
    402        GralCurveViewTrack_ifc input;
    403        assert(widgd instanceof GralTable<?>);  //NOTE: context menu to table lines, has GralTable as widget.
    404        @SuppressWarnings("unchecked")
    405        GralTable<GralCurveViewTrack_ifc> table = (GralTable<GralCurveViewTrack_ifc>)widgd; //oContentInfo;
    406        GralTable<GralCurveViewTrack_ifc>.TableLineData refline = table.getLineMousePressed();
    407        int ixnewline =-1;
    408        GralTableLine_ifc<GralCurveViewTrack_ifc> newline = null;
    409        if(bInsert || refline == null){  //insert a line, build a new one
    410          GralColor colorCurve = GralColor.getColor("rd");
    411          input = widgCurve.addTrack(sName, sPath, colorCurve, 0, 50, 5000.0f, 0.0f);
    412          if(refline ==null){
    413            newline = table.addLine(sPath, new String[]{""}, input);  //add on end
    414            ixnewline = table.size();  //first line
    415          } else {
    416            newline = refline.addPrevLine(sPath, new String[]{""}, input);
    417            ixnewline = table.getIxLine(refline);
    418          }
    419          newline.setCellText(sPath, 0);
    420        }
    421        else {
    422          input = (GralCurveViewTrack_ifc)refline.getContentInfo();
    423          input.setDataPath(sPath);
    424          refline.setCellText(sPath, 0);
    425        }
    426        if(newline !=null && ixnewline >=0) {
    427          table.setCurrentLine(newline, ixnewline, 0);
    428        }
    429        table.repaint();
    430      } else {
    431        System.out.printf("InspcCurveView - invalid widget to drop; %s\n", variableWidget.toString());
    432      }
    433    }
    434    return true;
    435
    436  }
    437
    438
    439
    440  protected boolean deleteVariable(int actionCode, GralWidget widgd, boolean bInsert){
    441    if(actionCode == KeyCode.menuEntered){
    442      GralCurveViewTrack_ifc input;
    443      assert(widgd instanceof GralTable<?>);  //NOTE: context menu to table lines, has GralTable as widget.
    444      @SuppressWarnings("unchecked")
    445      GralTable<GralCurveViewTrack_ifc> table = (GralTable<GralCurveViewTrack_ifc>)widgd; //oContentInfo;
    446      GralTable<GralCurveViewTrack_ifc>.TableLineData refline = table.getLineMousePressed();
    447      if(refline != null){
    448        input = (GralCurveViewTrack_ifc)refline.getContentInfo();
    449        if(input != null) {
    450          Debugutil.stop();
    451          //TODO
    452          //refline.deleteLine();
    453          //delete the track line!
    454
    455
    456      } }
    457
    458      table.repaint();
    459    }
    460    return true;
    461
    462  }
    463
    464
    465
    466  void setDatapath(GralTable<GralCurveViewTrack_ifc>.TableLineData line, String sDatapath){
    467    GralCurveViewTrack_ifc input = line.data;
    468    if(input == null){
    469      GralColor colorLine = GralColor.getColor("rd");
    470      input = widgCurve.addTrack(sName, sDatapath, colorLine, 0, 50, 5000.0f, 0.0f);
    471    } else {
    472      input.setDataPath(sDatapath);
    473    }
    474
    475  }
    476
    477
    478
    479
    480  /**Step routine to save a curve. A curve will be saved only if the time has expired and the autoSave button is on.
    481   *
    482   */
    483  public void stepSaveCurve(){
    484    //long timeNextSave = timeLastSave + timePeriodSave;
    485    //long timeNow = System.currentTimeMillis();
    486    if(wdgButtonAutosave !=null && wdgButtonAutosave.isOn() && widgCurve.shouldAutosave()) { //xx hasDataTosave && timeNextSave <= timeNow){
    487      saveCurve(GralCurveView_ifc.ModeWrite.autoSave);
    488    }
    489  }
    490
    491
    492
    493  /**Reads a curve ///
    494   *
    495   */
    496  protected void readCurve(File file){
    497    try{
    498      widgCurve.readCurve(file);
    499    } catch(Exception exc){
    500      widgBtnScale.setLineColor(GralColor.getColor("lrd"),0);
    501      System.err.println(Assert.exceptionInfo("InspcCurveView-read", exc, 1, 2));
    502    }
    503
    504  }
    505
    506
    507  /**Saves a curve ///
    508   *
    509   */
    510  protected void saveCurve(GralCurveView_ifc.ModeWrite mode){
    511    try{
    512      //long dateStart;
    513      CharSequence sDate;
    514      if(mode == GralCurveView_ifc.ModeWrite.autoSave){
    515        sDate = widgCurve.timeInitAutoSave();
    516      } else {
    517        sDate = widgCurve.timeInitSaveViewArea();
    518       // widgCurve.
    519      }
    520      String sNameFile = sDate + "_" + sName;
    521      //fileCurveSave.mkdirs();
    522      FileRemote fileCurveSave = dirCurveSave.child(sNameFile + ".csv");
    523      FileSystem.mkDirPath(fileCurveSave);
    524      System.out.println("InspcCurveView - save curve data to; " + fileCurveSave.getAbsolutePath());
    525      writerCurveCsv.setFile(fileCurveSave);
    526      widgCurve.writeCurve(writerCurveCsv, mode);
    527
    528      String sClassExportDat = curveExporterClasses.get("dat");
    529      if(sClassExportDat !=null){
    530        Class<?> clazzCurveWriter2 = Class.forName(sClassExportDat);
    531
    532        WriteCurve_ifc writerCurve2 = (WriteCurve_ifc)clazzCurveWriter2.newInstance();
    533        File fileDat = new File(dirCurveSave, sNameFile + ".dat");
    534
    535        writerCurve2.setFile(fileDat);
    536        widgCurve.writeCurve(writerCurve2, mode);
    537      }
    538      System.out.println("InspcCurveView - data saved; " + fileCurveSave.getAbsolutePath());
    539
    540      //timeLastSave = System.currentTimeMillis();
    541    } catch(Exception exc){
    542      widgBtnScale.setLineColor(GralColor.getColor("lrd"),0);
    543      System.err.println(Assert.exceptionInfo("InspcCurveView-save", exc, 1, 2));
    544    }
    545
    546  }
    547
    548
    549
    550  /**Adds an info block to the request telegram to get values. This routine is called
    551   * when the tx telegram to get values from target is assembled.
    552   *
    553  void addTxInfoBlock(){
    554    if(widgBtnOff.getState() == GralButton.kOn){
    555      GralCurveViewTrack_ifc inpLast = null;
    556      for(GralCurveViewTrack_ifc inp: tracks){
    557        if(inp.widgetVariable !=null){
    558          String sDataPath = inp.widgetVariable.getDataPath(); //inp.widgVarPath.getText().trim();
    559          //if(sDataPath.length() >0){
    560          inpLast = inp;
    561          inp.bLast = false;  //all set to fast, but only the inpLast.bLast = true;
    562          comm.getValueByPath(sDataPath, inp.rxActionRxValueByPath);
    563        }
    564
    565      } //for
    566      if(inpLast !=null){
    567        //at least one variable given.
    568        inpLast.bLast = true;
    569      }
    570    }
    571  }
    572   */
    573
    574
    575
    576
    577
    578  GralUserAction actionOpenWindow = new GralUserAction("actionOpenWindow"){
    579    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    580      windCurve.setVisible(true); //setWindowVisible(true);
    581      widgFileSelector.setVisible(false);
    582      widgFilename.setVisible(false);
    583      widgBtnReadCfg.setVisible(true);
    584      widgCurve.setFocus();
    585      return true;
    586    }
    587
    588  };
    589
    590
    591
    592  /**This action will be called if the mouse is pressed on the drop field.
    593   * It is not drag and drop because drag'ndrop doesn't works on a field which content is not be able to select.
    594   * That is on show fields. Therefore the {@link GralMng#getLastClickedWidget()} is used to detect
    595   * which show field was clicked last.
    596   *
    597   */
    598  GralUserAction actionReplaceVariable = new GralUserAction("actionReplaceVariable"){
    599    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params)
    600    { return dropVariable(actionCode, (GralWidget)widgd, false);
    601    }
    602  };
    603
    604
    605  GralUserAction actionDeleteVariable = new GralUserAction("actionReplaceVariable"){
    606    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params)
    607    { return deleteVariable(actionCode, (GralWidget)widgd, false);
    608    }
    609  };
    610
    611
    612  GralUserAction actionOnOffTrack = new GralUserAction("actionOnOffTrack"){
    613    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params)
    614    { if(trackScale.getVisible() ==0) {
    615        trackScale.setVisible(2);
    616        //line.setBackColor(colorTrackSameScale, -1);
    617      } else {
    618        trackScale.setVisible(0);
    619        //line.setBackColor(GralColor.getColor("gr"), -1);
    620      }
    621      GralTable<GralCurveViewTrack_ifc>.TableLineData line = widgTableVariables.getCurrentLine();
    622      actionSelectVariableInTable.exec(KeyCode.F2, widgTableVariables, line);
    623      widgCurve.repaint();
    624      return true;
    625    }
    626  };
    627
    628
    629  GralUserAction actionInsertVariable = new GralUserAction("actionInsertVariable"){
    630    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params)
    631    { return dropVariable(actionCode, (GralWidget)widgd, true);
    632    }
    633  };
    634
    635
    636  public GralUserAction actionKeyHandlingTable = new GralUserAction("actionEnterDatapath"){
    637    @Override public boolean exec(int key, GralWidget_ifc widgd, Object... params){
    638      if(key == KeyCode.enter){
    639        @SuppressWarnings("unchecked")  //compatible to Java-6
    640        GralTable<GralCurveViewTrack_ifc>.TableLineData line = (GralTable.TableLineData)params[0];
    641        if(line == null) {
    642          String sDatapath = widgTableVariables.getCellTextFocus();
    643          GralColor colorCurve = GralColor.getColor("red");
    644          GralCurveViewTrack_ifc input = widgCurve.addTrack(sName, sDatapath, colorCurve, 0, 50, 5000.0f, 0.0f);
    645          GralTableLine_ifc<GralCurveViewTrack_ifc> newline = widgTableVariables.addLine(sDatapath, new String[]{""}, input);  //add on end
    646          int ixnewline = widgTableVariables.size();  //first line
    647          newline.setCellText(sDatapath, 0);
    648          widgTableVariables.setCurrentLine(newline, ixnewline, 0);
    649        } else {
    650          String sDatapath = line.getCellText(0);
    651          InspcCurveView.this.setDatapath(line, sDatapath);
    652        }
    653      }
    654      else if(key == KeyCode.F2){
    655        actionOnOffTrack.exec(key, null);
    656      }
    657      return true;
    658    }
    659  };
    660
    661
    662
    663
    664  GralUserAction actionSwapVariable = new GralUserAction("actionSwapVariable"){
    665    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    666      if(actionCode == KeyCode.menuEntered && trackScale !=null){
    667        //read paths
    668        //Object oContent = widgd.getContentInfo();
    669        assert(widgd instanceof GralTable<?>);
    670        @SuppressWarnings("unchecked")
    671        GralTable<GralCurveViewTrack_ifc> table = (GralTable<GralCurveViewTrack_ifc>) widgd;
    672        GralTableLine_ifc<GralCurveViewTrack_ifc> linesrc = table.getCurrentLine();
    673        GralTableLine_ifc<GralCurveViewTrack_ifc> linedst = table.getLineMousePressed();
    674        /*
    675        if(linedst !=null && linesrc != linedst){
    676          TrackValues trackDst = linedst.getUserData();  //(TrackValues)oContent;
    677          //if(trackDst != trackScale){
    678            String sPathSwap = trackDst.getDataPath();
    679            GralColor colorSwap = trackDst.getLineColor(); //trackDst.colorCurve; //
    680            GralCurveViewTrack_ifc trackViewSwap = trackDst;
    681            String sPathDst = trackScale.getDataPath();
    682            GralColor colorDst = trackScale.getLineColor();  //colorCurve; //
    683            GralCurveViewTrack_ifc trackViewDst = trackScale;
    684            //set paths to other.
    685            trackScale.colorCurve = colorSwap;
    686            linesrc.setCellText(sPathSwap, 0);
    687            //linesrc.setKey(sPathSwap);
    688            trackScale.setDataPath(sPathSwap);
    689            linesrc.setTextColor(colorSwap);
    690            trackScale = trackViewSwap;
    691            //the new one can be an empty track:
    692            trackDst.colorCurve = colorDst;
    693            trackDst.setDataPath(sPathDst);
    694            lineDst.setCellText(sPathDst, 0);
    695            lineDst.setTextColor(colorDst);
    696            trackDst = trackViewDst;
    697            //change track for scale. It is the same like mouse1Down on this text field:
    698            //actionSelectOrChgVarPath.exec(KeyCode.mouse1Down, trackDst.widgVarPath);
    699          }
    700        }
    701        */
    702      }
    703      return true;
    704    }
    705  };
    706
    707
    708
    709
    710  GralUserAction actionShiftVariable = new GralUserAction("actionShiftVariable"){
    711    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    712      if(actionCode == KeyCode.menuEntered && trackScale !=null){
    713        //read paths
    714        assert(widgd instanceof GralTable<?>);
    715        @SuppressWarnings("unchecked")
    716        GralTable<GralCurveViewTrack_ifc> table = (GralTable<GralCurveViewTrack_ifc>) widgd;
    717        GralTableLine_ifc<GralCurveViewTrack_ifc> linesrc = table.getCurrentLine();
    718        GralTableLine_ifc<GralCurveViewTrack_ifc> linedst = table.getLineMousePressed();
    719        /*
    720        //save values of the current selected.
    721        if(trackScale != trackDst){
    722
    723          String sPathSel = trackScale.widgVarPath.getText();
    724          GralColor colorSel = trackScale.getLineColor();  //colorCurve; //
    725          GralCurveViewTrack_ifc trackViewSel = trackScale;
    726          if(trackScale.ix > trackDst.ix){  //shift current selected up, shift rest down
    727            int ix;
    728            for(ix = trackScale.ix -1; ix >= trackDst.ix; --ix){
    729              String sPath1 = tracks[ix].widgVarPath.getText();
    730              GralColor color1 = tracks[ix].getLineColor();  //colorCurve; //
    731              GralCurveViewTrack_ifc trackView1 = tracks[ix];
    732              tracks[ix+1].colorCurve = color1;
    733              tracks[ix+1].widgVarPath.setTextColor(color1);
    734              tracks[ix+1].widgVarPath.setText(sPath1);
    735              tracks[ix+1] = trackView1;
    736            }
    737            //write into dst selected.
    738            trackDst.colorCurve = colorSel;
    739            trackDst.widgVarPath.setText(sPathSel);
    740            trackDst.widgVarPath.setTextColor(colorSel);
    741            trackDst = trackViewSel;
    742          } else { //shift current selected down, shift rest up
    743            int ix;
    744            for(ix = trackScale.ix; ix < trackDst.ix-1; ++ix){
    745              String sPath1 = tracks[ix+1].widgVarPath.getText();
    746              GralColor color1 = tracks[ix+1].getLineColor();  //colorCurve; //
    747              GralCurveViewTrack_ifc trackView1 = tracks[ix+1];
    748              tracks[ix].colorCurve = color1;
    749              tracks[ix].widgVarPath.setTextColor(color1);
    750              tracks[ix].widgVarPath.setText(sPath1);
    751              tracks[ix] = trackView1;
    752            }
    753            //write into dst selected.
    754            tracks[ix].colorCurve = colorSel;
    755            tracks[ix].widgVarPath.setText(sPathSel);
    756            tracks[ix].widgVarPath.setTextColor(colorSel);
    757            tracks[ix] = trackViewSel;
    758          }
    759        }
    760        */
    761        //change track for scale. It is the same like mouse1Down on this text field:
    762        //actionSelectOrChgVarPath.exec(KeyCode.mouse1Down, trackDst.widgVarPath);
    763      }
    764      return true;
    765    }
    766  };
    767
    768
    769  GralUserAction actionShareScale = new GralUserAction("actionShareScale"){
    770    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params)
    771    { if( KeyCode.isControlFunctionMouseUpOrMenu(actionCode) && trackScale !=null){
    772        GralTable<GralCurveViewTrack_ifc>.TableLineData refline = widgTableVariables.getLineMousePressed();
    773        GralCurveViewTrack_ifc dst = refline.getUserData();     //the line which should be entered in the scale group
    774        dst.groupTrackScale(trackScale);  //trackScale is the line which was  previously selected.
    775      }
    776      return true;
    777    }
    778  };
    779
    780
    781  GralUserAction actionUnshareScale = new GralUserAction("actionShareScale"){
    782    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params)
    783    { if( KeyCode.isControlFunctionMouseUpOrMenu(actionCode) && trackScale !=null){
    784        GralTable<GralCurveViewTrack_ifc>.TableLineData refline = widgTableVariables.getLineMousePressed();
    785        GralCurveViewTrack_ifc dst = refline.getUserData();
    786        dst.ungroupTrackScale();
    787      }
    788      return true;
    789    }
    790  };
    791
    792
    793  GralUserAction actionSetScaleValues2Track = new GralUserAction("actionSetScaleValues2Track"){
    794    @Override public boolean exec(int actionCode, GralWidget_ifc widgi, Object... params)
    795    { System.out.println("InspcCurveView - actionSetScaleValues2Track, actioncode = " + Integer.toHexString(actionCode));
    796      GralWidget widgd = (GralWidget)widgi;
    797      if( (KeyCode.isControlFunctionMouseUpOrMenu(actionCode) || actionCode == KeyCode.enter) && trackScale !=null){
    798        boolean setScale = false;
    799        GralCurveViewTrack_ifc dst;
    800        if(actionCode == KeyCode.enter) {
    801          dst = trackScale; //TEST
    802          setScale = true;
    803        }
    804        else if(actionCode == KeyCode.menuEntered && widgd.sCmd == null){ //from menu
    805          assert(false);  //unused since shareTrackScale
    806          GralTable<GralCurveViewTrack_ifc>.TableLineData refline = widgTableVariables.getLineMousePressed();
    807          dst = refline.getUserData();
    808          setScale = true;
    809        } else {
    810          dst = trackScale;
    811        }
    812        try {
    813          String s1 = widgScale.getText();
    814          float scale = Float.parseFloat(s1);
    815          s1 = widgScale0.getText();
    816          float scale0 = Float.parseFloat(s1);
    817          s1 = widgline0.getText();
    818          int line0 = (int)Float.parseFloat(s1);
    819          String sNameScalingWidgd = null;
    820          if(widgd.sCmd != null && widgd.sCmd != "!") { //not for set cmd
    821            sNameScalingWidgd = scalingWidg.getName();
    822          }
    823          float[] fixScales = {7.5f, 6.0f, 5.0f, 4.0f, 3.0f, 2.5f, 2.0f, 1.75f, 1.5f, 1.25f, 1.0f};
    824          if(widgd.sCmd == "+" && sNameScalingWidgd.equals("scale")){
    825            float value = scale;
    826            float exp1 = (float)Math.log10(value);
    827            float exp = (float)Math.floor(exp1); //-1.0f;
    828            float base = (float)Math.pow(10.0, exp);
    829            float unit = value/base;  //1.0 till 9.999
    830            if(unit < 1.01f) {
    831              unit = fixScales[0]; base /= 10.0f;
    832            } else {
    833              for(int ii = 0; ii < fixScales.length; ++ii){
    834                if(unit > fixScales[ii]){ unit = fixScales[ii];  break; }
    835            } }
    836            scale = value = unit * base;;
    837            s1 = Float.toString(value);
    838            widgScale.setText(s1);
    839            setScale = true;
    840          }
    841          else if(widgd.sCmd == "-" && sNameScalingWidgd.equals("scale")){
    842            float exp1 = (float)Math.log10(1.01f * scale); //regard rounding effect, 0.1 may be presented by 0.0999999
    843            float exp = (float)Math.floor(exp1); //-1.0f;
    844            float base = (float)Math.pow(10.0, exp);
    845            float unit = scale / base;  //1.0 till 9.999
    846            if(unit >= 0.99f * fixScales[0]) {
    847              unit = 1.0f; base *= 10.0f;
    848            } else {
    849              for(int ii = fixScales.length-1; ii >=0; --ii){
    850                if(unit < 0.98f * fixScales[ii]){ unit = fixScales[ii];  break; }
    851            } }
    852            //scale = value = value*2;
    853            scale = unit * base;;
    854            s1 = Float.toString(scale);
    855            widgScale.setText(s1);
    856            setScale = true;
    857          }
    858          else if(widgd.sCmd == "-" && sNameScalingWidgd.equals("scale0")){
    859            if(scale0 >0 && scale0 < scale) {
    860              scale0 = 0;  //trap the 0.0
    861            } else {
    862              scale0 -= scale;
    863            }
    864            s1 = Float.toString(scale0);
    865            widgScale0.setText(s1);
    866            setScale = true;
    867          }
    868          else if(widgd.sCmd == "+" && sNameScalingWidgd.equals("scale0")){
    869            if(scale0 <0 && scale0 > -scale) {
    870              scale0 = 0;  //trap the 0.0
    871            } else {
    872              scale0 += scale;
    873            }
    874            s1 = Float.toString(scale0);
    875            widgScale0.setText(s1);
    876            setScale = true;
    877          }
    878          else if(widgd.sCmd == "-" && sNameScalingWidgd.equals("line0")){
    879            if(line0 >= 5.0f) {
    880              line0 -= 5.0f;
    881              s1 = Float.toString(line0);
    882              widgline0.setText(s1);
    883              setScale = true;
    884            }
    885          }
    886          else if(widgd.sCmd == "+" && sNameScalingWidgd.equals("line0")){
    887            if(line0 < 95.0f) {
    888              line0 += 5.0f;
    889              s1 = Float.toString(line0);
    890              widgline0.setText(s1);
    891              setScale = true;
    892            }
    893          }
    894
    895          //set the scale.
    896          if(dst !=null && (  setScale   //maybe cmd '+' or '-', maybe menu
    897                           || widgd.sCmd == "!"  //set key
    898                  )        ) {
    899            //widgCurve.setMinMax(trackScale.scale, -trackScale.scale);
    900            if(dst == null){
    901              dst = widgCurve.addTrack(sName, null, trackScale.getLineColor(), 0, 50, 5000.0f, 0.0f);
    902            }
    903            widgCurve.repaint(500,500);
    904            dst.setTrackScale(scale, scale0, line0);
    905            widgBtnScale.setTextColor(GralColor.getColor("lgn"));
    906          }
    907        } catch(NumberFormatException exc){
    908          widgBtnScale.setLineColor(GralColor.getColor("lrd"),0);
    909        }
    910      }
    911      return true;
    912  } };
    913
    914
    915
    916
    917  GralUserAction actionScaleFromMarkedTrack = new GralUserAction("actionScaleFromMarkedTrack"){
    918    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    919      GralTableLine_ifc markedLine = widgTableVariables.getFirstMarkedLine(1);
    920      if(markedLine !=null){
    921        //float scale = markedLine.
    922      }
    923      return true;
    924  } };
    925
    926
    927
    928  /**called if The text field was entered with mouse
    929   * or the focus lost on a changed variable path field.
    930   *
    931   */
    932  GralUserAction actionSelectVariableInTable = new GralUserAction("actionSelectOrChgVarPath"){
    933    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    934      @SuppressWarnings("unchecked") ////
    935      GralTableLine_ifc<GralCurveViewTrack_ifc> line = (GralTableLine_ifc<GralCurveViewTrack_ifc>)params[0];
    936      if(line !=null){
    937        GralCurveViewTrack_ifc track = line.getUserData(); //(GralCurveViewTrack_ifc)line.getContentInfo();
    938        if(track !=null){
    939          //set the background color of all line with the same scaling.
    940          if( track ==null //deselect scaled lines
    941            || trackScale !=null && !track.isGroupedTrackScale(trackScale) //don't do if it is the same scale group
    942            || actionCode == KeyCode.F2 //invoked from actionOnOffTrack
    943            ) {
    944            for(GralTableLine_ifc<GralCurveViewTrack_ifc> line1: widgTableVariables.iterLines()) { ////
    945              GralCurveViewTrack_ifc track1 = line1.getUserData();
    946              if(track1 !=null && track1.getVisible() == 0) {
    947                line1.setBackColor(colorTrackNotShown, colorTrackNotShownSelected, colorTrackNotShownSelected, colorTrackNotShownSelected, colorTrackNotShownSelected, -1);
    948              }
    949              else if(track1 !=null && track!=null && track1.isGroupedTrackScale(track)){
    950                line1.setBackColor(colorTrackSameScale, colorTrackSameScaleSelected, colorTrackSameScaleSelected, colorTrackSameScaleSelected, colorTrackSameScaleSelected, -1);  //same scale
    951              } else {
    952                line1.setBackColor(colorTrackOtherScale, colorTrackOtherScaleSelected, colorTrackOtherScaleSelected, colorTrackOtherScaleSelected, colorTrackOtherScaleSelected, -1);
    953              }
    954            }
    955            widgTableVariables.repaint(500,500);
    956          }
    957          //set the line from the last selection to normal
    958          if(trackScale !=null && trackScale !=null){
    959            trackScale.setLineProperties(trackScale.getLineColor(), 1, 0);
    960            if(trackScale.getVisible() !=0){
    961              trackScale.setVisible(1);
    962            }
    963          }
    964          //set the track bold and show the scaling of the track
    965          InspcCurveView.this.trackScale = track;
    966          if(trackScale !=null && trackScale.getVisible() !=0){
    967            trackScale.setLineProperties(trackScale.getLineColor(), 3, 0);
    968            trackScale.setVisible(2);
    969            widgScale.setText("" + track.getScale7div());
    970            widgScale0.setText("" + track.getOffset());
    971            widgline0.setText("" + track.getLinePercent());
    972          }
    973          System.out.println("InspcCurveView.action - SelectVariableInTable");
    974          widgCurve.repaint(100, 200);
    975        }
    976      }
    977      return true;
    978    }
    979  };
    980
    981
    982
    983
    984  /**called if The text field was entered with mouse
    985   * or the focus lost on a changed variable path field.
    986   *
    987   */
    988  GralUserAction actionSelectOrChgVarPath = new GralUserAction("actionSelectOrChgVarPath"){
    989    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    990      assert(false);
    991      GralWidget widg = (GralWidget)widgd;
    992      if(actionCode == KeyCode.mouse1Down || actionCode == KeyCode.menuEntered){
    993        chgSelectedTrack((GralCurveViewTrack_ifc)widgd.getContentInfo());
    994      }
    995      else if(actionCode == (KeyCode.mouse1Down | KeyCode.ctrl)){
    996        if(trackScale !=null){
    997          //last variable
    998          //trackScale.widgVarPath.setBackColor(GralColor.getColor("wh"),0);
    999          if(trackScale !=null){
    1000            trackScale.setLineProperties(trackScale.getLineColor(), 1, 0);
    1001          }
    1002        }
    1003        trackScale = (GralCurveViewTrack_ifc)widgd.getContentInfo();
    1004        if(trackScale == null){
    1005          trackScale = widgCurve.addTrack(sName, null, trackScale.getLineColor(), 0, 50, 5000.0f, 0.0f);
    1006        }
    1007        //colorLineTrackSelected = trackScale.getLineColor();
    1008        trackScale.setLineProperties(trackScale.getLineColor(), 3, 0);
    1009        //trackScale.widgVarPath.setBackColor(GralColor.getColor("lam"),0);
    1010        try{
    1011          String s1 = widgScale.getText();
    1012          float scale = Float.parseFloat(s1);
    1013          s1 = widgScale0.getText();
    1014          float scale0 = Float.parseFloat(s1);
    1015          s1 = widgline0.getText();
    1016          int line0 = (int)Float.parseFloat(s1);
    1017          //widgCurve.setMinMax(trackScale.scale, -trackScale.scale);
    1018          trackScale.setTrackScale(scale, scale0, line0);
    1019        } catch(NumberFormatException exc){
    1020          System.err.println("InspcCurveView - read scale values format error.");
    1021        }
    1022      }
    1023      else if(actionCode == KeyCode.focusLost && widgd.isChanged(true)){
    1024        String sPath = (widg).getValue();
    1025        if(sPath.length() >0 && !sPath.endsWith(".")){
    1026          GralCurveViewTrack_ifc track = (GralCurveViewTrack_ifc)widgd.getContentInfo();
    1027          track.setDataPath(sPath);
    1028        }
    1029      }
    1030      return true;
    1031    }
    1032  };
    1033
    1034
    1035
    1036  GralUserAction actionOpenFileDialog = new GralUserAction("OpenFileDialog"){
    1037    @SuppressWarnings("synthetic-access") @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params)
    1038    { if(actionCode == KeyCode.mouse1Up){
    1039        try{
    1040          String sCmd = widgd.getCmd();
    1041          if(sCmd.equals(sWhatTodoWithFile)) {
    1042            //file dialog is open, second press
    1043            actionEnterFile.exec(KeyCode.menuEntered, null);
    1044            //setVisible already done.
    1045          } else if(sWhatTodoWithFile !=null) {
    1046            //other button, it is esc
    1047            sWhatTodoWithFile = null;
    1048            widgFilename.setVisible(false);
    1049            widgFileSelector.setVisible(false);
    1050            widgCurve.setVisible(true);
    1051            widgBtnReadCfg.setBackColor(colorBtnFileInactive,0);
    1052            widgBtnSaveCfg.setBackColor(colorBtnFileInactive,0);
    1053            widgBtnReadValues.setBackColor(colorBtnFileInactive,0);
    1054            widgBtnSaveValues.setBackColor(colorBtnFileInactive,0);
    1055          } else {
    1056            //button pressed first time because .WhatTodoWithFile == null
    1057            sWhatTodoWithFile = widgd.getCmd(); //The button cmd.
    1058            widgd.setBackColor(colorBtnFileActive, 0);
    1059            final FileRemote dir;
    1060            if(sCmd.equals(sBtnReadCfg)){
    1061              dir = fileCurveCfg;
    1062            } else if(widgd.getCmd().equals(sBtnSaveCfg)){
    1063              //windFileCfg.openDialog(fileCurveCfg, widgd.getCmd(), true, actionSaveCfg);
    1064              dir = fileCurveCfg;
    1065            } else if(widgd.getCmd().equals(sBtnReadValues)){
    1066              //windFileCfg.openDialog(dirCurveSave, "read values", false, actionReadValues);
    1067              dir = dirCurveSave;
    1068            } else if(widgd.getCmd().equals(sBtnSaveValues)){
    1069              //windFileCfg.openDialog(dirCurveSave, "write values", true, actionSaveValues);
    1070              dir = dirCurveSave;
    1071            } else {
    1072              dir = null; //unexpected
    1073            }
    1074            //windFileCfg.openDialog(fileCurveCfg, widgd.getCmd(), false, actionReadCfg);
    1075            widgCurve.setVisible(false);
    1076            widgFilename.setVisible(true);
    1077            widgFileSelector.setVisible(true);
    1078            widgFileSelector.fillIn(dir, false);
    1079            widgFileSelector.setFocus();
    1080          }
    1081        } catch(Exception exc){
    1082          widgBtnScale.setLineColor(GralColor.getColor("lrd"),0);
    1083        }
    1084      }
    1085      return true;
    1086  } };
    1087
    1088
    1089  /**Action invoked for any selected file. */
    1090  GralUserAction actionSelectFile = new GralUserAction("GralFileSelector-actionSelectFile"){
    1091    /**The action called from {@link GralTable}.
    1092     * @param params [0] is the Table line. The content of table cells are known here,
    1093     *   because it is the file table itself. The {@link GralTableLine_ifc#getUserData()}
    1094     *   returns the {@link FileRemote} file Object.
    1095     * @see org.vishia.gral.ifc.GralUserAction#userActionGui(int, org.vishia.gral.base.GralWidget, java.lang.Object[])
    1096     */
    1097    @SuppressWarnings("synthetic-access") @Override
    1098    public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    1099      GralTableLine_ifc<?> line = (GralTableLine_ifc<?>) params[0];
    1100      String sFileCell = line.getCellText(GralFileSelector.kColFilename);
    1101      widgFilename.setText(sFileCell);
    1102      return true;
    1103    }
    1104  };
    1105
    1106
    1107  /**Action for Enter the file.
    1108   */
    1109  GralUserAction actionEnterFile = new GralUserAction("GralFileSelector-actionOk"){
    1110    @SuppressWarnings("synthetic-access") @Override
    1111    public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    1112      if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){  //supress both mouse up and down reaction
    1113        FileRemote dir = widgFileSelector.getCurrentDir();
    1114        String sFilename = widgFilename.getText();
    1115        FileRemote file;
    1116        if(sFilename.length()==0 || sFilename.equals("..")){
    1117          file = dir;
    1118        } else {
    1119          file = dir.child(sFilename);
    1120        }
    1121        if(sWhatTodoWithFile.equals(sBtnReadCfg)) {
    1122          actionReadCfg(KeyCode.menuEntered, null, file);
    1123          widgBtnReadCfg.setBackColor(colorBtnFileInactive, 0);
    1124        }
    1125        else if(sWhatTodoWithFile.equals(sBtnSaveCfg)) {
    1126          actionSaveCfg(KeyCode.menuEntered, null, file);
    1127          widgBtnSaveCfg.setBackColor(colorBtnFileInactive, 0);
    1128        }
    1129        else if(sWhatTodoWithFile.equals(sBtnReadValues)) {
    1130          actionReadValues(KeyCode.menuEntered, null, file);
    1131          widgBtnReadValues.setBackColor(colorBtnFileInactive, 0);
    1132        }
    1133        else if(sWhatTodoWithFile.equals(sBtnSaveValues)) {
    1134          actionSaveValues(KeyCode.menuEntered, null, file);
    1135          widgBtnSaveValues.setBackColor(colorBtnFileInactive, 0);
    1136        }
    1137        sWhatTodoWithFile = null;
    1138        widgFilename.setVisible(false);
    1139        widgFileSelector.setVisible(false);
    1140        widgCurve.setVisible(true);
    1141
    1142      }
    1143      return true;
    1144    }
    1145  };
    1146
    1147
    1148
    1149
    1150  boolean actionReadCfg(int actionCode, GralWidget_ifc widgd, Object... params)
    1151  { if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){
    1152      try{
    1153        fileCurveCfg = (FileRemote)params[0];
    1154        System.out.println("InspcCurveView - read curve view from; " + fileCurveCfg.getAbsolutePath());
    1155        windCurve.setTitle(InspcCurveView.this.sName + ": " + fileCurveCfg.getName());
    1156        String in = FileSystem.readFile(fileCurveCfg);
    1157        if(in ==null){
    1158          System.err.println("InspcCurveView - actionRead, file not found;" + fileCurveCfg.getAbsolutePath());
    1159        } else {
    1160          if(widgCurve.applySettings(in)){ //apply the content of the config file to the GralCurveView
    1161            //and transfer the names into the variable text fields of this widget.
    1162            fillTableTracks();
    1163          }
    1164        }
    1165      } catch(Exception exc){
    1166        widgBtnScale.setLineColor(GralColor.getColor("lrd"),0);
    1167      }
    1168      //windFileCfg.closeWindow();
    1169    }
    1170    return true;
    1171  }
    1172
    1173
    1174
    1175
    1176  void actionSaveCfg(int actionCode, GralWidget_ifc widgd, Object... params)
    1177  { if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){
    1178      try{
    1179        fileCurveCfg = (FileRemote)params[0];
    1180        //File file = new File("curve.save");
    1181        System.out.println("InspcCurveView - save curve view to; " + fileCurveCfg.getAbsolutePath());
    1182        Writer out = new FileWriter(fileCurveCfg);
    1183        String sTimeVariable = widgCurve.getTimeVariable();
    1184        if(sTimeVariable !=null){
    1185          out.append("timeVariable = ").append(sTimeVariable).append(";\n");
    1186        }
    1187        //don't use: widgCurve.writeSettings(out);
    1188        //because it writes the order of curves in the view.
    1189        List<GralCurveViewTrack_ifc> listTable = widgTableVariables.getListContent();
    1190        for(GralCurveViewTrack_ifc trackValue: listTable){
    1191          GralCurveViewTrack_ifc track = trackValue;
    1192          String sDataPath;
    1193          int ix = 0;
    1194          if(track !=null && (sDataPath = track.getDataPath()) !=null && sDataPath.length() >0){
    1195            out.append("track ").append("Track").append(Integer.toString(ix)).append(":");
    1196            out.append(" datapath=").append(sDataPath);
    1197            GralColor lineColor = track.getLineColor();
    1198            if(lineColor !=null){
    1199              out.append(", color=").append(track.getLineColor().toString());
    1200            } else {
    1201              out.append(", color=0x000000");
    1202            }
    1203            out.append(", scale=").append(Float.toString(track.getScale7div()));
    1204            out.append(", offset=").append(Float.toString(track.getOffset()));
    1205            out.append(", 0-line-percent=").append(Integer.toString(track.getLinePercent()));
    1206            out.append(";\n");
    1207          }
    1208          ix +=1;
    1209        }
    1210        out.close();  //NOTE: it is not closed on any write exception.
    1211      } catch(Exception exc){
    1212        widgBtnScale.setLineColor(GralColor.getColor("lrd"),0);
    1213      }
    1214    }
    1215  }
    1216
    1217
    1218
    1219  /**Action invoked if the read file was selected in the {@link GralFileSelectWindow}
    1220   */
    1221  void actionReadValues(int actionCode, GralWidget_ifc widgd, Object... params)
    1222  { if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){
    1223      try{
    1224        assert(params[0] instanceof File);
    1225        FileRemote file = (FileRemote)params[0];
    1226        dirCurveSave = file.getParentFile();
    1227
    1228        readCurve(file);
    1229        fillTableTracks();
    1230
    1231        ///
    1232
    1233      } catch(Exception exc){
    1234        widgBtnScale.setLineColor(GralColor.getColor("lrd"),0);
    1235        System.err.println(Assert.exceptionInfo("InspcCurveView - Read Curve", exc, 1, 2));
    1236      }
    1237    }
    1238  }
    1239
    1240
    1241  /**Action invoked if the write file was selected in the {@link GralFileSelectWindow}
    1242   */
    1243  void actionSaveValues(int actionCode, GralWidget_ifc widgd, Object... params)
    1244  { if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){
    1245      try{
    1246        dirCurveSave = (FileRemote)params[0];
    1247        if(dirCurveSave.exists() && !dirCurveSave.isDirectory()){
    1248          dirCurveSave = dirCurveSave.getParentFile();
    1249        }
    1250        saveCurve(GralCurveView_ifc.ModeWrite.currentView);
    1251        ///
    1252
    1253      } catch(Exception exc){
    1254        widgBtnScale.setLineColor(GralColor.getColor("lrd"),0);
    1255        System.err.println(Assert.exceptionInfo("InspcCurveView - dirCurveSave", exc, 1, 2));
    1256      }
    1257    }
    1258  }
    1259
    1260
    1261  public GralUserAction actionFocusScaling = new GralUserAction("actionSetFocusScaling"){
    1262    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    1263      if(actionCode == KeyCode.focusGained) {
    1264        if(scalingWidg !=null){
    1265          scalingWidg.setBackColor(GralColor.getColor("wh"), 0);   //current, old
    1266        }
    1267        scalingWidg = (GralTextField)widgd;
    1268        scalingWidg.setBackColor(GralColor.getColor("lam"), 0);  //the new one
    1269      }
    1270      return true;
    1271    }
    1272  };
    1273
    1274
    1275  public GralUserAction actionColorSelectorOpen = new GralUserAction("GralColorSelector-open"){
    1276    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    1277      if(KeyCode.isControlFunctionMouseUpOrMenu(actionCode)){
    1278        if(colorSelector == null) {
    1279          colorSelector = new GralColorSelector("colorSelector", GralMng.get());
    1280
    1281        }
    1282        colorSelector.openDialog("select Color for selected track", actionColorSet);
    1283        return true;
    1284      } else return false;
    1285    }
    1286  };
    1287
    1288
    1289  public GralColorSelector.SetColorIfc actionColorSet = new GralColorSelector.SetColorIfc(){
    1290    @Override public void setColor(GralColor color, SetColorFor what)
    1291    { if(what == SetColorFor.line){
    1292        if(trackScale !=null){
    1293          /*
    1294          if(trackScale == null){
    1295            trackScale = widgCurve.initTrack(sName, null, trackScale.colorCurve, 0, 50, 5000.0f, 0.0f);
    1296          }
    1297          trackScale.setLineProperties(color, 3, 0);  //change color immediately to see what happen
    1298          trackScale.colorCurve = color;
    1299          */
    1300          GralTableLine_ifc<GralCurveViewTrack_ifc> line = widgTableVariables.getCurrentLine();
    1301          line.setTextColor(color);
    1302          GralCurveViewTrack_ifc track = (GralCurveViewTrack_ifc)line.getContentInfo();
    1303          if(track == trackScale){
    1304            track.setLineProperties(color, 3, 0);  //change color immediately to see what happen
    1305            trackScale.setLineProperties(color, ixTrackScale, ixTrackScale);
    1306          } else {
    1307            track.setLineProperties(color, 1, 0);  //change color immediately to see what happen
    1308          }
    1309          //trackScale.widgVarPath.setTextStyle(color, null);
    1310      }
    1311    } else {
    1312      System.out.println("InspcCurveView - unexpected what");
    1313    }
    1314  } };
    1315
    1316
    1317  public GralUserAction actionShowCursorValues = new GralUserAction("actionShowCursorValues"){
    1318    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    1319      if(trackScale !=null && trackScale !=null){
    1320        float valueCursorLeft = trackScale.getValueCursorLeft();
    1321        float valueCursorRight = trackScale.getValueCursorRight();
    1322        widgValCursorLeft.setText("" + valueCursorLeft);
    1323        widgValCursorRight.setText("" + valueCursorRight);
    1324      }
    1325      return true;
    1326    }
    1327  };
    1328
    1329
    1330
    1331
    1332
    1333
    1334  public GralUserAction actionTrackSelectedFromGralCurveViewCtrlMousePressed = new GralUserAction("actionTrackSelected"){
    1335    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params){
    1336      //assert(false);
    1337      GralCurveViewTrack_ifc trackNew = (GralCurveViewTrack_ifc)params[0];
    1338      if(trackScale !=null && trackScale == trackNew) return true;  //do nothing.
    1339      else {
    1340        widgTableVariables.setCurrentLine(trackNew.getDataPath());
    1341        //Note: the GralTable will call actionSelectVariableInTable and mark the line.
    1342      }
    1343      return true;
    1344    }
    1345  };
    1346
    1347
    1348
    1349  protected void chgSelectedTrack(GralCurveViewTrack_ifc trackNew){
    1350    assert(false);
    1351    if(trackScale !=null){
    1352      //last variable
    1353      //trackScale.widgVarPath.setBackColor(GralColor.getColor("wh"),0);
    1354      if(trackScale !=null){
    1355        trackScale.setLineProperties(null, 1, 0);
    1356      }
    1357    }
    1358    trackScale = trackNew; //(GralCurveViewTrack_ifc)widgd.getContentInfo();
    1359    if(trackScale == null){
    1360      GralColor lineColor = GralColor.getColor("rd");
    1361      trackScale = widgCurve.addTrack(sName, null, lineColor, 0, 50, 5000.0f, 0.0f);
    1362    }
    1363    //colorLineTrackSelected = trackScale.getLineColor();
    1364    trackScale.setLineProperties(null, 3, 0);
    1365    //trackScale.widgVarPath.setBackColor(GralColor.getColor("lam"),0);
    1366    widgScale.setText("" + trackScale.getScale7div());
    1367    widgScale0.setText("" + trackScale.getOffset());
    1368    widgline0.setText("" + trackScale.getLinePercent());
    1369    widgCurve.repaint(100, 200);
    1370
    1371  }
    1372
    1373
    1374
    1375
    1376
    1377}