    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}