    001package org.vishia.gral.cfg;
    002
    003import java.util.ArrayList;
    004import java.util.LinkedList;
    005import java.util.List;
    006import java.util.Map;
    007import java.util.Set;
    008import java.util.TreeMap;
    009
    010import org.vishia.gral.ifc.GralMngBuild_ifc;
    011
    012
    013/**This class contains all configuration data for the appearance of the GUI.
    014 * It can be filled by {@link org.vishia.gral.cfg.GralCfgZbnf} or others.
    015 * It is changed by user handling on GUI.
    016 * It can be written out in a new configuration file
    017 *
    018 * @author Hartmut Schorrig
    019 *
    020 */
    021public final class GralCfgData
    022{
    023
    024  /**Version and history
    025   * <ul>
    026   * <li>2014-02-24 Hartmut new element help now also in config.
    027   * <li>2013-12-02 Hartmut new conditional configuration.
    028   * <li>2012-04-22 Hartmut support {@link #new_Type()}.
    029   * <li>2012-02-25 Hartmut chg {@link GuiCfgCurveLine#colorValue} = -1 initially to check whether it is given,
    030   *   see {@link GralCfgBuilder#buildWidget(GralCfgElement)}
    031   * <li>2011-06-00 Hartmut created: The old concept was evaluating ZBNF parse result of cfg file manually,
    032   *   now usage of {@link org.vishia.zbnf.ZbnfJavaOutput} to write result info in this class.
    033   * </ul>
    034   *
    035   * <b>Copyright/Copyleft</b>:<br>
    036   * For this source the LGPL Lesser General Public License,
    037   * published by the Free Software Foundation is valid.
    038   * It means:
    039   * <ol>
    040   * <li> You can use this source without any restriction for any desired purpose.
    041   * <li> You can redistribute copies of this source to everybody.
    042   * <li> Every user of this source, also the user of redistribute copies
    043   *    with or without payment, must accept this license for further using.
    044   * <li> But the LPGL is not appropriate for a whole software product,
    045   *    if this source is only a part of them. It means, the user
    046   *    must publish this part of source,
    047   *    but doesn't need to publish the whole source of the own product.
    048   * <li> You can study and modify (improve) this source
    049   *    for own using or for redistribution, but you have to license the
    050   *    modified sources likewise under this LGPL Lesser General Public License.
    051   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
    052   * </ol>
    053   * If you intent to use this source without publishing its usage, you can get
    054   * a second license subscribing a special contract with the author.
    055   *
    056   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
    057   */
    058  public static final int version = 20120422;
    059
    060
    061
    062  public final class Conditional
    063  {
    064    public boolean condition;
    065
    066
    067    final Conditional parentLevel;
    068
    069    public Conditional(GralCfgData cfgData, Conditional parent){
    070      //super(cfgData);
    071      parentLevel = parent;
    072    }
    073
    074  }
    075
    076
    077
    078  /**ZBNF: DataReplace::= <$?key> = <$-/\.?string> ;
    079   * Class for temporary instance to capture key and string. */
    080  public final static class DataReplace
    081  { public String key; public String string;
    082  }//class DataReplace
    083
    084
    085  /**ZBNF: Element::= ... ;
    086   * Class for instance to capture and store one element. */
    087  //public final static class GuiCfgElement
    088
    089  /**ZBNF: position::= ... ;
    090   * Class for instance to capture and store the position in an element. */
    091  //public final static class GuiCfgPosition{  }//class Position
    092
    093
    094  /**This is the base class of all configuration data for one widget. It contains common elements.
    095   * It is used as destination for the parser of the configuration file.
    096   */
    097  public static class GuiCfgWidget implements Cloneable
    098  {
    099    /**Backward aggregation to the config element queue, to the item.*/
    100    private final GralCfgElement itsElement;
    101
    102    /**See {@link org.vishia.gral.base.GralWidget#whatIs}. */
    103    final char whatIs;
    104
    105    public boolean editable;
    106
    107    /**From ZBNF-parser param::=<?> ...name = <""?name> etc. values are set if it is parsed. */
    108    public String name, text, cmd, userAction, mouseAction, data, showMethod, format, type, prompt, promptPosition, help;
    109
    110    /**From ZBNF-parser param::=<?> ...dropFiles = <""?name> etc. values are set if it is parsed. */
    111    public String dragFiles, dropFiles, dragText, dropText;
    112
    113    //public GuiCfgColor colorName = null;
    114    public GuiCfgColor color0 = null, color1 = null;
    115
    116    /**From ZBNF-parser param::=<?> ...<?dragFiles> etc. boolean values are set if <?name> is parsed. */
    117
    118    public GuiCfgWidget(GralCfgElement itsElement, char whatIs){
    119      this.itsElement = itsElement;
    120      this.whatIs = whatIs;
    121    }
    122
    123    public void set_data(String val){ this.data = val; }
    124
    125    public void set_help(String sHelp){ this.help = sHelp; }
    126
    127    public GuiCfgColor new_colorName(){ return color0 = new GuiCfgColor(); }
    128
    129    public void set_colorName(GuiCfgColor value){}
    130
    131    public GuiCfgColor new_color0(){ return color0 = new GuiCfgColor(); }
    132
    133    public void set_color0(GuiCfgColor value){}
    134
    135    public GuiCfgColor new_color1(){ return color1 = new GuiCfgColor(); }
    136
    137    public void set_color1(GuiCfgColor value){}
    138
    139    @Override
    140    protected GuiCfgWidget clone()
    141    { GuiCfgWidget clone = null;
    142      try{ clone = (GuiCfgWidget)super.clone(); }
    143      catch(CloneNotSupportedException exc){ assert(false); }
    144      return clone;
    145    }
    146
    147    /**Sets all fields which are not determined by this instance from any other instance,
    148     * especially from a type instance.
    149     * @param src source for all values which are not determined in this yet.
    150     */
    151    public void setFromType(GuiCfgWidget src){
    152      if(text ==null){ text = src.text; }
    153      if(cmd ==null){ cmd = src.cmd; }
    154      if(userAction ==null){ userAction = src.userAction; }
    155      if(data ==null){ data = src.data; }
    156      if(showMethod ==null){ showMethod = src.showMethod; }
    157      if(prompt ==null){ prompt = src.prompt; }
    158      if(promptPosition !=null){ promptPosition = src.promptPosition;}
    159      if(dragFiles ==null){ dragFiles = src.dragFiles; }
    160      if(dropFiles ==null){ dropFiles = src.dropFiles; }
    161      if(dragText ==null){ dragText = src.dragText; }
    162      //if(colorName ==null){ colorName = src.colorName; }
    163      if(color0 ==null){ color0 = src.color0; }
    164      if(color1 ==null){ color1 = src.color1; }
    165    }
    166
    167
    168  }//class WidgetTypeBase
    169
    170
    171  /**ZBNF: Text::= ... ;
    172   * Class for instance to capture and store the Table data. */
    173  public final static class GuiCfgType extends GuiCfgWidget implements Cloneable
    174  {
    175    public String typeName;
    176    public GuiCfgType(){ super(null, '*'); }
    177  }
    178
    179
    180  /**ZBNF: Text::= ... ;
    181   * Class for instance to capture and store the Table data. */
    182  public final static class GuiCfgText extends GuiCfgWidget implements Cloneable
    183  {
    184    public String size = "B";
    185    public int colorValue;
    186    public GuiCfgText(GralCfgElement itsElement){ super(itsElement, 'S'); }
    187    public void XXXset_colorValue(int value){
    188      //colorName =
    189    }
    190  }
    191
    192
    193  /**ZBNF: Text::= ... ;
    194   * Class for instance to capture and store the Table data. */
    195  public final static class GuiCfgLed extends GuiCfgWidget implements Cloneable
    196  {
    197    //public String size = "B";
    198    public GuiCfgLed(GralCfgElement itsElement){ super(itsElement, 'D'); }
    199
    200    @Override
    201    public void set_data(String val){ this.data = val; }
    202
    203  }
    204
    205
    206
    207  /**ZBNF: Line::= ... ;
    208   * Class for instance to capture and store the Table data. */
    209  public final static class GuiCfgLine extends GuiCfgWidget implements Cloneable
    210  {
    211    List<GuiCfgCoord> coords = new LinkedList<GuiCfgCoord>();
    212
    213    public GuiCfgLine(GralCfgElement itsElement){ super(itsElement, 'I'); }
    214
    215    public void set_coord(String value){}
    216
    217    public GuiCfgCoord new_coord(){ return new GuiCfgCoord(); }
    218
    219    public void add_coord(GuiCfgCoord value){ coords.add(value); }
    220  }
    221
    222
    223  /**ZBNF: |<?coord> <#f?x>, <#f?y>
    224   */
    225  public final static class GuiCfgCoord
    226  {
    227    public float x,y;
    228  }
    229
    230
    231  /**ZBNF: Text::= ... ;
    232   * Class for instance to capture and store the Table data. */
    233  public final static class GuiCfgImage extends GuiCfgWidget implements Cloneable
    234  {
    235    public String size = "B";
    236
    237    String file_;
    238
    239    public GuiCfgImage(GralCfgElement itsElement){ super(itsElement, 'i'); }
    240
    241    public void set_file(String value){ file_ = value; }
    242  }
    243
    244
    245
    246  /**ZBNF: ShowField::= ... ;
    247   * Class for instance to capture and store the Table data. */
    248  public final static class GuiCfgShowField extends GuiCfgWidget implements Cloneable
    249  {
    250
    251    public GuiCfgShowField(GralCfgElement itsElement){ super(itsElement, 'S'); }
    252  }
    253
    254
    255  /**ZBNF: ShowField::= ... ;
    256   * Class for instance to capture and store the Table data. */
    257  public final static class GuiCfgInputFile extends GuiCfgWidget implements Cloneable
    258  {
    259
    260    public GuiCfgInputFile(GralCfgElement itsElement){ super(itsElement, 'F'); }
    261  }
    262
    263
    264  /**ZBNF: Button::= ... ;
    265   * Class for instance to capture and store the Button data. */
    266  public final static class GuiCfgButton extends GuiCfgWidget implements Cloneable
    267  {
    268    final boolean bSwitch;
    269    public GuiCfgButton(GralCfgElement itsElement){ super(itsElement, 'B'); bSwitch = false; }
    270    public GuiCfgButton(GralCfgElement itsElement, boolean bSwitch){ super(itsElement, 'B'); this.bSwitch = bSwitch; }
    271  }
    272
    273
    274
    275  /**ZBNF: Table::= ... ;
    276   * Class for instance to capture and store the Table data. */
    277  public final static class GuiCfgTable extends GuiCfgWidget implements Cloneable
    278  {
    279
    280    public GuiCfgTable(GralCfgElement itsElement){ super(itsElement, 'l'); }
    281
    282    public int height;
    283
    284    private final List<Integer> columnWidths = new LinkedList<Integer>();
    285
    286    public void set_columnWidth(int val){ columnWidths.add(val); }
    287
    288    public void set_text(String value){ super.text = value; }
    289
    290    public List<Integer> getColumnWidths(){ return columnWidths; }
    291  }
    292
    293
    294  /**ZBNF: Table::= ... ;
    295   * Class for instance to capture and store the Table data. */
    296  public final static class GuiCfgCurveview extends GuiCfgWidget implements Cloneable
    297  {
    298    public int nrofPoints;
    299
    300    public boolean activate;
    301
    302    List<GuiCfgCurveLine> lines = new LinkedList<GuiCfgCurveLine>();
    303
    304    /**The element is created if the text if {@link #set_line(String)} is invoked
    305     * before {@link #newGuiElement} is invoked. The association is temporary valid for the current element. */
    306    private GuiCfgCurveLine newLine;
    307
    308
    309    public GuiCfgCurveview(GralCfgElement itsElement){ super(itsElement, 'c'); }
    310
    311
    312    /**ZBNF: DataReplace: CurveView::= .... <?line> */
    313    public GuiCfgCurveLine new_line()
    314    {
    315      if(newLine == null){ newLine = new GuiCfgCurveLine(null); }
    316      return newLine;
    317    }
    318
    319    /**ZBNF: DataReplace: < Element> */
    320    public void set_Element(String val)
    321    {
    322      if(newLine == null){ newLine = new GuiCfgCurveLine(null); }
    323      newLine.content = val;
    324      //NOTE: the newGuiElement will be returned to fill in in new_Element()
    325    }
    326
    327
    328
    329    /**From ZBNF: DataReplace: < DataReplace> */
    330    public void add_line(GuiCfgCurveLine value)
    331    { lines.add(value);
    332      newLine = null;
    333    }
    334
    335
    336  }
    337
    338
    339  /**ZBNF: {<?line> ... ;
    340   * Class for instance to capture and store the Table data. */
    341  public final static class GuiCfgCurveLine extends GuiCfgWidget implements Cloneable
    342  {
    343    String content;
    344
    345    public GuiCfgCurveLine(GralCfgElement itsElement){ super(itsElement, 'C'); }
    346
    347    public int colorValue = 0;
    348    public float offset, scale;
    349    public int nullLine;
    350  }
    351
    352
    353  public final static class GuiCfgColor
    354  {
    355    public String color;
    356  }
    357
    358
    359  final List<String> cfgConditions;
    360
    361
    362  GralCfgElement firstElement = null;
    363
    364  private GralCfgElement actualElement = null;
    365
    366  private Conditional actualConditional;
    367
    368  /**ZBNF: DataReplace::= <$?key> = <$-/\.?string> ;
    369   * Temporary instance to capture key and string. */
    370  private final DataReplace dataReplaceTempInstance = new DataReplace();
    371
    372
    373  /**The element is created if the text if {@link #set_Element(String)} is invoked
    374   * before {@link #newGuiElement} is invoked. The association is temporary valid for the current element. */
    375  private GralCfgElement newGuiElement;
    376
    377  /**Map of replacements of paths to data. Filled from ZBNF: DataReplace::= <$?key> = <$-/\.?string> */
    378  public final Map<String, String> dataReplace = new TreeMap<String,String>();
    379
    380  Map<String, GuiCfgWidget> idxTypes = new TreeMap <String, GuiCfgWidget>();
    381
    382
    383  /**TODO widgets sorted to panels and tabs!
    384   *
    385   */
    386  final List<GralCfgElement> listElementsInTextfileOrder = new ArrayList<GralCfgElement>();
    387
    388  GralCfgPanel actPanel;
    389
    390  /**Map of replacements of paths to data. Filled from ZBNF: DataReplace::= <$?key> = <$-/\.?string> */
    391  private final Map<String, GralCfgPanel> idxPanels = new TreeMap<String,GralCfgPanel>();
    392
    393
    394  public GralCfgData(List<String> conditions)
    395  {
    396    this.cfgConditions = conditions;
    397  }
    398
    399
    400  public Set<Map.Entry<String, GralCfgPanel>> getPanels(){return idxPanels.entrySet(); }
    401
    402  /**ZBNF: size( <#?ySize> , <#?xSize> ) */
    403  public void set_ySize(int value)
    404  {
    405
    406  }
    407
    408  /**ZBNF: size( <#?ySize> , <#?xSize> ) */
    409  public void set_xSize(int value)
    410  {
    411
    412  }
    413
    414
    415  /**From ZBNF: DataReplace: < DataReplace> */
    416  public DataReplace new_DataReplace(){ return dataReplaceTempInstance; }
    417
    418  /**From ZBNF: DataReplace: < DataReplace> */
    419  public void set_DataReplace(DataReplace value)
    420  { dataReplace.put(value.key, value.string);
    421  }
    422
    423
    424
    425
    426
    427  /**ZBNF: DataReplace: < ?Element >[ | | ] */
    428  public GralCfgData new_Conditional()
    429  { Conditional conditional = new Conditional(this, actualConditional);
    430    actualConditional = conditional;
    431    return this;
    432  }
    433
    434
    435  /**ZBNF: DataReplace: < ?Element >[ | | ] */
    436  public GralCfgData new_ElseConditional()
    437  { Conditional conditional = new Conditional(this, actualConditional);
    438    actualConditional = conditional;
    439    return this;
    440  }
    441
    442
    443  /**It is called on end of conditional block.
    444   * @param val
    445   */
    446  public void add_Conditional(GralCfgData val){
    447    actualConditional = actualConditional.parentLevel;
    448  }
    449
    450
    451  public void set_ifCondition(String cond){
    452
    453    actualConditional.condition = cfgConditions.contains(cond);
    454  }
    455
    456
    457  public void set_elseCondition(){
    458
    459    actualConditional.condition = !actualConditional.condition;
    460  }
    461
    462
    463
    464  public GralCfgPanel new_Window()
    465  { GralCfgPanel panel = new GralCfgPanel();
    466    panel.widgetType = new GuiCfgWidget(panel, 'w');
    467    return panel;
    468  }
    469
    470  public void add_Window(GralCfgPanel panel)
    471  {
    472    idxPanels.put(panel.name, panel);
    473    listElementsInTextfileOrder.add(panel);  //list of elements in text file
    474
    475  }
    476
    477
    478  /**ZBNF: DataReplace: < ?Element >[ | | ] */
    479  public GralCfgElement new_Element()
    480  {
    481    if(newGuiElement == null){ newGuiElement = new GralCfgElement(); }
    482    //
    483    if(actualConditional ==null || actualConditional.condition){
    484      if(firstElement ==null){
    485        firstElement = newGuiElement;
    486      }
    487      //GralCfgElement actual1 = actualConditional == null ? actualElement : actualConditional.actualElement;
    488      if(actualElement !=null){
    489        actualElement.next = newGuiElement;
    490      }
    491      newGuiElement.previous = actualElement;  //may be null
    492      actualElement = newGuiElement;
    493    }
    494    return newGuiElement;
    495  }
    496
    497
    498  /**From ZBNF: DataReplace: < DataReplace> */
    499  public void add_Element(GralCfgElement value)
    500  {
    501    if(actualConditional ==null || actualConditional.condition){
    502      String sPanel = value.positionInput.panel;
    503      if(value.widgetType != null && value.widgetType.text !=null && value.widgetType.text.equals("wd:yCos"))
    504        stop();
    505      if(sPanel == null){ //the last panel is used furthermore.
    506        if(actPanel == null){
    507          actPanel = new GralCfgPanel("$");
    508        }
    509        sPanel = actPanel.name;
    510        value.setPanel(sPanel);
    511      } else { //a panel is given.
    512        actPanel = idxPanels.get(sPanel);
    513        if(actPanel == null){ //first time use that:
    514          actPanel = new GralCfgPanel(sPanel);
    515          idxPanels.put(sPanel, actPanel);
    516        }
    517      }
    518      actPanel.listElements.add(value);      //list of elements in panels
    519      listElementsInTextfileOrder.add(value);  //list of elements in text file
    520    }
    521    newGuiElement = null;
    522  }
    523
    524
    525
    526
    527  /**ZBNF: DataReplace: < Element> */
    528  public void set_Element(String val)
    529  {
    530    if(newGuiElement == null){ newGuiElement = new GralCfgElement(); }
    531    newGuiElement.content = val;
    532    //NOTE: the newGuiElement will be returned to fill in in new_Element()
    533  }
    534
    535  /**ZBNF: Type::= typeName ( param ); */
    536  public GralCfgData.GuiCfgType new_Type()
    537  { GralCfgData.GuiCfgType widgt = new GralCfgData.GuiCfgType();
    538    return widgt;
    539  }
    540
    541
    542  /**ZBNF: Type::= typeName ( param ); */
    543  public void add_Type(GralCfgData.GuiCfgType data){
    544    idxTypes.put(data.typeName, data);
    545  }
    546
    547
    548
    549
    550
    551
    552  void XXXprocessConfiguration(final GralMngBuild_ifc panel)
    553  {
    554
    555  }
    556
    557
    558  public String XXXreplacePathPrefix(String path, String[] target)
    559  {
    560    String pathRet = path;
    561    int posSep = path.indexOf(':');
    562    if(posSep >=0){
    563      String sRepl = dataReplace.get(path.substring(0, posSep));
    564      if(sRepl !=null){
    565        pathRet = sRepl + path.substring(posSep+1);  //Note: sRepl may contain a ':', its the device.
    566      }
    567      posSep = pathRet.indexOf(':');  //after replace or if it isn't replaced
    568      if(posSep >=0){
    569        target[0] = pathRet.substring(0, posSep);
    570        pathRet = pathRet.substring(posSep+1);
    571      }
    572    }
    573    return pathRet;
    574  }
    575
    576
    577  void stop(){}
    578}