001package org.vishia.commander;
002
003import java.util.EventObject;
004import java.util.LinkedList;
005import java.util.List;
006
007import org.vishia.event.EventConsumer;
008import org.vishia.event.EventSource;
009import org.vishia.fileRemote.FileMark;
010import org.vishia.fileRemote.FileRemote;
011import org.vishia.fileRemote.FileRemoteCallback;
012import org.vishia.fileRemote.FileRemoteProgressTimeOrder;
013import org.vishia.gral.base.GralButton;
014import org.vishia.gral.base.GralPos;
015import org.vishia.gral.base.GralTextField;
016import org.vishia.gral.base.GralValueBar;
017import org.vishia.gral.base.GralWidget;
018import org.vishia.gral.base.GralWindow;
019import org.vishia.gral.ifc.GralColor;
020import org.vishia.gral.ifc.GralTextField_ifc;
021import org.vishia.gral.ifc.GralUserAction;
022import org.vishia.gral.ifc.GralWidget_ifc;
023import org.vishia.gral.ifc.GralWindow_ifc;
024import org.vishia.util.Debugutil;
025import org.vishia.util.FileSystem;
026import org.vishia.util.KeyCode;
027import org.vishia.util.SortedTreeWalkerCallback;
028import org.vishia.util.StringFormatter;
029import org.vishia.util.StringFunctions;
030
031
032/**Base class for initializing some class variables before the variables with only code in the class body are executed. */
033class FcmdFileActionBase {
034
035  /**The command which is given with that window. */
036  final FcmdCopyCmprDel.Ecmd cmdWind;
037  
038  final String helpPrefix;
039  
040  FcmdFileActionBase(FcmdCopyCmprDel.Ecmd whatisit){
041    cmdWind = whatisit;
042    switch(whatisit){
043      case compare: helpPrefix = "cmpr"; break;
044      case copy: helpPrefix = "copy"; break;
045      case delete: helpPrefix = "del"; break;
046      default: throw new IllegalArgumentException("internal");
047    }
048  }
049}
050
051
052/**This class contains all functionality to execute copy, move, compare and delete for The.file.Commander.
053 * The same class is used for three instances with a different view. See constructor-argument.
054 * 
055 * 
056 * @author Hartmut Schorrig
057 *
058 */
059public final class FcmdCopyCmprDel extends FcmdFileActionBase
060{
061  /**Version and History
062   * <ul>
063   * <li>2015-01-03 Hartmut refactory
064   * <li>2013-02-03 Hartmut chg: set the destination only if it is not set on button setSrc
065   * <li>2013-02-03 Hartmut chg: {@link #execMove()} with files
066   * <li>2013-02-03 Hartmut new: Copy exception (on file open to write) cases a message, the key {@link #widgOverwrFile}
067   *   works together with the Ask state.
068   * <li>2012-11-16 Hartmut chg: Copy: The {@link #filesToCopy} will be filled after callback of check. The files which are used
069   *   are read only from the input fields of the GUI. The user can change it.
070   * <li>2012-02-26 Hartmut chg: Strategy for button texts and abort behavior improved. Problem was: 
071   *   The 'check' phase needs some calculation time for a slow network connection. 
072   * <li>2012-02-04 Hartmut new: If a file was copied and a comparison result exists, it is set to equal.
073   *   That helps to handle with comparison.
074   * </ul>
075   */
076  public static final int version = 0x20120204; 
077  
078  
079  String sTextExecuteForFile = (cmdWind == Ecmd.delete) ? "del file" : "overwr file";
080  
081  protected final Fcmd main;
082
083  GralWindow windConfirmCopy;
084  
085  GralPos posWindConfirmCopy;
086  
087  //GralWidget widgdCopyFrom, widgdCopyTo;
088  
089  GralTextField widgShowSrc, widgFromConditions;
090  
091  GralButton widgButtonModeDst;
092  
093  GralTextField widgInputDst, widgCopyState;
094  
095  GralTextField widgCopyDirDst, widgCopyNameDst;  //TODO with progress
096  
097  GralButton widgdChoiceCreateNew, widgdChoiceOverwrExists, widgdChoiceOverwrReadOnly;
098  
099  GralButton widgOverwrFile, widgSkipFile, widgSkipDir, widgBtnPause;
100  
101  
102  GralButton widgState, widgButtonSetSrc, widgButtonSetDst, widgButtonCheck, widgButtonMove, widgButtonOk;
103
104  GralButton widgButtonClearSel, widgButtonShowSrc, widgButtonShowDst, widgButtonShowResult;
105  
106  GralValueBar widgProgressFile;
107  GralValueBar widgProgressAll;
108  
109  GralButton widgButtonEsc;
110
111  GralColor colorNoChangedText = GralColor.getColor("am");
112  
113  GralColor colorChangedText = GralColor.getColor("wh");
114  
115  GralColor colorGrayed = GralColor.getColor("gr");
116  
117  /**Mode overwrite readonly. '?'-ask, y-overwrite n-skip, don't ask
118   */
119  int modeOverwrReadonly = FileRemote.modeCopyReadOnlyAks;
120  
121  /**Mode overwrite with timestamp. 'w'-newer, o-older, n-never, ?-ask. */
122  int modeOverwrDate = FileRemote.modeCopyExistAsk;
123  
124  /**Mode create new file while copying. 'n'-no, y-yes, a-ask. */
125  int modeCreateCopy = FileRemote.modeCopyCreateYes;
126  
127  /**The file card where the directory content is shown where the files will be copied to, the destination. */
128  FcmdFileCard fileCardSrc, fileCardDst;
129  
130  /**The source file to copy. It is set in the {@link #actionConfirmCopy()}. Either dirSrc == fileSrc 
131   * and the {@link #sFilesSrc} contains some file names, or dirSrc is the directory of fileSrc, fileSrc is the only one
132   * file to copy (maybe a directory) and sFilesSrc is empty.
133   */
134  FileRemote srcDir, srcFile;
135  
136  boolean srcSomeFiles;
137  
138  /**If more as one files are selected to copy, the names are contained here separated with ' : '.
139   * Elsewhere it is "*". */
140  String sFilesSrc;
141  
142  /**The destination selected directory and file as destination for compare and move or second tree for comparison. 
143   * The fileDst is build with the name of the source file for copy and move and with the real dst file for compare
144   */
145  FileRemote fileDst, dirDst; //, dirDstCmpr;
146
147  /**Name of the file for dst. */
148  CharSequence sFileDstCopy;
149  
150  StringBuilder bufferDstChars = new StringBuilder(100);
151  
152  StringFormatter formatShow = new StringFormatter(100);
153  
154  /**If true then the {@link #widgInputDst} was changed for this session. Not automatically change the content. */
155  boolean bDstChanged;
156
157  boolean bFirstSelect;
158  
159  /**Content from the input fields while copy is pending. */
160  //String sDstDir, sDstName;
161  
162  long zBytes;
163  int zFiles;
164  
165  FileRemote fileProcessed, dirProcessed;
166  
167  
168  //List<String> listFileSrc;
169  
170  /**This list is filled with some callback Events for files which are checked before copying.
171   * If the callback of the check process occurs, the events will be removed from this list.
172   * Only events which are found in this list are considered to build the list of files to copy.
173   * This list is definitive cleared if the "abort" button is pressing. A current running check process
174   * cannot be aborted because it runs in another unknown thread. But the usage of the callback is prevented then.
175   */
176  final List<FileRemote.CallbackEvent> listEvCheck = new LinkedList<FileRemote.CallbackEvent>();
177  
178  int nrofFilesCheck;
179  
180  
181  /**State of the handling. */
182  protected Estate state = Estate.inactive;
183  
184  
185  /**Selected handling command. */
186  protected Ecmd cmd = Ecmd.copy;
187  
188  //protected boolean bLockSrc;
189  
190  /**If true then not all files are selected below the shown source directory.
191   * Then move and delete should work in fine steps. 
192   */
193  protected boolean bFineSelect;
194  
195  final List<FileRemote.CallbackEvent> listEvCopy = new LinkedList<FileRemote.CallbackEvent>();
196  
197  /**Current files which are in copy process. Typical contains one file only. 
198   * This list will be filled in {@link #actionConfirmCopy}.
199   * If the copy process is finished, this list will be empty.
200   */
201  final List<FileRemote> filesToCopy = new LinkedList<FileRemote>();
202  
203  /**Last files which are in copy process. Typical contains one file only. 
204   * This list will be filled in {@link #actionButtonCopy} if the copy process will be started.
205   * It is used in {@link #actionLastSrc} to fill the {@link #filesToCopy}.
206   * This list remains after copy process to supply "last files".
207   */
208  //final List<FileRemote> filesToCopyLast = new LinkedList<FileRemote>();
209  
210  
211  
212  EventSource evSrc = new EventSource("FcmdCopy-GUIaction");
213  
214
215  
216  
217  /**This reference is set with the callback of operation cmd. 
218   * The event can be used to affect the copying process.
219   */
220  FileRemote.CallbackEvent evCurrentFile;
221  
222  Actions action;
223  
224  FcmdCopyCmprDel(Fcmd main, Ecmd cmdArg)
225  { super(cmdArg);
226    this.main = main;
227  }
228  
229  
230  /**Last files which are in copy process. Typical contains one file only. 
231   * This list will be filled in {@link #actionButtonCopy} if the copy process will be started.
232   * It is used in {@link #actionLastSrc} to fill the {@link #filesToCopy}.
233   * This list remains after copy process to supply "last files".
234   */
235  //final List<FileRemote> filesToCopyLast = new LinkedList<FileRemote>();
236  
237  
238  
239  /**Builds the content of the confirm-copy window. The window is created static. It is shown
240   * whenever it is used.  */
241  void buildWindowConfirmCopy(String sTitle)
242  {
243    action = new Actions();
244    main._gralMng.selectPanel("primaryWindow"); //"output"); //position relative to the output panel
245    //System.out.println("CopyWindow frame: " + main.gralMng.pos.panel.getPixelPositionSize().toString());
246    //panelMng.setPosition(1, 30+GralGridPos.size, 1, 40+GralGridPos.size, 1, 'r');
247    main._gralMng.setPosition(10, GralPos.size+37, 10, GralPos.size+70, 1, 'r'); //right buttom, about half less display width and hight.
248    
249
250    posWindConfirmCopy = main._gralMng.getPositionInPanel();
251    int windprops = GralWindow.windConcurrently; // + GralWindow.windResizeable;
252    windConfirmCopy = main._gralMng.createWindow("copyWindow", sTitle, windprops);
253    //System.out.println(" window: " + main.gralMng.pos.panel.getPixelPositionSize().toString());
254    
255    //source path and check:
256    if(cmdWind != Ecmd.delete) {
257      main._gralMng.setPosition(0.5f, GralPos.size +2, 1, 7.5f, 0, 'r', 0);
258      widgButtonModeDst = main._gralMng.addSwitchButton(null, "dst/..", "dst/dst", GralColor.getColor("gn"), GralColor.getColor("ye") );
259      widgButtonModeDst.setActionChange(actionChgModeDst);
260    }
261    main._gralMng.setPosition(0.5f, GralPos.size +2.5f, 15, GralPos.size+12, 0, 'r', 1);
262    widgButtonSetSrc = main._gralMng.addButton(null, actionConfirmCopy, "setSrc", null, "set source" );
263    widgButtonSetSrc.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".setSrc.");
264    widgButtonClearSel = main._gralMng.addButton(null, null, "clrSel", null, "clear selection" );
265    widgButtonClearSel.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".clearSel.");
266    if(cmdWind != Ecmd.delete) {
267      main._gralMng.setPosition(GralPos.same, GralPos.samesize, -17, -1, 0, 'r', 1);
268      widgButtonSetDst = main._gralMng.addButton(null, actionSetDst, "setDst", null, "set destination" );
269      widgButtonSetDst.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".setDst.");
270    }
271    main._gralMng.setPosition(2.5f, GralPos.size +3.2f, 1, -4, 0, 'd', 0);
272    //main.gralMng.addText("source:", 0, GralColor.getColor("bk"), GralColor.getColor("lgr"));
273    widgShowSrc = main._gralMng.addTextField("copyFrom", false, "source root path", "t");
274    widgShowSrc.setBackColor(GralColor.getColor("am"),0);
275    widgShowSrc.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".pathSrc.");
276    main._gralMng.setPosition(GralPos.refer+0.9f, GralPos.size +2.5f, -4f, -1, 0, 'r', 1);
277    widgButtonShowSrc = main._gralMng.addButton(null, null, "showSrc", null, "=>" );
278    widgButtonShowSrc.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".show.");
279    
280    
281    main._gralMng.setPosition(GralPos.refer + 2.3f, GralPos.size +3.2f, 1, -13, 0, 'r', 0.3f);
282    widgFromConditions = main._gralMng.addTextField("copyCond",true, "select src files: mask* : *.ext ", "t");  /// 2012-08-05..06
283    widgFromConditions.setActionChange(actionSelectMask);
284    widgFromConditions.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".selcond.");
285    
286    main._gralMng.setPosition(GralPos.refer+0.2f, GralPos.size+3.5f, -13, -1, 0, 'd', 0);
287    widgButtonCheck = main._gralMng.addButton("buttonCheck", actionCheck, "check", null, "check" );
288    widgButtonCheck.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".check.");
289    
290    //dst path, set dst
291    if(cmdWind != Ecmd.delete) {
292      main._gralMng.setPosition(GralPos.refer+3.0f, GralPos.size -3.2f, 1, -4, 0, 'r', 0);
293      widgInputDst = main._gralMng.addTextField("copyDirDst", true, "destination:", "t");
294      widgInputDst.setActionChange(actionEnterTextInDst);
295      widgInputDst.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".setDst.");
296      main._gralMng.setPosition(GralPos.refer+0.9f, GralPos.size +2.5f, -4, -1, 0, 'r', 1);
297      widgButtonShowDst = main._gralMng.addButton(null, null, "showDst", null, "=>" );
298      widgButtonShowDst.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".show.");
299    }  
300    
301    main._gralMng.setPosition(GralPos.refer+1.5f, GralPos.size -1.5f, 1, 18, 0, 'r', 1);
302    if(cmdWind == Ecmd.delete) {
303      main._gralMng.addText("Del read only ?");
304    } else if(cmdWind == Ecmd.compare) {
305      //nothing such
306    } else {
307      main._gralMng.addText("Overwr read only ?");
308      main._gralMng.addText("Overwr exists ?");
309      main._gralMng.addText("Create ?");
310    }
311    if(cmdWind != Ecmd.compare) {
312      main._gralMng.setPosition(GralPos.refer+3.5f, GralPos.size -3, 1, GralPos.size +12, 0, 'r',1);
313      widgdChoiceOverwrReadOnly = main._gralMng.addButton("overwritero", actionOverwrReadonly, "overwritero", null,"ask ?yes ?no");
314      widgdChoiceOverwrReadOnly.setBackColor(GralColor.getColor("lam"), 0);
315      widgdChoiceOverwrReadOnly.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".ctrl.overwrRo.");
316    }
317    if(cmdWind != Ecmd.delete && cmdWind != Ecmd.compare) {
318      main._gralMng.setPosition(GralPos.same, GralPos.size -3, GralPos.next, GralPos.size +20, 0, 'r',1);
319      widgdChoiceOverwrExists = main._gralMng.addButton("copyOverwriteReadonly", actionOverwrDate, "copyOverwriteReadonly", null, "ask ?newer?older?all ?no");
320      widgdChoiceOverwrExists.setBackColor(GralColor.getColor("lam"), 0);
321      widgdChoiceOverwrExists.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".ctrl.overwrExists.");
322      main._gralMng.setPosition(GralPos.same, GralPos.size -3, GralPos.next, GralPos.size +12, 0, 'r',1);
323      widgdChoiceCreateNew = main._gralMng.addButton("copyCreate", actionCreateCopy, "copyCreate", null, "yes ?no ?ask");
324      widgdChoiceCreateNew.setBackColor(GralColor.getColor("lgn"), 0);
325      widgdChoiceCreateNew.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".ctrl.createNew.");
326    }
327    
328    //field for showing the current action or state, not for input:
329    //field for showing the current name, not for input:
330    main._gralMng.setPosition(GralPos.refer + 3.5f, GralPos.size +3.2f, 1, -1, 0, 'd');
331    widgCopyDirDst = main._gralMng.addTextField("copyDirDst", false, "current directory:", "t");
332    widgCopyDirDst.setBackColor(GralColor.getColor("lam"),0);
333    widgCopyDirDst.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".currfile.");
334    widgCopyNameDst = main._gralMng.addTextField("copyNameDst", false, "current file:", "t");
335    widgCopyNameDst.setBackColor(GralColor.getColor("lam"),0);
336    widgCopyNameDst.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".currfile.");
337    
338    main._gralMng.setPosition(GralPos.refer+3.5f, GralPos.size +3.2f, 1, -15, 0, 'd', 0.3f); //same line as del
339    widgCopyState = main._gralMng.addTextField("copyStatus", false, "current state:", "t");
340    widgCopyState.setBackColor(GralColor.getColor("lam"),0);
341    widgCopyState.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".state.");
342    
343    main._gralMng.setPosition(-4, GralPos.size +1, 10, -14, 0, 'd', 1);
344    if(cmdWind != Ecmd.delete) {
345      //widgProgressFile = main.gralMng.addValueBar("copyProgressFile", null);
346    }
347    //widgProgressAll = main.gralMng.addValueBar("copyProgressAll", null);
348
349    if(cmdWind == Ecmd.copy) {
350      main._gralMng.setPosition(-8, GralPos.size+2.5f, -13f, -1, 0, 'd', 0.3f);
351      widgButtonMove = main._gralMng.addSwitchButton("copyMove", "move ?", "Move/ ?copy", GralColor.getColor("wh"), GralColor.getColor("lgn"));
352      widgButtonMove.setActionChange(actionButtonCmprDelMove);
353      widgButtonMove.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".fn.");
354    }
355    main._gralMng.setPosition(-4, GralPos.size+3.2f, 1, 9, 0, 'r');
356    widgButtonEsc = main._gralMng.addButton("copyEsc", actionButtonAbort, "esc", null, "close");
357    widgButtonEsc.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".escape.");
358    main._gralMng.setPosition(GralPos.same, GralPos.size +2.5f, GralPos.next, GralPos.size+3.0f, 0, 'r', 1);
359    widgState = main._gralMng.addButton(null, actionShowState, "?", null, "?" );
360    widgState.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".state.");
361    
362    if(cmdWind != Ecmd.compare){
363      //main.gralMng.setPosition(GralPos.refer+3.5f, GralPos.size -3, 1, 12, 0, 'r', 1);
364      main._gralMng.setPosition(GralPos.same, GralPos.size +2.5f, GralPos.next, GralPos.size + 11, 0, 'r', 1);
365      //main.gralMng.setPosition(GralPos.same, GralPos.size -3, 16, GralPos.size +14, 0, 'r', 1);
366      widgSkipDir = main._gralMng.addButton("copySkipDir", actionButtonSkipDir, "copySkipDir", null, "skip dir");
367      widgSkipDir.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".quest.skipDir.");
368      widgSkipFile = main._gralMng.addButton("copyskip", actionButtonSkipFile, "copyskip", null, "skip file");
369      widgSkipFile.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".quest.skipFile.");
370      widgOverwrFile = main._gralMng.addButton(sTextExecuteForFile, actionOverwriteFile, "copyOverwrite", null, sTextExecuteForFile);
371      widgOverwrFile.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".quest.wr.");
372      //widgBtnPause = main.gralMng.addButton("pause", null, "pause", null, "pause");
373      //widgBtnPause.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".pause.");
374    }  
375    main._gralMng.setPosition(-4, GralPos.size+3.5f, -13f, -1, 0, 'd', 0.4f);
376    widgButtonOk = main._gralMng.addButton("copyOk", actionButtonOk, "close", null, "close");
377    widgButtonOk.setHtmlHelp(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".ok.");
378  
379  }
380  
381  
382  protected void closeWindow(){
383    widgButtonOk.setText("close");
384    //widgButtonOk.setCmd("close");
385    filesToCopy.clear();
386    listEvCheck.clear();
387    listEvCopy.clear();
388    state = Estate.inactive;
389    windConfirmCopy.setVisible(false);
390    //main.gralMng.setWindowsVisible(windConfirmCopy, null); //set it invisible.
391  }
392  
393  
394  
395  
396  
397  /**Last files which are in copy process. Typical contains one file only. 
398   * This list will be filled in {@link #actionButtonCopy} if the copy process will be started.
399   * It is used in {@link #actionLastSrc} to fill the {@link #filesToCopy}.
400   * This list remains after copy process to supply "last files".
401   */
402  //final List<FileRemote> filesToCopyLast = new LinkedList<FileRemote>();
403  
404  
405  
406  /**All mode bits of the 3 variables.*/
407  private int modeCopy(){
408    int mode = modeCreateCopy | modeOverwrReadonly |modeOverwrDate;
409    return mode;            
410  }
411
412
413  /**Starts the execution of mark in another thread. Note that the mark works with the walk-file algorithm
414   * and refreshes the files therewith. The #action.showFilesProcessing is used as callback.
415   * See {@link FileRemote#refreshAndMark(int, boolean, String, int, int, FileRemoteCallback)}.
416   */
417  final void execMark(){
418    setTexts(Estate.busyCheck);
419    widgCopyState.setText("busy-check");
420    widgButtonOk.setText("busy-check");
421    widgButtonCheck.setState(GralButton.State.Disabled);
422    widgButtonEsc.setText("abort");
423    String sSrcMask= widgFromConditions.getText();
424    //FileSystem: acts in other thread.
425    //regards mark in first level ?
426    int depths = srcSomeFiles ? -Integer.MAX_VALUE : Integer.MAX_VALUE;
427    long bMarkSelect = srcSomeFiles ? 0x200000000L + FileMark.select : 0;
428    //====>
429    //srcFile.refreshAndMark(bFirstSelect, sSrcMask, bMarkSelect, depths, callbackFromFilesCheck, action.showFilesProcessing);
430    srcFile.refreshAndMark(false, sSrcMask, bMarkSelect, depths, callbackFromFilesCheck, action.showFilesProcessing);
431    widgCopyNameDst.setText(srcDir.getStateDevice());
432    bFirstSelect = false;
433  }
434  
435  
436  final protected void execDel(){
437    if(state == Estate.checked){
438      srcFile.deleteMarkedInThread(FileMark.select, callbackFromFilesExec);      
439    } else if(state == Estate.start){
440    }
441  }
442  
443  
444  
445  final protected void execMove() {
446    String sDst = widgInputDst.getText();
447    String sDstDir, sDstMask;
448    int posWildcard = sDst.indexOf('*');
449    if(posWildcard >0) {
450      int posSep = sDst.lastIndexOf('/', posWildcard);
451      sDstDir = sDst.substring(0, posSep+1);
452      sDstMask = sDst.substring(posSep+1);
453    } else {
454      sDstDir = sDst;
455      sDstMask = null;
456    }
457    FileRemote fileDst;
458    if(FileSystem.isAbsolutePathOrDrive(sDstDir)) {
459      fileDst = main.fileCluster.getDir(sDstDir);  //maybe a file or directory
460    } else {
461      fileDst = srcDir.child(sDstDir);  //relative to source
462    }
463    FileRemote.CallbackEvent callback = new FileRemote.CallbackEvent(evSrc, srcFile, null, evConsumerCallbackFromFileMachine, null, evSrc);
464    //====>
465    //srcFile.moveChecked(sFilesSrc, fileDst, callback);
466    setTexts(Estate.busy);
467    ///
468  }
469
470
471  /**Starts the execution of copy in another thread. Note that the compy works with a state machine which uses
472   * the found files in the {@link FileRemote#children()} tree. 
473   * See {@link FileRemote#copyChecked(String, String, int, org.vishia.fileRemote.FileRemote.CallbackEvent)}.
474   */
475  final protected void execCopy(){
476    widgCopyState.setText("busy-copy");
477    widgButtonOk.setText("busy-copy");
478    widgButtonEsc.setText("abort");
479    String sDst = widgInputDst.getText();
480    String sDstDir, sDstMask;
481    int posWildcard = sDst.indexOf('*');
482    if(posWildcard >0) {
483      int posSep = sDst.lastIndexOf('/', posWildcard);
484      sDstDir = sDst.substring(0, posSep+1);
485      sDstMask = sDst.substring(posSep+1);
486    } else {
487      sDstDir = sDst;
488      sDstMask = null;
489    }
490    if(!FileSystem.isAbsolutePathOrDrive(sDstDir)) {
491      sDstDir = srcDir.getAbsolutePath() + "/" + sDstDir;
492    }
493    //====>
494    srcFile.copyChecked(sDstDir, sDstMask, modeCopy(), null, action.showFilesProcessing);  //, evCallback);
495    //String stateCopy = copyStates.getStateInfo();
496    setTexts(Estate.busy);
497    //widgCopyState.setText("State: " + stateCopy);
498  } 
499  
500  
501  /**Starts the execution of compare in another thread. Note that the compare works with the walk-file algorithm
502   * and refreshes the files therewith. See {@link FileRemote#refreshAndCompare(FileRemote, int, String, int, org.vishia.fileRemote.FileRemote.CallbackEvent)}.
503   */
504  final protected void execCompare(){
505    String sDst = widgInputDst.getText();
506    int posSep = sDst.lastIndexOf('/');
507    int posSep2 = sDst.lastIndexOf('\\');
508    if(posSep2 >=0 && posSep2 > posSep){ posSep = posSep2; }
509    int posWildcard = sDst.indexOf('*');
510    String sDstDir;
511    if(posWildcard > posSep){
512      sDstDir = sDst.substring(0, posSep);
513    } else {
514      //no asterisk, either it is one file or it is the destination dir:
515      sDstDir = sDst;
516    }
517    FileRemote fileDst;
518    if(FileSystem.isAbsolutePathOrDrive(sDstDir)) {
519      fileDst = main.fileCluster.getDir(sDstDir);  //maybe a file or directory
520    } else {
521      fileDst = srcDir.child(sDstDir);  //relative to source
522    }
523    if(fileDst.isDirectory()){ dirDst = fileDst; } 
524    else { dirDst = fileDst.getParentFile(); } 
525    boolean bOk = true;
526    //check whether the event is able to occupy, use it to check.
527    if(evCallback.occupyRecall(100, evSrc, evConsumerCallbackFromFileMachine, null, true) == 0){
528      if(evCallback.occupyRecall(1000, evSrc, evConsumerCallbackFromFileMachine, null, true) == 0){
529        System.err.println("FcmdCopyCmd event occupy hangs");
530        bOk = false;
531      }
532    }
533    if(bOk) {
534      String sSrcMask= widgFromConditions.getText();
535      evCallback.sendEvent(FileRemote.CallbackCmd.start);  //sends to myself for showing the state, 
536      //it is a check of sendEvent and it should relinguish the event.
537      //====>
538      srcFile.refreshAndCompare(dirDst, 0, sSrcMask, 0, null, action.showFilesProcessing); //evCallback); //evCallback able to use from callback.
539      //setTexts(Estate.busy);
540    } else {
541      widgCopyState.setText("evCallback hangs");
542      setTexts(Estate.quest);
543    }
544    ///
545  }
546  
547  
548  final protected void abortCopy(){
549    //if(fileSrc !=null ) {fileSrc.abortAction();}
550    for(FileRemote.CallbackEvent ev: listEvCopy){
551      //ev.copyAbortAll();
552      //ev.sendEvent(FileRemote.cmdAbortAll);
553    }
554    if(action.showFilesProcessing.evAnswer.getDst() !=null) { //don't send if the destination is not set.
555      action.showFilesProcessing.evAnswer.send(FileRemoteProgressTimeOrder.Answer.abortAll, modeCopy() ); //triggerStateMachine(evSrc, FileRemote.Cmd.abortAll);
556    }
557    String sDirSrc = widgShowSrc.getText();
558    //FileRemote dirSrc = main.fileCluster.getFile(sDirSrc, null); //new FileRemote(sDirSrc);
559    if(srcDir !=null) { srcDir.abortAction(); }  //to set stateMachine of copy in ready state 
560    else {
561      System.err.println("FcmdCopyCmd: abort, dirSrc not given.");
562    }
563    listEvCheck.clear();
564    listEvCopy.clear();
565    filesToCopy.clear();
566    FcmdCopyCmprDel.this.evCurrentFile = null;
567    //bLockSrc = false;
568    //widgButtonOk.setText("close");
569    //widgButtonOk.setCmd("close");
570    setTexts(Estate.finit);
571  }
572  
573  
574  /**Sets the source and destination depending on the cmd and given {@link #srcFile}, {@link #dirDst}
575   * The {@link #widgInputDst} will be not changed if {@link #bDstChanged} is set.
576   */
577  final void setTextSrcDst(){
578    //
579    //show source files, it is only to show, no functionality.
580    if(srcFile == null){
581      widgShowSrc.setText("--no source--");
582    } else {
583      if(sFilesSrc == null) {
584        if(srcFile.isDirectory()) { // && cmd == Ecmd.copy) {
585          if(srcSomeFiles){
586            widgShowSrc.setText(srcFile.getAbsolutePath() + "/?+");  //copy some files dir/?+ signals, there are more files but add mask into
587          } else {
588            widgShowSrc.setText(srcFile.getAbsolutePath() + "/*");  //copy a directory: show dir/* to signal, there are more files.
589          }
590        } else {
591          widgShowSrc.setText(srcFile.getAbsolutePath());         //compare, move or copy only one file: show only srcfile or srcdir
592        }
593      } else {
594        widgShowSrc.setText(srcFile.getAbsolutePath() + "/" + sFilesSrc);  //more as one 
595      }
596    }
597    //
598    if(cmdWind != Ecmd.delete) {
599      if(dirDst == null){
600        bufferDstChars.setLength(0); bufferDstChars.append("??");
601      } else if(!bDstChanged) {
602        if(cmd == Ecmd.compare) {
603          FileRemote dirDstCmpr = fileDst !=null && fileDst.isDirectory() ? fileDst : this.dirDst;
604          bufferDstChars.setLength(0); bufferDstChars.append(dirDstCmpr.getPathChars()); //.append('/').append(sFileDstCopy);
605        } else {
606          bufferDstChars.setLength(0); 
607          final FileRemote dstSet;
608          if(!widgButtonModeDst.isOn() || srcFile.isDirectory() && !fileDst.isDirectory()){
609            dstSet = dirDst;
610            bufferDstChars.append(dirDst.getPathChars()); //the directory of the file.
611          } else {
612            //select "dst/dst" in mode or 
613            dstSet = fileDst;
614            bufferDstChars.append(fileDst.getPathChars()); //file or directory
615          }
616          //if(cmd == Ecmd.copy || cmd == Ecmd.move){
617          //if(dirDst == fileDst || fileSrc.isDirectory() && !fileDst.isDirectory()) {  // .. is selected
618          if(dstSet.isDirectory()) {  // .. is selected
619            if(srcSomeFiles){
620              bufferDstChars.append("/*");  
621            } else {
622              String nameSrc = srcFile.getName();
623              bufferDstChars.append('/').append(nameSrc);
624            }
625          }
626          if(cmd == Ecmd.copy && srcFile != null && srcFile.isDirectory()) {
627            bufferDstChars.append("/*");
628          }
629        }
630      }
631      widgInputDst.setText(bufferDstChars);
632    }
633    
634  }
635
636
637  /**Set the texts to any widgets depending on the state of execution and the activated switch key.
638   * @param newState
639   */
640  void setTexts( Estate newState) {  ////
641    state = newState;
642    //Texts depending from pressed command button:
643    String[][] textOk = 
644    { { "check del"  , "move"        , "check copy", "compare" }
645    , { "check del"  , "move"        , "check copy", "compare" }
646    , { "busy check" , "busy check"  , "busy check", "compare" }
647    , { "del checked", "move checked", "copy checked", "compare" } 
648    , { "pause del"  , "pause move"  , "pause copy", "pause cmpr" }
649    , { "close del"  , "close move"  , "close copy", "close cmpr"  }
650    };
651    String[][] textSrc = 
652    { { "set src + dst", "set src + dst", "busy check", "set src + dst", "busy", "set src + dst" }
653    , { "set dst", "set dst", "busy check", "set dst", "busy", "set dst" }
654    };
655    String[] textAbort = { "abort"         , "abort"       , "abort"        , "abort", "abort", "close" };
656    String[] textDest =  { "---"           , "move to"     , "copy to"      , "compare with"  };
657    
658    int ix1;
659    if(cmdWind == Ecmd.delete){ 
660      ix1=0; 
661      cmd = Ecmd.delete; 
662      if(cmdWind != Ecmd.delete) {
663        widgButtonMove.setState(GralButton.State.Off);
664        widgInputDst.setEditable(false);
665        widgInputDst.setBackColor(colorGrayed, 0);
666      }
667    } else if(cmdWind == Ecmd.compare){ 
668      ix1 = 3; 
669      cmd = Ecmd.compare; 
670      widgInputDst.setEditable(true);
671      widgInputDst.setBackColor(bDstChanged ? colorChangedText : colorNoChangedText, 0);
672    } else {
673      //move or copy window:
674      if(state == Estate.finit) {
675        widgOverwrFile.setBackColor(GralColor.getColor("lgr"), 0);
676        widgSkipFile.setBackColor(GralColor.getColor("lgr"), 0);
677      }  
678      if(widgButtonMove.isOn()) { 
679      ix1 = 1; 
680        cmd = Ecmd.move; 
681        widgInputDst.setEditable(true);
682        widgInputDst.setBackColor(bDstChanged ? colorChangedText : colorNoChangedText, 0);
683      } else { 
684        ix1 = 2; 
685        cmd = Ecmd.copy; 
686        widgInputDst.setEditable(true);
687        widgInputDst.setBackColor(bDstChanged ? colorChangedText : colorNoChangedText, 0);
688      }
689    }
690    if(cmdWind != Ecmd.delete) {
691      widgInputDst.setPrompt(textDest[ix1]);
692    }
693    if(!bDstChanged) {
694      setTextSrcDst();
695    }
696    int ix2;
697    GralButton.State checkDisable;
698    boolean setSrcPossible;
699    switch(state){
700      case start: setSrcPossible = true; checkDisable = GralButton.State.On; ix2= bFineSelect? 1 : 0; break;
701      case busyCheck: setSrcPossible = false; checkDisable = GralButton.State.Disabled; ix2=2; break;
702      case checked: setSrcPossible = false; checkDisable = GralButton.State.On; ix2=3; break;
703      case quest:
704      case busy: setSrcPossible = false; checkDisable = GralButton.State.Disabled; ix2=4; break;
705      case error:
706      case inactive:
707      case finit: setSrcPossible = true; checkDisable = GralButton.State.On; ix2=5; break;
708      default: setSrcPossible = true; checkDisable = GralButton.State.On; ix2=0;
709    }
710    String sTextBtnOk = textOk[ix2][ix1];
711    widgButtonOk.setText(sTextBtnOk);
712    //String sTextSrc = textSrc[bLockSrc? 1: 0][ix2];
713    //widgButtonCheck.setText(sTextSrc);
714    widgButtonCheck.setState(checkDisable);
715    widgButtonSetSrc.setState(setSrcPossible ? GralButton.State.On : GralButton.State.Disabled);
716    String sTextAbort = textAbort[ix2];
717    widgButtonEsc.setText(sTextAbort);
718    
719  }
720  
721  
722  
723  /**Invoked with a time order.
724   * 
725   */
726  void showCurrentProcessedFileAndDir(FileRemoteProgressTimeOrder order) //FileRemote fileProcessed, int zFiles, boolean bDone) {
727  { StringBuilder u = new StringBuilder(100);
728    if(order.currFile !=null) {
729      widgCopyDirDst.setText(order.currFile.getParent());
730      widgCopyNameDst.setText(order.currFile.getName());
731    } else {
732      widgCopyDirDst.setText("?");
733      widgCopyNameDst.setText("?");
734    }
735    if(order.bDone) {
736      widgCopyState.setText("ok: "); // + ev1.nrofBytesInFile/1000000 + " M / " + ev1.nrofBytesAll + "M / " + ev1.nrofFiles + " Files");
737      setTexts(Estate.finit);
738    }
739    if(order.quest() !=null) {
740      switch(order.quest()){
741        case askDstOverwr: 
742          u.append("overwrite file? "); 
743          widgOverwrFile.setBackColor(GralColor.getColor("lng"), 0);
744          widgSkipFile.setBackColor(GralColor.getColor("lgn"), 0);
745          break;
746        case askDstNotAbletoOverwr: 
747          u.append("cannot overwrite file? "); 
748          widgSkipFile.setBackColor(GralColor.getColor("lrd"), 0);
749          break;
750        case askErrorCopy: 
751          u.append("error copy? "); 
752          widgSkipFile.setBackColor(GralColor.getColor("lrd"), 0);
753          break;
754        case askErrorDstCreate: 
755          u.append("cannot create? "); 
756          widgSkipFile.setBackColor(GralColor.getColor("lrd"), 0);
757          break;
758        case askDstReadonly: 
759          u.append("overwrite readonly file? "); 
760          widgOverwrFile.setBackColor(GralColor.getColor("lng"), 0);
761          widgSkipFile.setBackColor(GralColor.getColor("lgn"), 0);
762          break;
763        case askErrorSrcOpen: 
764          u.append("cannot open sourcefile "); 
765          widgSkipFile.setBackColor(GralColor.getColor("lrd"), 0);
766          break;
767        case done:       
768          u.append("ok: "); // + ev1.nrofBytesInFile/1000000 + " M / " + ev1.nrofBytesAll + "M / " + ev1.nrofFiles + " Files");
769          setTexts(Estate.finit);
770          break;
771        
772      }
773    }
774    u.append("; Files:").append(Integer.toString(zFiles)).append(": ");
775    widgCopyState.setText(u.toString());
776  }
777  
778  
779  void showFinishState(CharSequence start, SortedTreeWalkerCallback.Counters cnt)
780  {
781    FcmdCopyCmprDel.this.zFiles = cnt.nrofLeafss;
782    FcmdCopyCmprDel.this.zBytes = cnt.nrofBytes;
783    formatShow.reset();
784    formatShow.add(start);
785    formatShow.add(" Files:").addint(cnt.nrofLeafSelected, "3333333331");
786    //StringBuilder u = new StringBuilder();
787    //u.append("Files:").append(Integer.toString(cnt.nrofLeafSelected));
788    if(cnt.nrofLeafSelected != cnt.nrofLeafss){  //u.append(" (").append(Integer.toString(cnt.nrofLeafSelected)).append(")"); }
789      formatShow.add(" /").addint(cnt.nrofLeafss, "3333333331");
790    }
791    if(cnt.nrofBytes > 1000000){
792      formatShow.addint(cnt.nrofBytes/1000, ", 33331.111 MByte");
793    }
794    else if(cnt.nrofBytes > 1000){
795      formatShow.addint(cnt.nrofBytes, ", 331.111 kByte");
796    } else {
797      formatShow.addint(cnt.nrofBytes, ", 331 Byte");
798    }
799    widgCopyState.setText(formatShow.toString());
800  }
801  
802  void actionConfirmCopy(){
803    
804  }
805
806  
807  /**Will be initialized if the main.gralMng is available.
808   */
809  private class Actions
810  {
811    
812    @SuppressWarnings("serial") 
813    FileRemoteProgressTimeOrder showFilesProcessing = 
814        new FileRemoteProgressTimeOrder("showFilesProcessing", evSrc, main._gralMng.gralDevice.orderList(), 100) 
815    {
816      @Override public void executeOrder() { 
817        //System.out.println("showFilesProcessing");
818        showCurrentProcessedFileAndDir(this); //this.currFile, this.nrFilesProcessed, this.bDone); 
819        //this.currFile = null;  //to invoke second time.
820      }
821    };
822  }  
823
824  /**Shows the state of FileRemote, especially for debug and problems. */
825  GralUserAction actionShowState = new GralUserAction("actionConfirmCopy")
826  {
827    @Override public boolean exec(int key, GralWidget_ifc widgi, Object... params){ 
828      if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
829        if(srcFile !=null) { widgCopyState.setText(srcFile.getStateDevice()); }
830        else { widgCopyState.setText("no source file"); }
831      }
832      return true;
833    }
834  };
835  
836  /**Opens the confirm-copy window, prepares the list of src files.
837   */
838  GralUserAction actionConfirmCopy = new GralUserAction("actionConfirmCopy")
839  {
840    /**Opens the confirm-copy window and fills its fields to ask the user whether confirm.
841     */
842    @Override public boolean exec(int key, GralWidget_ifc widgi, Object... params)
843    { //String sSrc, sDstName, sDstDir;
844      if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
845        //sCmd: This method was called from a button or with any function key.
846        //sCmd describes from where it was called.
847        String sCmd = widgi instanceof GralWidget ? ((GralWidget)widgi).getCmd() : "openCopy";
848        //
849        if(state == Estate.inactive){
850          setTexts(Estate.finit);
851        } 
852        //if(state.equals("close") || state.equals("check")) {
853        //if(state == Estate.start || state == Estate.checked || state == Estate.finit || state == Estate.error) {
854        if(!widgButtonSetSrc.isDisabled()) {
855          //only if it is ready to check, get the files.
856          bFirstSelect = true;
857          filesToCopy.clear();
858          listEvCheck.clear();
859          listEvCopy.clear();
860          FcmdFileCard[] lastFileCards = main.getLastSelectedFileCards();
861          if(lastFileCards[0] !=null){ ///
862            fileCardSrc = lastFileCards[0];
863            fileCardDst = lastFileCards[1];
864            
865            //widgButtonDst.setState(GralButton.kOff);  //maybe disabled, set off.
866            List<FileRemote> listFileSrc = fileCardSrc.getSelectedFiles(true, 1);
867            //String sDirSrc;
868            if(listFileSrc == null){
869              //widgShowSrc.setText("??? listFileSrc==null");
870              
871            } else {
872              if(listFileSrc.size() ==1){
873                //only one file is selected:
874                srcFile = listFileSrc.get(0);
875                srcDir = srcFile.getParentFile();
876                srcSomeFiles = false;
877                sFilesSrc = null;  //only one file, 
878                //widgShowSrc.setText(fileSrc.getAbsolutePath());
879                if(srcFile.isDirectory()) {
880                  sFileDstCopy = "*";
881                } else {
882                  sFileDstCopy = srcFile.getName();  //name of source file as default for destination.
883                }
884              } else {
885                //more as one file:
886                sFileDstCopy = "*";
887                //StringBuilder uFileSrc = new StringBuilder();
888                //fileSrc = fileCardSrc.currentFile();
889                srcFile = srcDir = fileCardSrc.currentDir();
890                srcDir.setMarked(FileMark.selectSomeInDir);
891                srcSomeFiles = true;
892                //srcFile = null; 
893                sFilesSrc = null;  //only one file, 
894                //widgShowSrc.setText(dirSrc.getAbsolutePath() + "/?+");
895                /*
896                fileSrc = dirSrc 
897                String sSep = "";
898                for(FileRemote srcFile : listFileSrc){
899                  srcFile.resetMarked(1);
900                  uFileSrc.append(sSep).append(srcFile.getName());
901                  sSep = " : "; //For next one.
902                  //FileRemote fileSrc = FileRemote.fromFile(srcFile);
903                  //filesToCopy.add(fileSrc);
904                }
905                sFilesSrc = uFileSrc.toString();
906                uFileSrc.insert(0, " : ").insert(0, fileSrc.getAbsolutePath());
907                widgShowSrc.setText(uFileSrc);
908                */
909              }
910            }
911            //sDstName = listFileSrc.size() >1 ? "*" 
912            //           : listFileSrc.size() ==1 ? listFileSrc.get(0).getName() : "??";
913            //sSrc = fileSrc.getAbsolutePath() + "/" + sDstName;
914            if(fileCardDst !=null){
915              dirDst = fileCardDst.currentDir();
916              fileDst = fileCardDst.currentFile();  //it is ==dirDst if .. is selected.
917              /*
918              if(dirDst !=null) {
919                if(!dirDst.isDirectory()) {
920                  dirDst = dirDst.getParentFile();  //a file selected, use the directory of the panel.
921                } else {
922                  //dirDst.getPathChars(bufferDstChars);
923                }
924              }
925              */
926              //dirDstCmpr = fileCardDst.currentFile();  //should be a directory, check later before compare.
927              //sDstDir = dirDst.getAbsolutePath();
928            } else {
929              dirDst = null;
930              fileDst = null;
931              //sDstDir = "??";
932            }
933            //bLockSrc = true;
934            //widgFromConditions.setText("");
935          } else { //FileCard not found:
936            srcFile = null;
937            dirDst = null;
938            fileDst = null;
939            
940            //listFileSrc = null;
941            //sSrc = "???";
942            //sDstName = "??";
943            //sDstDir = "??";
944            widgShowSrc.setText("??");
945          }
946          /*
947          String sTextDst = widgCopyDirDst.getText().trim();
948          if(!sCmd.equals("setSrc") || sTextDst.length() == 0){
949            //set the destination only if it is not set on button setSrc
950            widgCopyDirDst.setText(sDstDir);
951            widgCopyDirDst.setBackColor(colorNoChangedText, 0);
952            bDstChanged = false;
953            widgCopyNameDst.setText(sDstName);
954          }
955          */
956          boolean setVisible = true; //state == Estate.inactive;
957          bDstChanged = false;
958          if(widgInputDst !=null) {
959            widgInputDst.setBackColor(colorNoChangedText, 0);
960          }
961          setTexts(Estate.start);
962          //widgButtonOk.setText("check");
963          //widgButtonOk.setCmd("check");
964          widgCopyState.setText("check?", 0);
965          if(setVisible){
966            widgButtonOk.setPrimaryWidgetOfPanel();
967            windConfirmCopy.setVisible(true);
968            main.gui.setHelpUrl(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".");
969          }
970          //widgButtonMove.setValue(GralMng_ifc.cmdSet, 0, 0);
971          zFiles = 0; zBytes = 0;
972        }
973        windConfirmCopy.setFocus();
974        //main.gralMng.setWindowsVisible(windConfirmCopy, posWindConfirmCopy);
975        main.gui.setHelpUrl(main.cargs.dirHtmlHelp + "/Fcmd.html#Topic.FcmdHelp." + helpPrefix + ".");
976      }
977      return true;
978   }  };
979  
980  
981
982   /**Opens the confirm-copy window, prepares the list of src files.
983    * It is Key F5 for copy command from the classic NortonCommander.
984    * The OK-key is designated to "check". On button pressed the {@link #actionButtonCopy} is called,
985    * with the "check" case.
986    */
987   GralUserAction actionCheck = new GralUserAction("actionCheck")
988   {
989     /**Opens the confirm-copy window and fills its fields to ask the user whether confirm.
990      * @param dst The path which is selected as destination. It may be a directory or a file
991      * @param src The path which is selected as source. It may be a directory or a file.
992      */
993     @Override public boolean exec(int key, GralWidget_ifc widgi, Object... params)
994     { //String sSrc, sDstName, sDstDir;
995       if(KeyCode.isControlFunctionMouseUpOrMenu(key)){ 
996         if(!widgButtonCheck.isDisabled()){
997         //if(state == Estate.start || state == Estate.checked) { //widgg.sCmd.equals("check")){    
998           execMark();
999         }
1000       }
1001       return true;
1002     }
1003   };
1004   
1005
1006  
1007   protected GralUserAction actionSetDst = new GralUserAction("actionSetDst") ///
1008   { @Override public boolean exec(int key, GralWidget_ifc widgP, Object... params)
1009     { if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1010         GralButton widgb = (GralButton)(widgP);
1011         FcmdFileCard[] lastFileCards = main.getLastSelectedFileCards();
1012         fileCardDst = lastFileCards[0];
1013         dirDst = fileCardDst.currentDir();
1014         CharSequence sText = dirDst.getAbsolutePath();
1015         /*
1016         if(sFilesSrc == null || sFilesSrc.isEmpty()){
1017           StringBuilder u = new StringBuilder(sText);
1018           sText = u.append("/").append( fileSrc.getName());
1019         }
1020         */
1021         bDstChanged = false;
1022         setTextSrcDst();
1023       }
1024       return true;
1025     }
1026   };
1027   
1028   
1029   protected GralUserAction actionChgModeDst = new GralUserAction("actionChgModeDst") ///
1030   { @Override public boolean exec(int key, GralWidget_ifc widgP, Object... params)
1031     { if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1032         setTextSrcDst();
1033       }
1034       return true;
1035     }
1036   };
1037   
1038   
1039  protected GralUserAction actionEnterTextInDst = new GralUserAction("actionSelectMask")
1040  { @Override public boolean exec(int key, GralWidget_ifc widgi, Object... params)
1041    { if(key == KeyCode.valueChanged) {
1042        String text = widgInputDst.getText();
1043        if(StringFunctions.compare(text, bufferDstChars) ==0) {
1044          //unchanged text or the original text again:
1045          widgInputDst.setBackColor(colorNoChangedText, 0);
1046          bDstChanged = false;
1047        } else {
1048          widgInputDst.setBackColor(colorChangedText, 0);
1049          bDstChanged = true;
1050        }
1051      } else {
1052        Debugutil.stop();
1053      }
1054      return true;
1055    }
1056  };
1057
1058  GralUserAction actionOverwrReadonly = new GralUserAction("actionOverwrReadonly")
1059  {
1060    @Override public boolean userActionGui(int key, GralWidget infos, Object... params){
1061      if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1062        switch(modeOverwrReadonly){
1063        case FileRemote.modeCopyReadOnlyAks: 
1064          modeOverwrReadonly= FileRemote.modeCopyReadOnlyOverwrite; 
1065          widgdChoiceOverwrReadOnly.setText("yes ?no ?ask");
1066          widgdChoiceOverwrReadOnly.setBackColor(GralColor.getColor("lgn"), 0);
1067          break;
1068        case FileRemote.modeCopyReadOnlyNever: 
1069          modeOverwrReadonly= FileRemote.modeCopyReadOnlyAks; 
1070          widgdChoiceOverwrReadOnly.setText("ask ?yes ?no");
1071          widgdChoiceOverwrReadOnly.setBackColor(GralColor.getColor("lam"), 0);
1072          break;
1073        default:
1074          modeOverwrReadonly= FileRemote.modeCopyReadOnlyNever; 
1075          widgdChoiceOverwrReadOnly.setText("no ?ask ?yes");
1076          widgdChoiceOverwrReadOnly.setBackColor(GralColor.getColor("lrd"), 0);
1077          break;
1078        }
1079      }
1080      return true;
1081  } };
1082  
1083  
1084  
1085  GralUserAction actionOverwrDate = new GralUserAction("actionOverwrDate")
1086  {
1087    @Override public boolean userActionGui(int key, GralWidget infos, Object... params){
1088      if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1089        switch(modeOverwrDate){
1090        case FileRemote.modeCopyExistAsk: 
1091          modeOverwrDate= FileRemote.modeCopyExistNewer; 
1092          widgdChoiceOverwrExists.setText("newer ?older?all ?no?ask");
1093          widgdChoiceOverwrExists.setBackColor(GralColor.getColor("lpk"),0);
1094          break;
1095        case FileRemote.modeCopyExistNewer: 
1096          modeOverwrDate= FileRemote.modeCopyExistOlder; 
1097          widgdChoiceOverwrExists.setText("older ?all ?no?ask?newer");
1098          widgdChoiceOverwrExists.setBackColor(GralColor.getColor("lbl"),0);
1099          break;
1100        case FileRemote.modeCopyExistOlder:
1101          modeOverwrDate= FileRemote.modeCopyExistAll; 
1102          widgdChoiceOverwrExists.setText("all ? no?ask?newer?older");
1103          widgdChoiceOverwrExists.setBackColor(GralColor.getColor("lgn"),0);
1104          break;
1105        case FileRemote.modeCopyExistAll:
1106          modeOverwrDate= FileRemote.modeCopyExistSkip; 
1107          widgdChoiceOverwrExists.setText("no ?ask?newer?older?all");
1108          widgdChoiceOverwrExists.setBackColor(GralColor.getColor("lrd"),0);
1109          break;
1110        default:
1111          modeOverwrDate= FileRemote.modeCopyExistAsk; 
1112          widgdChoiceOverwrExists.setText("ask ?newer?older?all ?no");
1113          widgdChoiceOverwrExists.setBackColor(GralColor.getColor("lam"),0);
1114          break;
1115        }
1116      }
1117      return true;
1118  } };
1119  
1120  
1121  
1122  GralUserAction actionCreateCopy = new GralUserAction("actionButtonCreateCopy")
1123  {
1124    @Override public boolean userActionGui(int key, GralWidget infos, Object... params){
1125      if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1126        switch(modeCreateCopy){
1127        case FileRemote.modeCopyCreateAsk: 
1128          modeCreateCopy = FileRemote.modeCopyCreateYes; 
1129          widgdChoiceCreateNew.setText("yes ?no ?ask");
1130          widgdChoiceCreateNew.setBackColor(GralColor.getColor("lgn"), 0);
1131          break;
1132        case FileRemote.modeCopyCreateYes: 
1133          modeCreateCopy = FileRemote.modeCopyCreateNever; 
1134          widgdChoiceCreateNew.setText("no ?ask ?yes");
1135          widgdChoiceCreateNew.setBackColor(GralColor.getColor("lrd"), 0);
1136          break;
1137        default:
1138          modeCreateCopy = FileRemote.modeCopyCreateAsk; 
1139          widgdChoiceCreateNew.setText("ask ?yes ?no");
1140          widgdChoiceCreateNew.setBackColor(GralColor.getColor("lam"), 0);
1141          break;
1142        }
1143      }
1144      return true;
1145  } };
1146  
1147  
1148   /**Opens the confirm-copy window, prepares the list of src files.
1149    * It is Key F5 for copy command from the classic NortonCommander.
1150    * The OK-key is designated to "check". On button pressed the {@link #actionButtonCopy} is called,
1151    * with the "check" case.
1152    */
1153   GralUserAction actionButtonCmprDelMove = new GralUserAction("actionButtonDel")
1154   {
1155     /**Opens the confirm-copy window and fills its fields to ask the user whether confirm.
1156      * @param dst The path which is selected as destination. It may be a directory or a file
1157      * @param src The path which is selected as source. It may be a directory or a file.
1158      */
1159     @Override public boolean exec(int key, GralWidget_ifc widgi, Object... params)
1160     { //String sSrc, sDstName, sDstDir;
1161       if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1162         setTexts(state);
1163       }
1164       return true;
1165     }
1166   };
1167   
1168   
1169  
1170  /**Action for any button of the confirm-copy window.
1171   * in a loop FileRemote.copyTo(dst) is called for any selected file. It may be one file, 
1172   * or more files in more selected lines.
1173   * The copy process itself is executed in an own thread in management of the FileRemote implementation,
1174   * see {@link org.vishia.fileLocalAccessor.FileRemoteAccessorLocalFile#addCommission(org.vishia.util.FileRemoteAccessor.Commission)}
1175   * for local files. The copy process can be executed in an remote device without copying of data
1176   * between this device (PC) and the remote device, if the commission is organized in the remote device itself.
1177   * <br><br>
1178   * To notify for success or progression of the copy process some events are used.
1179   * See the {@link #success} {@link EventConsumer} in this class. The event instance is given to the 
1180   * {@link FileRemote#copyTo(FileRemote, EventCmdPingPongType)} invocation. It is used to callback either from the thread
1181   * which copies local or from the thread which receives the copy response telegrams for remote communication.
1182   * <br><br>
1183   * All Events which are created are stored in the {@link #listEvCopy}. If the callback occurs, the event 
1184   * will be removed from the list. The list is only used to check whether the copy action is succeeded 
1185   * respectively to check whether all copy actions are succeeded. If a copy success callback is not received, 
1186   * for example because a remote device hangs or the communication fails, the copy process hasn't no
1187   * progression. The operator on this machine sees this situation because the progression bar stands.
1188   * The operator can abort the copy process to preset to a default empty state.  
1189   */
1190  protected GralUserAction actionButtonOk = new GralUserAction("actionButtonCopy")
1191  { @Override public boolean exec(int key, GralWidget_ifc widgg, Object... params)
1192    { if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1193        if(state == Estate.start) { //widgg.sCmd.equals("check")){    
1194          if(cmd == Ecmd.delete){
1195            execMark();
1196          } else if(cmd == Ecmd.copy || bFineSelect){
1197            execMark();
1198          } else if(cmd == Ecmd.move){
1199            execMark();
1200          } else if(cmd == Ecmd.compare){
1201            execCompare();
1202          }
1203        } else if(state == Estate.checked) { //widgg.sCmd.equals("copy")) {
1204          switch(cmd){
1205            case copy: execCopy(); break;
1206            case move: execMove(); break; 
1207            case delete: execDel(); break;
1208            case compare: execCompare(); break;
1209          }//switch
1210        } else if(state == Estate.finit) { //widgg.sCmd.equals("close")){
1211          closeWindow();
1212        } else {
1213          //should be state pause
1214          action.showFilesProcessing.evAnswer.send(FileRemoteProgressTimeOrder.Answer.cont, modeCopy()); //triggerStateMachine(evSrc, FileRemote.Cmd.docontinue);
1215        }
1216      }
1217      return true;
1218    }
1219  };
1220
1221  
1222  
1223  
1224  protected GralUserAction actionButtonAbort = new GralUserAction("actionButtonAbort")
1225  { @Override public boolean exec(int key, GralWidget_ifc widgg, Object... params)
1226    { if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1227        switch(state){ //inactive, start, checked, busyCheck, busy, quest, error, finit
1228          case start: {
1229            setTexts(Estate.finit);
1230          } break;
1231          case inactive:
1232          case error:
1233          case finit: closeWindow(); break;
1234          case quest:
1235          case busy: abortCopy(); break;
1236          case checked: abortCopy(); break;
1237          case busyCheck: abortCopy(); break;
1238        }
1239        //trigger a copy statemachine, only effected if in such a state.
1240        abortCopy();
1241      }
1242      return true;
1243    }
1244  };
1245
1246  
1247  
1248  
1249
1250  /**This action is used to skip over the current showed file while copying. Copying of the selected file
1251   * should be aborted and that file should be deleted.
1252   * 
1253   */
1254  protected GralUserAction actionOverwriteFile = new GralUserAction(sTextExecuteForFile)
1255  { @Override public boolean userActionGui(int key, GralWidget widgg, Object... params)
1256    { if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1257        if(action.showFilesProcessing.quest() == FileRemote.CallbackCmd.askDstOverwr
1258             || action.showFilesProcessing.quest() == FileRemote.CallbackCmd.askDstReadonly) {
1259          action.showFilesProcessing.modeCopyOper = modeCopy();
1260          action.showFilesProcessing.evAnswer.send(FileRemoteProgressTimeOrder.Answer.overwrite, modeCopy() ); 
1261          widgSkipFile.setBackColor(GralColor.getColor("wh"), 0);
1262          widgOverwrFile.setBackColor(GralColor.getColor("wh"), 0);
1263        } else {
1264          action.showFilesProcessing.evAnswer.send(FileRemoteProgressTimeOrder.Answer.cont, modeCopy() ); //triggerStateMachine(evSrc, FileRemote.Cmd.docontinue);
1265        }
1266        //widgCopyNameDst.setText("");
1267        widgCopyState.setText("skipped");
1268      }
1269      return true;
1270    } 
1271  };
1272  
1273  
1274  
1275  
1276  /**This action is used to skip over the current showed file while copying. Copying of the selected file
1277   * should be aborted and that file should be deleted.
1278   * 
1279   */
1280  protected GralUserAction actionButtonSkipFile = new GralUserAction("actionButtonSkipFile")
1281  { @Override public boolean userActionGui(int key, GralWidget widgg, Object... params)
1282    { if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1283        if(evCurrentFile !=null){
1284          int modeCopyOper = modeCopy();
1285          //action.showFilesProcessing.answer(FileRemoteProgressTimeOrder.Answer.abortFile);
1286          action.showFilesProcessing.evAnswer.send(FileRemoteProgressTimeOrder.Answer.abortFile, modeCopy() ); 
1287        }
1288        else if(action.showFilesProcessing !=null) {
1289          action.showFilesProcessing.modeCopyOper = modeCopy();
1290          action.showFilesProcessing.evAnswer.send(FileRemoteProgressTimeOrder.Answer.abortFile, modeCopy() ); //;
1291         
1292        }
1293        widgCopyNameDst.setText("");
1294        widgCopyState.setText("skipped");
1295        widgSkipFile.setBackColor(GralColor.getColor("wh"), 0);
1296        widgOverwrFile.setBackColor(GralColor.getColor("wh"), 0);
1297      }
1298      return true;
1299    } 
1300  };
1301  
1302  
1303  /**This action is used to skip over the current showed file while copying. Copying of the selected file
1304   * should be aborted and that file should be deleted.
1305   * 
1306   */
1307  protected GralUserAction actionButtonSkipDir = new GralUserAction("actionButtonSkipDir")
1308  { @Override public boolean userActionGui(int key, GralWidget widgg, Object... params)
1309    { if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
1310        if(evCurrentFile !=null){
1311          int modeCopyOper = modeCopy();
1312          //evCurrentFile.copySkipDir(modeCopyOper);
1313        }
1314        action.showFilesProcessing.evAnswer.send(FileRemoteProgressTimeOrder.Answer.abortDir, modeCopy() ); //triggerStateMachine(evSrc, FileRemote.Cmd.abortAll);
1315        widgSkipFile.setBackColor(GralColor.getColor("wh"), 0);
1316        widgOverwrFile.setBackColor(GralColor.getColor("wh"), 0);
1317      }
1318      return true;
1319    } 
1320  };
1321  
1322  
1323
1324  protected GralUserAction actionSelectMask = new GralUserAction("actionSelectMask")
1325  { @Override public boolean exec(int key, GralWidget_ifc widgi, Object... params)
1326    { String sContent = ((GralTextField_ifc)widgi).getText();
1327      boolean empty = sContent.isEmpty();
1328      System.out.println("actionSelectMask");
1329      if(empty == bFineSelect){
1330        bFineSelect = !empty;
1331        setTexts(state);
1332      }
1333      return false;
1334    }
1335  };
1336
1337  
1338  
1339  
1340  
1341  private void eventConsumed(EventObject evp, boolean ok){
1342    FileRemote.CallbackEvent ev = (FileRemote.CallbackEvent)evp;
1343    listEvCopy.remove(ev);
1344    int nrofPendingFiles = listEvCopy.size();
1345    
1346    /*
1347    //int percent = (int)(nrofPendingFiles * 100 / zFiles);  //- filesToCopy.size();
1348    widgProgressAll.setValue(100);
1349    if(ok){
1350      File file = ev.getFileSrc();
1351      FileCompare.Result cmprResult = fileCardSrc.searchCompareResult(file);
1352      if(cmprResult !=null){
1353        cmprResult.setToEqual();  
1354      }
1355      fileCardSrc.fillInCurrentDir();  //maybe changed if dst = src or if moved.
1356      if(fileCardDst !=null){
1357        fileCardDst.fillInCurrentDir();
1358      }
1359    }
1360    */
1361    if(nrofPendingFiles == 0){
1362      if(!ok){
1363        widgCopyState.setText("error");
1364        widgButtonOk.setText("quit");
1365        //widgButtonOk.setCmd("quit");
1366      } else {
1367        widgButtonOk.setText("close");
1368        //widgButtonOk.setCmd("close");
1369      }
1370      widgButtonEsc.setText("close");
1371      //widgButtonEsc.setCmd("close");
1372      //windConfirmCopy.setVisible(false);      
1373    }
1374  }
1375  
1376  
1377  
1378  
1379  /**Instance of an event consumer which is used for all callback actions from the FileRemote machine.
1380   * The given event contains a command which depends on the action which is done by the file state machine or the file process.
1381   * Especially
1382   * <ul>
1383   * <li>{@link FileRemote.CallbackCmd#nrofFilesAndBytes}: shows the progress of the action. 
1384   * </ul>
1385   */
1386  EventConsumer evConsumerCallbackFromFileMachine = new EventConsumer(){
1387    @Override public int processEvent(EventObject ev)
1388    {
1389      FileRemote.CallbackEvent ev1 = (FileRemote.CallbackEvent)ev;
1390      FileRemote.CallbackCmd cmd = ev1.getCmd();
1391      String sCmd = cmd.name();
1392      System.out.println("FcmdCopy - callbackCopy;" + sCmd);
1393      switch(ev1.getCmd()){
1394        case start: {
1395          setTexts(Estate.busy);
1396        } break;
1397        case doneCheck:{ ///
1398          //if(listEvCheck.remove(ev)){  ///
1399            FcmdCopyCmprDel.this.evCurrentFile = ev1;
1400            zFiles = ev1.nrofFiles;
1401            zBytes = ev1.nrofBytesAll;
1402            //int nrofPendingFiles = listEvCheck.size();
1403            //if(nrofPendingFiles == 0){
1404              //TODO check dst space
1405              widgCopyState.setText("files:" + zFiles + ", size:" + zBytes);
1406              //widgButtonOk.setText("copy");
1407              //widgButtonOk.setCmd("copy");
1408              //widgButtonSrc.setText("set src");
1409              //widgButtonSrc.setCmd("setSrc");
1410            //}
1411            
1412          //} else {
1413            //unexpected doneCheck:
1414          //}
1415          setTexts(Estate.checked);
1416        } break;
1417        case copyDir:{
1418          FcmdCopyCmprDel.this.evCurrentFile = ev1;
1419          String sPath = StringFunctions.z_StringJc(ev1.fileName);
1420          widgCopyNameDst.setText(sPath);
1421        } break;
1422        case nrofFilesAndBytes:{
1423          FcmdCopyCmprDel.this.evCurrentFile = ev1;
1424          int percent = ev1.promilleCopiedBytes / 10;
1425          widgProgressFile.setValue(percent);
1426          widgProgressAll.setValue(ev1.promilleCopiedFiles / 10);
1427          widgCopyNameDst.setText(StringFunctions.z_StringJc(ev1.fileName));
1428          widgCopyState.setText("... " + ev1.nrofBytesInFile/1000000 + " M / " + ev1.nrofBytesAll + "M / " + ev1.nrofFiles + " Files");
1429        }break;
1430        case askDstOverwr: {
1431          FcmdCopyCmprDel.this.evCurrentFile = ev1;
1432          widgCopyNameDst.setText("exists: " + StringFunctions.z_StringJc(ev1.fileName));
1433          widgSkipFile.setBackColor(GralColor.getColor("am"), 0);
1434          widgOverwrFile.setBackColor(GralColor.getColor("lrd"), 0);
1435        } break;
1436        case askDstReadonly: {
1437            FcmdCopyCmprDel.this.evCurrentFile = ev1;
1438            widgCopyNameDst.setText("read only: " + StringFunctions.z_StringJc(ev1.fileName));
1439            widgSkipFile.setBackColor(GralColor.getColor("am"), 0);
1440            widgOverwrFile.setBackColor(GralColor.getColor("lrd"), 0);
1441        } break;
1442        case askDstNotAbletoOverwr: {
1443          FcmdCopyCmprDel.this.evCurrentFile = ev1;
1444          widgCopyNameDst.setText("can't overwrite: " + StringFunctions.z_StringJc(ev1.fileName));
1445          widgSkipFile.setBackColor(GralColor.getColor("lrd"), 0);
1446          widgOverwrFile.setBackColor(GralColor.getColor("am"), 0);
1447        } break;
1448        case askErrorDstCreate: {
1449          FcmdCopyCmprDel.this.evCurrentFile = ev1;
1450          widgCopyNameDst.setText("can't create: " + StringFunctions.z_StringJc(ev1.fileName));
1451          widgOverwrFile.setBackColor(GralColor.getColor("lrd"), 0);
1452        } break;
1453        case askErrorCopy: {
1454          FcmdCopyCmprDel.this.evCurrentFile = ev1;
1455          widgCopyNameDst.setText("copy error: " + StringFunctions.z_StringJc(ev1.fileName));
1456          widgSkipFile.setBackColor(GralColor.getColor("lrd"), 0);
1457          widgOverwrFile.setBackColor(GralColor.getColor("am"), 0);
1458        } break;
1459        case error: {
1460          FcmdCopyCmprDel.this.evCurrentFile = null;
1461          widgCopyState.setText("error");
1462          setTexts(Estate.error);
1463          eventConsumed(ev, false);
1464        }break;
1465        case nok: {
1466          FcmdCopyCmprDel.this.evCurrentFile = null;
1467          widgCopyState.setText("nok");
1468          setTexts(Estate.error);
1469          eventConsumed(ev, false);
1470        }break;
1471        case done: {
1472          FcmdCopyCmprDel.this.evCurrentFile = null;
1473          widgCopyState.setText("ok: " + ev1.nrofBytesInFile/1000000 + " M / " + ev1.nrofBytesAll + "M / " + ev1.nrofFiles + " Files");
1474          eventConsumed(ev, true);
1475          setTexts(Estate.finit);
1476        }break;
1477        default:
1478          FcmdCopyCmprDel.this.evCurrentFile = ev1;
1479
1480      }
1481      //windConfirmCopy.setWindowVisible(false);
1482      return 1;
1483    }
1484    @Override public String toString(){ return "FcmdCopy-success"; }
1485
1486    
1487  };
1488
1489  
1490 
1491  
1492  /**This event instance with back event and a possible command event as opponent is generally used for invoke and callback to routines
1493   * for file handling. That methods should be execute in another thread. Only one process can be run for one of this window for
1494   * mark, move, copy, compare and delete. Therefore only one event instance is necessary which is reused. 
1495   * For hanging processes there is an "abort" button which sends the abort event at last. Usual the hanging is forced by an
1496   * Exception while handling files or while communication with an device. In that cases the exception had terminate the other process already,
1497   * so the abort command for this event is not used and not necessary. But if the process does not hang and it should be aborted
1498   * that event is essential. 
1499   * <br><br>
1500   * If the event will be reused the "abort" was send for a longer time (at least 1 second for manual handling, pressing buttons). 
1501   * Therefore it can be occupied usual without waiting, at least with thread switch to finish execution of the event.
1502   * See {@link EventCmdPingPongType#occupyRecall(int, EventSource, EventConsumer, org.vishia.event.EventThread, boolean)}  
1503   */
1504  FileRemote.CallbackEvent evCallback = new FileRemote.CallbackEvent(evConsumerCallbackFromFileMachine, null, evSrc); 
1505  
1506
1507  
1508  
1509  FileRemoteCallback callbackFromFilesCheck = new FileRemoteCallback() {
1510    @Override public void start(FileRemote startDir) {  
1511      fileProcessed = null;
1512    }
1513    
1514    @Override public Result offerParentNode(FileRemote file) {
1515      dirProcessed = file;
1516      return Result.cont;      
1517    }
1518    
1519    /**Finish a directory, check whether a file panel should be refreshed.
1520     * @see org.vishia.util.SortedTreeWalkerCallback#finishedParentNode(java.lang.Object, org.vishia.util.SortedTreeWalkerCallback.Counters)
1521     */
1522    @Override public Result finishedParentNode(FileRemote dir, FileRemoteCallback.Counters cnt) {
1523      main.refreshFilePanel(dir);
1524      return Result.cont;      
1525    }
1526    
1527    
1528
1529    @Override public Result offerLeafNode(FileRemote file, Object info) {
1530      boolean bShow = (fileProcessed == null);
1531      //actionShowFilesCmp.fileProcessed = file;
1532      //actionShowFilesCmp.zFiles +=1;
1533      if(bShow){
1534        //actionShowFilesCmp.addToList(widgButtonShowSrc.gralMng().gralDevice.orderList(), 300);
1535      }
1536      return Result.cont;
1537    }
1538
1539    
1540    @Override public boolean shouldAborted(){
1541      return false;
1542    }
1543
1544    @Override public void finished(FileRemote startFile, SortedTreeWalkerCallback.Counters cnt) {  
1545      showFinishState("checked ", cnt);
1546      main.refreshFilePanel(startFile.getParentFile());  //The start file is any file or directory in parent. A directory is refreshed by finishParentNode already.
1547      setTexts(Estate.checked);
1548    }
1549
1550
1551  };
1552  
1553  
1554  
1555  FileRemoteCallback callbackFromFilesExec = new FileRemoteCallback() {
1556    @Override public void start(FileRemote startDir) {  }
1557    
1558    @Override public Result offerParentNode(FileRemote file) {
1559      return Result.cont;      
1560    }
1561    
1562    @Override public Result finishedParentNode(FileRemote dir, FileRemoteCallback.Counters cnt) {
1563      String path = dir.getAbsolutePath();
1564      showFinishState(path, cnt);
1565      main.refreshFilePanel(dir);
1566      return Result.cont;      
1567    }
1568    
1569    
1570
1571    @Override public Result offerLeafNode(FileRemote file, Object info) {
1572      return Result.cont;
1573    }
1574
1575    
1576    @Override public boolean shouldAborted(){
1577      return false;
1578    }
1579
1580    @Override public void finished(FileRemote startFile, SortedTreeWalkerCallback.Counters cnt) {  
1581      showFinishState("done", cnt);
1582      setTexts(Estate.finit);
1583      main.refreshFilePanel(startFile.getParentFile());  //The start file is any file or directory in parent. A directory is refreshed by finishParentNode already.
1584    }
1585
1586    
1587    @Override public String toString(){ return "callbackFromFilesExec"; }
1588
1589  };
1590  
1591  
1592  enum Estate{ inactive, start, checked, busyCheck, busy, quest, error, finit};
1593  
1594  enum Ecmd{ copy, move, delete, compare};
1595  
1596  void stop(){}
1597  
1598}