001package org.vishia.gral.widget;
002
003import java.io.IOException;
004
005import org.vishia.byteData.VariableContainer_ifc;
006import org.vishia.gral.base.GralButton;
007import org.vishia.gral.base.GralHtmlBox;
008import org.vishia.gral.base.GralMng;
009import org.vishia.gral.base.GralPos;
010import org.vishia.gral.base.GralTextField;
011import org.vishia.gral.base.GralWidget;
012import org.vishia.gral.base.GralWindow;
013import org.vishia.gral.base.GralTextBox;
014import org.vishia.gral.base.GralWindow_setifc;
015import org.vishia.gral.ifc.GralColor;
016import org.vishia.gral.ifc.GralFont;
017import org.vishia.gral.ifc.GralMngBuild_ifc;
018import org.vishia.gral.ifc.GralRectangle;
019import org.vishia.gral.ifc.GralUserAction;
020import org.vishia.gral.ifc.GralWidget_ifc;
021import org.vishia.gral.ifc.GralWindow_getifc;
022import org.vishia.gral.ifc.GralTextBox_ifc;
023import org.vishia.gral.ifc.GralWindow_ifc;
024import org.vishia.util.KeyCode;
025
026/**This class presents a sub window which is used as info box for any messages.
027 * A Text info box and a html info box is supported. The html info box is used especially for help.
028 * The HTML text is navigable with internal links, maybe with external too.
029 * The HTML text 
030 * @author Hartmut Schorrig
031 *
032 */
033public final class GralInfoBox implements GralTextBox_ifc, GralWindow_setifc, GralWindow_getifc
034{
035
036  /**Version, history and license.
037   * <ul>
038   * <li>2013-03-24 Hartmut chg: {@link #createHtmlInfoBox(GralMngBuild_ifc, String, String, boolean)}
039   *   with Parameter onTop: Especially a help window should able to stay on top.
040   * <li>2011-10-00 Hartmut created
041   * </ul>
042   * 
043   * <b>Copyright/Copyleft</b>:<br>
044   * For this source the LGPL Lesser General Public License,
045   * published by the Free Software Foundation is valid.
046   * It means:
047   * <ol>
048   * <li> You can use this source without any restriction for any desired purpose.
049   * <li> You can redistribute copies of this source to everybody.
050   * <li> Every user of this source, also the user of redistribute copies
051   *    with or without payment, must accept this license for further using.
052   * <li> But the LPGL is not appropriate for a whole software product,
053   *    if this source is only a part of them. It means, the user
054   *    must publish this part of source,
055   *    but doesn't need to publish the whole source of the own product.
056   * <li> You can study and modify (improve) this source
057   *    for own using or for redistribution, but you have to license the
058   *    modified sources likewise under this LGPL Lesser General Public License.
059   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
060   * </ol>
061   * If you intent to use this source without publishing its usage, you can get
062   * a second license subscribing a special contract with the author. 
063   * 
064   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
065   */
066  public static final int version = 20130324;
067
068  /**The window is created invoking the {@link GralMngBuild_ifc#createWindow(String, boolean)}. 
069   * It has its implementation in the underlying graphic system.  */
070  private final GralWindow window;
071  
072  
073  /**The widget which holds the text in the {@link #window}. */
074  private final GralTextBox textBox;
075  
076  private final GralHtmlBox htmlBox;
077  
078  private final GralWidget buttonOk;
079  
080  private GralButton buttonLock;
081  
082  
083  protected final GralTextField infoLine;
084  
085  private GralUserAction actionOk;
086  
087  public GralInfoBox(GralWindow window, GralTextBox textBox, GralTextField infoLine, GralWidget buttonOk)
088  {
089    this.window = window;
090    this.textBox = textBox;
091    this.htmlBox = null;
092    this.infoLine = infoLine;
093    this.buttonOk = buttonOk;
094  }
095  
096  public GralInfoBox(GralWindow window, GralHtmlBox htmlBox, GralTextField infoLine, GralWidget buttonOk)
097  {
098    this.window = window;
099    this.textBox = null;
100    this.htmlBox = htmlBox;
101    this.infoLine = infoLine;
102    this.buttonOk = buttonOk;
103  }
104  
105  public static GralInfoBox createTextInfoBox(GralMngBuild_ifc mng, String name, String title)
106  {
107    GralWindow window = mng.createWindow(name, title, GralWindow_ifc.windConcurrently);
108    //TODO the position frame (size) regards the title bar, it should not do so!
109    mng.setPosition(0, -3, 0, 0, 0, '.');
110    GralTextBox text = mng.addTextBox(name, false, null, '.');
111    mng.setPosition(0, -4, -4, -2, 0, '.');
112    GralTextField infoLine = mng.addTextField("info", false, null, null);
113    mng.setPosition(-3, 0, -6, 0, 0, '.');
114    GralWidget buttonOk = mng.addButton(name + "-Info-ok", null, "OK");
115    mng.setPosition(-3, 0, -16, -10, 0, '.');
116    GralWidget buttonClear = mng.addButton(name + "-Info-clear", null, "clear");
117    GralInfoBox box = new GralInfoBox(window, text, infoLine, buttonOk);
118    box.buttonOk.setActionChange(box.actionOkButton);
119    buttonClear.specifyActionChange("Info clear", box.actionClear, null);
120    return box; 
121  }
122  
123  
124  @Override public void setToPanel(GralMngBuild_ifc mng){
125    throw new IllegalArgumentException("TODO, new concept is not implemented yet.");
126  }
127
128
129  @Override public void createImplWidget_Gthread(){
130    throw new IllegalArgumentException("TODO, new concept is not implemented yet.");
131  }
132
133
134  
135  /**Creates a sub window for showing html content.
136   * This routine should only be called in the graphical thread. TODO setToPanel in extra routine! 
137   * Then it is able to create in any thread.
138   * @param posString
139   * @param name
140   * @param title
141   * @param onTop
142   * @return
143   */
144  public static GralInfoBox createHtmlInfoBox(String posString, String name, String title, boolean onTop)
145  {
146    int props = GralWindow_ifc.windConcurrently | GralWindow_ifc.windResizeable;
147    if(onTop){ props |= GralWindow_ifc.windOnTop; }
148    GralWindow window = new GralWindow(posString, name, title, props); //mng.createWindow(name, title, props);
149    GralMng mng = GralMng.get();
150    window.setToPanel(mng);
151    //TODO the position frame (size) regards the title bar, it should not do so!
152    mng.setPosition(0, -3, 0, 0, 0, '.');
153    GralHtmlBox text = new GralHtmlBox(name); //     mng.addHtmlBox(name);
154    text.setToPanel(mng);
155    mng.setPosition(-2.5f, -0.5f, 0, -14, 0, '.');
156    GralTextField infoLine = mng.addTextField("info", false, null, null);
157    mng.setPosition(-3, GralPos.size+3, -13, GralPos.size+6, 0, 'r', 0.5f);
158    GralButton buttonLock = mng.addSwitchButton(name + "-Info-ok", "following", "locked", GralColor.getColor("wh"), GralColor.getColor("gn"));
159    mng.setPosition(-3, GralPos.size+3, -6, GralPos.size+6, 0, 'r', 0.5f);
160    GralWidget buttonOk = mng.addButton(name + "-Info-ok", null, "close");
161    GralInfoBox box = new GralInfoBox(window, text, infoLine, buttonOk);
162    box.buttonLock = buttonLock;
163    box.buttonOk.setActionChange(box.actionOkButton);
164    //mng.registerWidget(box);
165    return box; 
166
167  }
168  
169  public void setActionOk(GralUserAction action){ this.actionOk = action; }
170  
171  
172  public void activate(){
173    if(htmlBox !=null){ htmlBox.activate(); }
174  }
175  
176  @Override public String getName(){ return textBox !=null ? textBox.getName() : htmlBox.getName(); }
177  
178  @Override public void setCmd(String cmd){ if(textBox !=null) textBox.setCmd(cmd); else htmlBox.setCmd(cmd); }
179    
180  @Override public String getCmd(){ return textBox !=null ? textBox.getCmd() : htmlBox.getCmd(); }
181    
182
183  
184  @Override public String getDataPath(){ return textBox !=null ? textBox.getDataPath() : htmlBox.getDataPath(); }
185  
186  @Override public ActionChange getActionChange(ActionChangeWhen when){ return textBox !=null ? textBox.getActionChange(when) : htmlBox.getActionChange(when); }
187  
188
189  
190  
191  @Override public void setTextStyle(GralColor color, GralFont font)
192  { textBox.setTextStyle(color, font);
193  }
194
195  
196  @Override public void setEditable(boolean editable){
197    textBox.setEditable(editable);
198  }
199
200
201  
202  @Override public Appendable append(CharSequence text) throws IOException{ return textBox.append(text); }
203
204  @Override
205  public int getNrofLines()
206  {
207    // TODO Auto-generated method stub
208    return 0;
209  }
210
211  @Override public void setText(CharSequence text)
212  { textBox.setText(text);
213  }
214  
215  @Override public void setText(CharSequence text, int caretPos)
216  { textBox.setText(text, caretPos);
217  }
218  
219  
220  @Override public int setCursorPos(int pos){
221    if(textBox !=null){
222      return textBox.setCursorPos(pos);
223    } else {
224      return 0;
225    }
226  }
227
228
229  
230  //@Override public void setSelection(String how){ textBox.setSelection(how); }
231  
232  
233  public void setUrl(String url){
234    if(buttonLock == null || !buttonLock.isOn()){
235      infoLine.setText(url);
236      if(htmlBox !=null){ 
237        htmlBox.setUrl(url); 
238      }
239      else throw new IllegalArgumentException("it is not a html box.");
240    }
241  }
242  
243  
244  /**Query whether the table line is able to edit: Return from the whole table.
245   * @see org.vishia.gral.ifc.GralWidget_ifc#isEditable()
246   */
247  @Override public boolean isEditable(){ return textBox.isEditable(); }
248  
249  @Override public boolean isNotEditableOrShouldInitialize(){ return textBox.isNotEditableOrShouldInitialize(); }
250  
251
252  @Override public boolean isGraphicDisposed(){ return textBox !=null ? textBox.isGraphicDisposed() : htmlBox !=null ? htmlBox.isGraphicDisposed() : true; }
253  
254
255  @Override public boolean isChanged(boolean setUnchanged){ return textBox.isChanged(setUnchanged); }
256  
257  @Override public String getText(){ return textBox.getText(); }
258  
259  
260  @Override public boolean isVisible(){ return textBox.isVisible(); }
261  
262  @Override public int getCursorPos(){ return textBox.getCursorPos(); }
263
264  @Override public long setContentIdent(long date){ return textBox.setContentIdent(date); }
265  
266  @Override public long getContentIdent(){ return textBox.getContentIdent(); }
267
268
269
270  
271  
272
273  @Override public void repaint(){ repaint(0,0); }
274
275  @Override public void repaint(int delay, int latest){
276    window.repaint(delay, latest);
277  }
278  
279  
280
281  
282  @Override
283  public void viewTrail()
284  {
285    // TODO Auto-generated method stub
286    
287  }
288
289  //@Override public Object[] getWidgetMultiImplementations(){ return implWidgets; }
290  
291  
292  @Override
293  public GralColor setBackgroundColor(GralColor color)
294  {
295    // TODO Auto-generated method stub
296    return null;
297  }
298
299  @Override public void setFocus()
300  { if(textBox !=null){ textBox.setFocus(); }
301    else if(htmlBox !=null){ htmlBox.setFocus();}
302  }
303
304  @Override public void setFocus(int delay, int latest)
305  { if(textBox !=null){ textBox.setFocus(delay, latest); }
306    else if(htmlBox !=null){ htmlBox.setFocus(delay, latest);}
307  }
308  
309  
310  @Override public boolean isInFocus()
311  { if(textBox !=null){ return textBox.isInFocus(); }
312    else if(htmlBox !=null){ return htmlBox.isInFocus();}
313    else return false;
314  }
315  
316  
317  
318
319  @Override public void setFullScreen(boolean full){ window.setFullScreen(full); }
320
321  
322  @Override
323  public GralColor setForegroundColor(GralColor color)
324  {
325    // TODO Auto-generated method stub
326    return null;
327  }
328
329
330
331  @Override
332  public boolean isWindowsVisible()
333  {
334    // TODO Auto-generated method stub
335    return false;
336  }
337
338
339
340  @Override
341  public void setWindowVisible(boolean visible)
342  {
343    window.setWindowVisible(visible);
344    // TODO Auto-generated method stub
345    
346  }
347
348  @Override
349  public Appendable append(char arg0) throws IOException
350  {
351    // TODO Auto-generated method stub
352    return null;
353  }
354
355  @Override
356  public Appendable append(CharSequence arg0, int arg1, int arg2)
357      throws IOException
358  {
359    // TODO Auto-generated method stub
360    return null;
361  }
362  
363  
364
365  
366  GralUserAction actionOkButton = new GralUserAction("actionOkButton"){
367    @Override public boolean userActionGui(int actionCode, GralWidget widgd, Object... params) {
368      //if(textBox !=null) {textBox.setText(""); }  //'I have seen it, therefore delete.
369      if(actionOk !=null){ actionOk.exec(KeyCode.enter, widgd); }
370      window.setWindowVisible(false);
371      return true;
372    }
373  };
374
375  GralUserAction actionClear = new GralUserAction("actionClear"){
376    @Override public boolean exec(int actionCode, GralWidget_ifc widgd, Object... params) {
377      if(textBox !=null) {textBox.setText(""); }  //'I have seen it, therefore delete.
378      return true;
379    }
380  };
381
382  @Override public void setBoundsPixel(int x, int y, int dx, int dy)
383  { window.setBoundsPixel(x,y,dx,dy);
384  }
385  
386  
387
388  
389  @Override public GralRectangle getPixelPositionSize(){ return window.getPixelPositionSize(); }
390    
391  @Override public void closeWindow()
392  { 
393    window.closeWindow();
394  }
395
396  @Override
397  public boolean remove()
398  {
399    // TODO Auto-generated method stub
400    return false;
401  }
402
403  @Override
404  public void setHtmlHelp(String url)
405  {
406    if(textBox !=null){ textBox.setHtmlHelp(url); }
407    if(htmlBox !=null){ htmlBox.setHtmlHelp(url); }
408    infoLine.setText(url);
409    //buttonOk.setHtmlHelp(url);
410  }
411
412  
413  @Override public boolean setVisible(boolean visible){
414    if(textBox !=null){ return textBox.setVisible(visible); }
415    if(htmlBox !=null){ return htmlBox.setVisible(visible); }
416    else return false;
417    
418  }
419
420  @Override public void refreshFromVariable(VariableContainer_ifc container){
421    if(textBox !=null){ textBox.refreshFromVariable(container); }
422    if(htmlBox !=null){ htmlBox.refreshFromVariable(container); }
423    
424  }
425  
426  
427  @Override public void refreshFromVariable(VariableContainer_ifc container, long timeAtleast, GralColor colorRefreshed, GralColor colorOld){
428    if(textBox !=null){ textBox.refreshFromVariable(container, timeAtleast, colorRefreshed, colorOld); }
429    if(htmlBox !=null){ htmlBox.refreshFromVariable(container, timeAtleast, colorRefreshed, colorOld); }
430  }
431
432
433  @Override public void setDataPath(String sDataPath)
434  { 
435    if(textBox !=null){ textBox.setDataPath(sDataPath); }
436    if(htmlBox !=null){ htmlBox.setDataPath(sDataPath); }
437  }
438
439  @Override public void setBackColor(GralColor color, int ix)
440  { 
441    if(textBox !=null){ textBox.setBackColor(color, ix); }
442    if(htmlBox !=null){ htmlBox.setBackColor(color, ix); }
443  }
444
445  @Override public GralColor getBackColor(int ix)
446  { 
447    if(textBox !=null){ return textBox.getBackColor(ix); }
448    if(htmlBox !=null){ return htmlBox.getBackColor(ix); }
449    else return null;
450  }
451
452  @Override public void setLineColor(GralColor color, int ix)
453  { 
454    if(textBox !=null){ textBox.setLineColor(color, ix); }
455    if(htmlBox !=null){ htmlBox.setLineColor(color, ix); }
456  }
457
458  @Override public void setTextColor(GralColor color)
459  { 
460    if(textBox !=null){ textBox.setTextColor(color); }
461    if(htmlBox !=null){ htmlBox.setTextColor(color); }
462  }
463
464  @Override public Object getContentInfo(){ return null; }
465  
466  
467  @Override public GralMng gralMng(){ return window.gralMng(); }
468
469  @Override public void setData(Object data)
470  {
471    // TODO Auto-generated method stub
472    
473  }
474
475  @Override public Object getData()
476  {
477    // TODO Auto-generated method stub
478    return null;
479  }
480}