001package org.vishia.commander;
002
003import java.io.File;
004import java.util.EventObject;
005import java.util.LinkedList;
006import java.util.List;
007
008import org.vishia.event.EventCmdtype;
009import org.vishia.event.EventCmdtypeWithBackEvent;
010import org.vishia.event.EventConsumer;
011import org.vishia.event.EventSource;
012import org.vishia.fileRemote.FileRemote;
013import org.vishia.gral.base.GralPos;
014import org.vishia.gral.base.GralValueBar;
015import org.vishia.gral.base.GralWidget;
016import org.vishia.gral.base.GralWindow;
017import org.vishia.gral.ifc.GralColor;
018import org.vishia.gral.ifc.GralTextField_ifc;
019import org.vishia.gral.ifc.GralUserAction;
020import org.vishia.gral.ifc.GralWindow_ifc;
021import org.vishia.util.FileSystem;
022import org.vishia.util.KeyCode;
023
024/**This class contains all functionality to execute copy and move for The.file.Commander.
025 * @author Hartmut Schorrig
026 *
027 */
028public class FcmdDelete
029{
030  protected final Fcmd main;
031
032  
033  GralWindow_ifc windConfirmDelete;
034
035  GralTextField_ifc widgDeleteDir, widgDeletePath, widgTrashPath;
036  
037  GralValueBar widgProgress;
038  
039  /**Buttons. */
040  GralWidget widgRemoveToTrash, widgDelete;
041  
042  GralWidget widgButtonOk;
043
044  /**Name of the file which is attempt to delete. */
045  List<FileRemote> listFileDel;
046  
047  /**Content of the widgDeletePath on confirmation invocation, to compare on actionDelete.
048   * If the user does not change the field, the listFileDel is valid.
049   */
050  String sFileDelete;
051 
052  final List<EventCmdtypeWithBackEvent<?,?>> listEvDel = new LinkedList<EventCmdtypeWithBackEvent<?, ?>>();
053
054  
055  /**The file card where the directory content is shown where the file will be deleted.
056   */
057  FcmdFileCard fileCard;
058  
059  FileRemote currentDirWhereDelete;
060  
061  //File dirDelete;
062  
063  EventSource evSrc = new EventSource("FcmdDelete"){
064    
065  };
066  
067  FcmdDelete(Fcmd main)
068  { this.main = main;
069  }
070  
071  /**Builds the content of the confirm-delete window. The window is created static. It is shown
072   * whenever it is used.  */
073  void buildWindowConfirmDelete()
074  { ///
075    main._gralMng.selectPanel("primaryWindow");
076    main._gralMng.setPosition(-22, 0, -47, 0, 1, 'r'); //right buttom, about half less display width and hight.
077    
078    windConfirmDelete = main._gralMng.createWindow("windConfirmDelete", main.idents.windConfirmDelete, GralWindow.windConcurrently);
079    //System.out.println(" window: " + main.gralMng.pos.panel.getPixelPositionSize().toString());
080    
081    main._gralMng.setPosition(4, GralPos.size -3.8f, 1, -1, 0, 'd', 0.2f);
082    widgDeleteDir = main._gralMng.addTextField("deletedirectory", false, "directory", "t");
083    widgDeletePath = main._gralMng.addTextField("deletePath", true, "delete (Note: path/*.ext or path/file* possible)", "t");
084    
085    //main.gralMng.setPosition(12, GralPos.size -3.5f, 1, -1, 0, 'd');
086    widgTrashPath = main._gralMng.addTextField("deleteTrashPath", true, "trash path (Note: left empty to delete forever)", "t");
087    
088    main._gralMng.setPosition(-6, GralPos.size +1, 7, -11, 0, 'd', 1);
089    //widgProgressFile = main.gralMng.addValueBar("copyProgressFile", null, null);
090    widgProgress = main._gralMng.addValueBar("copyProgressAll", null);
091    main._gralMng.setPosition(-4, -1, 1, 6, 0, 'r');
092    main._gralMng.addButton("deleteEsc", actionDelete, "esc", null, "esc");
093    main._gralMng.setPosition(-1, GralPos.size-3, -19,-11, 0, 'r');
094    widgRemoveToTrash = main._gralMng.addButton("deleteToTrash", actionDelete, "trash", null,  "trash");
095    main._gralMng.setPosition(-1, GralPos.size-3, -9, -1, 0, 'r');
096    widgButtonOk = main._gralMng.addButton("deleteOk", actionDelete, "delete", null,  "delete");
097    widgButtonOk.setPrimaryWidgetOfPanel();
098  }
099  
100  
101  
102  /**Opens the confirm-delete window and fills its fields to ask the user whether confirm.
103   * @param src The path which is selected as source. It may be a directory or a file.
104   */
105  void confirmDelete(File src111)
106  { fileCard = main.getLastSelectedFileCards()[0];
107    sFileDelete = null;
108    currentDirWhereDelete = fileCard.currentDir();
109    if(fileCard !=null){
110      listFileDel = fileCard.getSelectedFiles(true, 1);
111      int nrofFilesDel = listFileDel.size();
112      if(nrofFilesDel >1){
113        sFileDelete = "" + nrofFilesDel + " Files";
114        for(FileRemote file: listFileDel){
115          sFileDelete += " : " + file.getName();
116        }
117      } else if(nrofFilesDel >0){
118        FileRemote file = listFileDel.get(0);
119        sFileDelete = file.getName();
120      } else {
121        sFileDelete = "??No files";
122      }
123      if(sFileDelete == null){ //NOTE: 
124        sFileDelete = "--no files selected--";
125      }
126      widgDeleteDir.setText(FileSystem.getCanonicalPath(currentDirWhereDelete));
127      widgDeletePath.setText(sFileDelete);
128      widgTrashPath.setText("TODO");
129    }
130    else {
131      widgDeleteDir.setText("??No filecard active");
132      widgDeletePath.setText("?? abort");
133    }
134    windConfirmDelete.setFocus(); //WindowVisible(true);
135    
136
137  }
138  
139
140  /**
141   * Key F8 for delete command. Its like Norton Commander.
142   */
143  GralUserAction actionConfirmDelete = new GralUserAction("actionConfirmDelete")
144  {
145    @Override
146    public boolean userActionGui(int keyCode, GralWidget infos, Object... params)
147    {
148      FileRemote fileSrc = main.lastFilePanels.get(0).actFileCard.currentFile();
149      confirmDelete(fileSrc);
150      return true;
151      // /
152    }
153  };
154
155  
156  GralUserAction actionDelete = new GralUserAction("actionDelete")
157  { @Override public boolean userActionGui(int key, GralWidget widgg, Object... params)
158    { try{ 
159        if(KeyCode.isControlFunctionMouseUpOrMenu(key)){
160          if(widgg.sCmd.equals("delete")){
161            String sPathDelete = widgDeletePath.getText().trim();
162            if(sPathDelete.equals(sFileDelete)){  
163              //no user changing:
164              if(!sPathDelete.equals("--no files selected--")){
165                for(FileRemote file : listFileDel){
166                  if(file !=null){
167                    if(!file.canWrite()){
168                      //file.setWritable();
169                    }
170                    FileRemote.CallbackEvent callback = new FileRemote.CallbackEvent(evSrc, file
171                        , null, success, null,  evSrc);  //NOTE: store file as src to get its name for report in callback.
172                    listEvDel.add(callback);
173                    //
174                    //The delete action:
175                    if(file instanceof FileRemote){
176                      (file).delete(callback);
177                    } else {
178                      if(!file.delete()){
179                        file.setWritable(true);
180                        file.delete();
181                      }
182                    }
183                  }
184                  //      
185                }
186              }
187            } else { //user has changed the path
188              FileRemote dirRemote = currentDirWhereDelete;
189              FileRemote.CallbackEvent callback = new FileRemote.CallbackEvent(evSrc, dirRemote, null, success, null, evSrc);  
190              dirRemote.delete(sPathDelete, true, callback);
191            }
192          } else if(widgg.sCmd.equals("esc")){
193            windConfirmDelete.setWindowVisible(false);
194          }
195        }
196      } catch(Exception exc){ main._gralMng.log.sendMsg(0, "FcmdDelete-actionDelete"); }
197      return true;
198    }
199  };
200
201  
202  
203  EventConsumer success = new EventConsumer(){
204    @Override public int processEvent(EventObject ev)
205    { FileRemote.CallbackEvent callback = (FileRemote.CallbackEvent)ev;
206      if(callback.successCode !=0){
207        main.mainCmd.writeError("can't delete " + callback.getFileSrc().getCanonicalPath());
208      }
209      listEvDel.remove(ev);
210      int nrofPendingFiles = listEvDel.size();
211      int percent = nrofPendingFiles * 100 / listFileDel.size();
212      widgProgress.setValue(percent);
213      if(nrofPendingFiles == 0){
214        windConfirmDelete.setWindowVisible(false);      
215      }
216      fileCard.fillInCurrentDir();
217      return 1;
218    }
219
220     @Override public String toString(){ return "FcmdDelete - success"; }
221
222  };
223  
224  //XX Event evSuccess = new Event(this, success);
225  
226  
227  
228}