001package org.vishia.gral.ifc;
002
003import java.io.File;
004import java.util.List;
005import java.util.Map;
006import java.util.TreeMap;
007
008import javax.script.ScriptException;
009
010import org.vishia.cmd.JZtxtcmdExecuter;
011import org.vishia.cmd.JZtxtcmdScript;
012import org.vishia.cmd.JZtxtcmdThreadQueue;
013import org.vishia.gral.base.GralMng;
014import org.vishia.mainCmd.MainCmdLogging_ifc;
015import org.vishia.util.DataAccess;
016
017/**This class should be instantiated by a JZtxtcmd script.
018 * It is the common container for all actions which are deployed by sub routines of jzcmd.
019 * To add an action invoke in JZtxtcmd:<pre>
020 * Obj gralActions = java new org.vishia.gral.ifc.GralActionJztc(jztc, out);
021 * gralActions.add(jztc.sub("buttonConvert"));
022 * ....
023 * sub buttonConvert(){
024 *   .....do something with graphical content or other
025 * }  
026 * </pre>
027 * @author hartmut Schorrig
028 *
029 */
030public class GralActionJztc
031{
032  
033  /**The version, history and license.
034   * <ul>
035   * <li>2018-09-17 created
036   * </ul>
037   * 
038   * <b>Copyright/Copyleft</b>:
039   * For this source the LGPL Lesser General Public License,
040   * published by the Free Software Foundation is valid.
041   * It means:
042   * <ol>
043   * <li> You can use this source without any restriction for any desired purpose.
044   * <li> You can redistribute copies of this source to everybody.
045   * <li> Every user of this source, also the user of redistribute copies
046   *    with or without payment, must accept this license for further using.
047   * <li> But the LPGL is not appropriate for a whole software product,
048   *    if this source is only a part of them. It means, the user
049   *    must publish this part of source,
050   *    but don't need to publish the whole source of the own product.
051   * <li> You can study and modify (improve) this source
052   *    for own using or for redistribution, but you have to license the
053   *    modified sources likewise under this LGPL Lesser General Public License.
054   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
055   * </ol>
056   * If you are intent to use this sources without publishing its usage, you can get
057   * a second license subscribing a special contract with the author. 
058   * 
059   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
060   * 
061   * 
062   */
063  public final static String version = "2018-09-17";
064
065
066  
067  private class Action extends GralUserAction {
068
069    JZtxtcmdScript.Subroutine jzsub;
070
071    Action(JZtxtcmdScript.Subroutine jzsub){
072      super(jzsub.name);
073      this.jzsub = jzsub;
074    }
075    
076    @Override public boolean exec(int key, GralWidget_ifc widgd, Object... params) {
077      thread.add(jzsub);
078      return true;
079    }
080    
081  }
082  
083  
084  private class ActionRereadScript extends GralUserAction {
085
086
087    public ActionRereadScript()
088    { super("GralActionJztc-reread script");
089      GralMng.get().registerUserAction("GralActionJztc_reread", this);
090    }
091    
092    @Override public boolean exec(int key, GralWidget_ifc widgd, Object... params) {
093      if(scriptFile !=null) {
094        GralActionJztc.this.setScript(scriptFile);
095      }
096      return true;
097    }
098    
099  }
100  
101
102  
103  
104  
105  Map<String, Action> actions = new TreeMap<String, Action>();
106  
107  
108  
109  /**The java prepared script which contains subroutines. */
110  JZtxtcmdScript jzcmdScript;
111
112  File scriptFile;
113  
114  final JZtxtcmdThreadQueue thread;
115  
116  //final JZtxtcmdExecuter cmdExecuter;
117
118  final Appendable out;
119  
120  final MainCmdLogging_ifc log;
121  
122  /**Constructs and stores JZtxtcmd aggregation.
123   * @param jztc The main data to access script level
124   * @param out Any output used in the sub routine.
125   */
126  public GralActionJztc(JZtxtcmdExecuter.JzTcMain jztc, Appendable out, MainCmdLogging_ifc log){
127    this.thread = new JZtxtcmdThreadQueue("jzTc-GUI", jztc);
128    //this.cmdExecuter = cmdExecuter;
129    this.out = out; this.log = log;
130  }
131  
132  
133  
134  public void setScript(File scriptfile) {
135    if(this.scriptFile == null) { //first invocation
136      new ActionRereadScript();   //registeres it.
137    }
138    this.scriptFile = scriptfile;
139    try{ 
140      jzcmdScript = JZtxtcmdScript.createScriptFromFile(scriptfile, log, null);
141      List<Object> listSubs = jzcmdScript.scriptClass().listClassesAndSubroutines();
142      for(Object e: listSubs) {
143        if(e instanceof JZtxtcmdScript.Subroutine) {
144          JZtxtcmdScript.Subroutine sub = (JZtxtcmdScript.Subroutine)e;
145          if(sub.formalArgs !=null && sub.formalArgs.size()==1) {
146            DataAccess arg = sub.formalArgs.get(0).defVariable;   //has a defVariable always.
147            if(arg.datapath().get(0).ident().equals("widget")) {  //datapath only simple, 'widget' aus key
148              //subroutine to register
149              add(sub);  //adds or replaces
150            }
151          }
152        }
153      }
154    } catch (ScriptException exc) {
155      log.writeError("Error GralUserAction.setScript", exc);
156    }
157  }
158  
159  
160  
161  
162  /**Adds a JZtxtcmd-subroutine as execution of a {@link GralUserAction}.
163   * to the registered actions, able to get with {@link GralMng#getRegisteredUserAction(String)}
164   * The name of the action is the name of the sub routine.
165   * The user is responsible to unique names in the graphic application.
166   * @param jzsub
167   */
168  public void add(JZtxtcmdScript.Subroutine jzsub) {
169    String name = jzsub.name;
170    Action action = actions.get(name);
171    if(action != null) {
172      action.jzsub = jzsub;      //replace action on reread script.
173    } else {
174      action = new Action(jzsub);
175      actions.put(name, action);
176      GralMng.get().registerUserAction(jzsub.name, action);
177    }
178  }
179  
180  
181}