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}