001package org.vishia.commander; 002 003import java.io.BufferedReader; 004import java.io.ByteArrayInputStream; 005import java.io.File; 006import java.io.IOException; 007import java.io.InputStream; 008import java.io.InputStreamReader; 009import java.nio.ByteBuffer; 010import java.nio.CharBuffer; 011import java.nio.channels.ReadableByteChannel; 012import java.nio.channels.WritableByteChannel; 013import java.nio.charset.Charset; 014 015import org.vishia.fileRemote.FileRemote; 016import org.vishia.gral.base.GralTextBox; 017import org.vishia.gral.base.GralWidget; 018import org.vishia.gral.base.GralWindow; 019import org.vishia.gral.ifc.GralColor; 020import org.vishia.gral.ifc.GralUserAction; 021import org.vishia.gral.ifc.GralWindow_ifc; 022import org.vishia.util.KeyCode; 023import org.vishia.util.StringFormatter; 024 025/**All functionality of view (F3-Key) and quick view. 026 * @deprecated. The {@link FcmdView} have more capabilities. It contains adequates. 027 * @author Hartmut Schorrig 028 * */ 029public class FcmdEdit 030{ 031 protected final Fcmd main; 032 033 /**The window of this functionallity. */ 034 private GralWindow_ifc windView; 035 036 /**The widget to show content. */ 037 private GralTextBox widgContent; 038 039 /**A buffer to get bytes from the file using the java.nio.Channel mechanism. 040 * The channel mechanism is proper to work with remote file access especially. 041 * Note: The ByteBuffer may be a part of the channel mechanism itself, because it is placed JVM-internally, 042 * for example for socket communication. TODO check and change it. 043 */ 044 private final ByteBuffer byteBuffer = ByteBuffer.allocate(1200); 045 046 /**Number of read bytes. */ 047 private int nrofBytes; 048 049 050 /**The gotten bytes from bytebuffer. */ 051 private byte[] buffer = new byte[1200]; 052 053 054 //private byte[] outBuffer = new byte[20000]; 055 056 /**The current choiced view format. 057 * <ul> 058 * <li>a: us-ascii-text 059 * <li>w: iso (Windows)-text 060 * <li>u: UTF16-text 061 * <li>1: Hexa byte wise 062 * <li>2: Hexa 16-bit-words 063 * <li>4: Hexa 32-bit-words 064 * <li>F: contains, float values, shows it 065 * </ul> 066 */ 067 private final char format = 't'; 068 069 070 private static Charset ascii7 = Charset.forName("US-ASCII"); 071 072 private static Charset utf8 = Charset.forName("UTF8"); 073 074 075 /**Instance to prepare the text especially for hex view. */ 076 private final StringFormatter formatterHex = new StringFormatter(120); 077 078 public FcmdEdit(Fcmd main) 079 { this.main = main; 080 } 081 082 083 /**Builds the content of the confirm-delete window. The window is created static. It is shown 084 * whenever it is used. */ 085 void buildWindow() 086 { 087 main._gralMng.selectPanel("primaryWindow"); 088 main._gralMng.setPosition(10, 0, 10, 0, 1, 'r'); //right buttom, about half less display width and hight. 089 int windProps = GralWindow.windConcurrently | GralWindow.windHasMenu; 090 GralWindow wind = main._gralMng.createWindow("windView", "view - The.file.Commander", windProps); 091 wind.addMenuBarItemGThread("view-Search", "&Edit/&Search", actionOpenEdit); 092 wind.addMenuBarItemGThread("view-Search", "&Edit/set &Writeable", actionOpenEdit); 093 wind.addMenuBarItemGThread("view-Search", "&View/&Hex-Byte", actionOpenEdit); 094 wind.addMenuBarItemGThread("view-Search", "&View/text-&Windows", actionOpenEdit); 095 wind.addMenuBarItemGThread("view-Search", "&View/text-&UTF", actionOpenEdit); 096 wind.addMenuBarItemGThread("view-Search", "&View/text-&ASCII-7", actionOpenEdit); 097 wind.addMenuBarItemGThread("view-Search", "&View/text-&Encoding", actionOpenEdit); 098 wind.addMenuBarItemGThread(null, "&Save-as/UTF8-Unix-lf", actionConvertUTF8unix); 099 main._gralMng.setPosition(0, 0, 0, 0, 1, 'r'); 100 widgContent = main._gralMng.addTextBox("view-content", false, null, '.'); 101 widgContent.setTextStyle(GralColor.getColor("bk"), main._gralMng.propertiesGui.getTextFont(2.0f, 'm', 'n')); 102 windView = wind; 103 windView.setWindowVisible(false); 104 //windView1. 105 } 106 107 108 109 110 /**Opens the view window and fills its content. 111 * @param src The path which is selected as source. It may be a directory or a file. 112 */ 113 void openEdit(FileRemote src) 114 {if(src !=null){ 115 long len = src.length(); 116 if(len > 1000000){ len = 1000000; } //nor more than 1MByte, 117 buffer = new byte[(int)len]; 118 int iBuffer = 0; 119 ReadableByteChannel reader = src.openRead(0); 120 try{ 121 if(reader == null){ 122 widgContent.setText("File is not able to read:\n"); 123 widgContent.append(src.getAbsolutePath()); 124 } else { 125 do{ 126 byteBuffer.clear(); 127 nrofBytes = reader.read(byteBuffer); 128 if(nrofBytes >0){ 129 byteBuffer.rewind(); 130 byteBuffer.get(buffer, iBuffer, nrofBytes); 131 iBuffer += nrofBytes; 132 } 133 } while(nrofBytes >0); 134 reader.close(); 135 //byteBuffer.rewind(); 136 presentContent(); 137 } 138 } catch(IOException exc){ 139 if(reader !=null) { try{ reader.close(); } catch(IOException exc1){}} 140 } 141 } 142 windView.setFocus(); //WindowVisible(true); 143 144 } 145 146 147 148 149 void presentContent() throws IOException 150 { 151 widgContent.setText("file ...\n"); 152 presentContentHex(); 153 } 154 155 156 157 void presentContentHex() throws IOException 158 { 159 try{ 160 //byteBuffer.get(buffer); 161 for(int ii = 0; ii < 16 && ii < buffer.length /16; ++ii){ 162 formatterHex.reset(); 163 formatterHex.addHex(ii, 4).add(": "); 164 formatterHex.addHexLine(buffer, 16*ii, 16, StringFormatter.k1); 165 formatterHex.add(" ").addStringLine(buffer, 16*ii, 16, ascii7.name()); 166 widgContent.append(formatterHex.getContent()).append('\n'); 167 } 168 } catch(Exception exc){ 169 widgContent.append(exc.getMessage()); 170 } 171 } 172 173 174 175 void presentContentText() throws IOException 176 { 177 178 CharBuffer tContent = ascii7.decode(byteBuffer); 179 try{ 180 do{ 181 char cc = tContent.get(); 182 widgContent.append(cc); 183 } while(true); 184 } catch(Exception exc){ 185 widgContent.append('?'); 186 } 187 } 188 189 190 /**Action for Key F3 for view command. Its like Norton Commander. 191 */ 192 GralUserAction actionOpenEdit = new GralUserAction("actionOpenEdit") 193 { 194 @Override public boolean userActionGui(int key, GralWidget infos, Object... params) 195 { if(key == KeyCode.mouse1Up || key == KeyCode.menuEntered){ 196 openEdit(main.currentFile()); 197 return true; 198 } else return false; 199 // / 200 } 201 }; 202 203 204 GralUserAction actionConvertUTF8unix = new GralUserAction("actionConvertUTF8unix") 205 { 206 @Override public boolean userActionGui(int keyCode, GralWidget infos, Object... params) 207 { 208 try{ 209 InputStream inpBytes = new ByteArrayInputStream(buffer); 210 InputStreamReader inpText = new InputStreamReader(inpBytes); 211 BufferedReader inpLines = new BufferedReader(inpText); 212 FileRemote filedst = main.currentFile(); 213 WritableByteChannel outchn =filedst.openWrite(0); 214 ByteBuffer outBuffer = ByteBuffer.allocate(1200); 215 //Writer out = new FileWriter(); 216 String sLine; 217 do{ 218 sLine = inpLines.readLine(); 219 if(sLine !=null){ 220 byte[] bytes = sLine.getBytes(utf8); 221 if(outBuffer.remaining() < bytes.length+1){ 222 outBuffer.rewind(); 223 outchn.write(outBuffer); 224 outBuffer.clear(); 225 } 226 int posBytes = 0; 227 int zOutBuffer; 228 while( (zOutBuffer = outBuffer.remaining()) < (bytes.length - posBytes +1)){ 229 outBuffer.put(bytes, posBytes, zOutBuffer); 230 outBuffer.rewind(); 231 outchn.write(outBuffer); 232 outBuffer.clear(); 233 posBytes += zOutBuffer; 234 } 235 outBuffer.put(bytes, posBytes, bytes.length - posBytes) 236 .put((byte)0x0a); 237 //outText.append(sLine).append('\n'); 238 } 239 } while(sLine !=null); 240 outBuffer.rewind(); 241 outchn.write(outBuffer); 242 outBuffer.clear(); 243 outchn.close(); 244 245 } catch(Exception exc){ 246 main._gralMng.writeLog(0, exc); 247 } 248 return true; 249 // / 250 } 251 }; 252 253 254 255}