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}