Package net.sourceforge.squirrel_sql.fw.datasetviewer

Source Code of net.sourceforge.squirrel_sql.fw.datasetviewer.PopupEditableIOPanel$LineWrapAction

package net.sourceforge.squirrel_sql.fw.datasetviewer;
/*
* Copyright (C) 2001 Colin Bell
* colbell@users.sourceforge.net
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.BinaryDisplayConverter;
import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.CellComponentFactory;
import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.RestorableJTextArea;
import net.sourceforge.squirrel_sql.fw.gui.TextPopupMenu;
import net.sourceforge.squirrel_sql.fw.gui.action.BaseAction;
import net.sourceforge.squirrel_sql.fw.util.IOUtilities;
import net.sourceforge.squirrel_sql.fw.util.IOUtilitiesImpl;
import net.sourceforge.squirrel_sql.fw.util.StringManager;
import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;

/**
* @author gwg
*
* Class to handle IO between user and editable text, text and object,
* and text/object to/from file.
*/
public class PopupEditableIOPanel extends JPanel implements ActionListener {

    private static final long serialVersionUID = 1L;

    private static final StringManager s_stringMgr =
    StringManagerFactory.getStringManager(PopupEditableIOPanel.class);

  // The text area displaying the object contents
  private final JTextArea _ta;

  // the scroll pane that holds the text area
  private final JScrollPane scrollPane;

  // Description needed to handle conversion of data to/from Object
  transient private final ColumnDisplayDefinition _colDef;

  transient private MouseAdapter _lis;

  private final TextPopupMenu _popupMenu;

  // name of file to do export/import/process on
  private JTextField fileNameField;

  // command to use when processing data with an external program
  private JComboBox externalCommandCombo;

  // save the original value for re-use by CLOB/BLOB types in conversion
  private Object originalValue;

  // Binary data viewing option: which radix to use
  // This object is only non-null when the data is binary data
  private JComboBox radixList = null;
  private String previousRadixListItem = null;
  // Binary data viewing option: view ascii as char rather than as numeric value
  private JCheckBox showAscii = null;
  private boolean previousShowAscii;

  private IOUtilities _iou = new IOUtilitiesImpl()
 
  class BinaryOptionActionListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {

      // user asked to see binary data in a different format
      int base = 16// default to hex
      if (previousRadixListItem.equals("Decimal")) base = 10;
      else if (previousRadixListItem.equals("Octal")) base = 8;
      else if (previousRadixListItem.equals("Binary")) base = 2;

      Byte[] bytes = BinaryDisplayConverter.convertToBytes(_ta.getText(),
        base, previousShowAscii);

      // return the expected format for this data
      base = 16// default to hex
      if (radixList.getSelectedItem().equals("Decimal")) base = 10;
      else if (radixList.getSelectedItem().equals("Octal")) base = 8;
      else if (radixList.getSelectedItem().equals("Binary")) base = 2;

      ((RestorableJTextArea)_ta).updateText(
        BinaryDisplayConverter.convertToString(bytes,
        base, showAscii.isSelected()));

      previousRadixListItem = (String)radixList.getSelectedItem();
      previousShowAscii = showAscii.isSelected();

      return;
    }
  }
  transient private BinaryOptionActionListener optionActionListener =
    new BinaryOptionActionListener();

  // text put in file name field to indicate that we should
  // create a temp file for export
  private final String TEMP_FILE_FLAG = "<temp file>";

  // Symbol used by user in Command field to indicate
  // "Put the file name here" when the command is executed.
  private final String FILE_REPLACE_FLAG = "%f";

  /**
   * Constructor
   */
  public PopupEditableIOPanel(ColumnDisplayDefinition colDef,
                     Object value, boolean isEditable) {

    originalValue = value;  // save for possible future use

    _popupMenu = new TextPopupMenu();

    _colDef = colDef;
    _ta = CellComponentFactory.getJTextArea(colDef, value);

    if (isEditable) {
      _ta.setEditable(true);
      _ta.setBackground(Color.yellow)// tell user it is editable
    }
    else {
      _ta.setEditable(false);
    }


    _ta.setLineWrap(true);
    _ta.setWrapStyleWord(true);

    setLayout(new BorderLayout());

    // add a panel containing binary data editing options, if needed
    JPanel displayPanel = new JPanel();
    displayPanel.setLayout(new BorderLayout());
    scrollPane = new JScrollPane(_ta);
    /*
     * TODO: When 1.4 is the earliest version supported, include
     * the following line here:
     *   scrollPane.setWheelScrollingEnabled(true);
     * The scroll-wheel function is important for ease of use, but the
     * setWheelScrollingEnabled function is not available in java 1.3.
     */

    displayPanel.add(scrollPane, BorderLayout.CENTER);
    if (CellComponentFactory.useBinaryEditingPanel(colDef)) {
      // this is a binary field, so allow for multiple viewing options

      String[] radixListData = { "Hex", "Decimal", "Octal", "Binary" };
      radixList = new JComboBox(radixListData);
      radixList.addActionListener(optionActionListener);
      previousRadixListItem = "Hex";

      showAscii = new JCheckBox();
      previousShowAscii = false;
      showAscii.addActionListener(optionActionListener);

      JPanel displayControlsPanel = new JPanel();
      // use default sequential layout

      // i18n[popupeditableIoPanel.numberBase=Number Base:]
      displayControlsPanel.add(new JLabel(s_stringMgr.getString("popupeditableIoPanel.numberBase")));
      displayControlsPanel.add(radixList);
      displayControlsPanel.add(new JLabel("    "))// add some space
      displayControlsPanel.add(showAscii);
      // i18n[popupeditableIoPanel.showAscii=Show ASCII as chars]
      displayControlsPanel.add(new JLabel(s_stringMgr.getString("popupeditableIoPanel.showAscii")));
      displayPanel.add(displayControlsPanel, BorderLayout.SOUTH);
    }
    add(displayPanel, BorderLayout.CENTER);

    // add controls for file handling, but only if DataType
    // can do File operations
    if (CellComponentFactory.canDoFileIO(colDef)) {
      // yes it can, so add controls
      add(exportImportPanel(isEditable), BorderLayout.SOUTH);
    }

    _popupMenu.add(new LineWrapAction());
    _popupMenu.add(new WordWrapAction());
    _popupMenu.add(new XMLReformatAction());
    _popupMenu.setTextComponent(_ta);
  }

  /**
   * build the user interface for export/import operations
   */
  private JPanel exportImportPanel(boolean isEditable) {
    JPanel eiPanel = new JPanel();
    eiPanel.setLayout(new GridBagLayout());

    final GridBagConstraints gbc = new GridBagConstraints();

    gbc.insets = new Insets(4,4,4,4);
    gbc.gridx = 0;
    gbc.gridy = 0;

    // File handling controls
    // i18n[popupeditableIoPanel.useFile=Use File: ]
    eiPanel.add(new JLabel(s_stringMgr.getString("popupeditableIoPanel.useFile")), gbc);


    fileNameField = new JTextField(TEMP_FILE_FLAG, 19);
    gbc.gridx++;
    eiPanel.add(fileNameField, gbc);


    // add button for Brows
    // i18n[popupeditableIoPanel.browse=Browse]
    JButton browseButton = new JButton(s_stringMgr.getString("popupeditableIoPanel.browse"));
    browseButton.setActionCommand("browse");
    browseButton.addActionListener(this);


    gbc.gridx++;
    eiPanel.add(browseButton, gbc);


    // i18n[popupeditableIoPanel.export44=Export]
    JButton exportButton = new JButton(s_stringMgr.getString("popupeditableIoPanel.export44"));
    exportButton.setActionCommand("export");
    exportButton.addActionListener(this);

    gbc.gridx++;
    eiPanel.add(exportButton, gbc);

    // import and external processing can only be done if
    // panel is editable
    if ( isEditable == false)
      return eiPanel;

    // Add import control
    // i18n[popupeditableIoPanel.import44=Import]
    JButton importButton = new JButton(s_stringMgr.getString("popupeditableIoPanel.import44"));
    importButton.setActionCommand("import");
    importButton.addActionListener(this);

    gbc.gridx++;
    eiPanel.add(importButton, gbc);

    // add external processing command field and button
    gbc.gridy++;
    gbc.gridx = 0;
    // i18n[popupeditableIoPanel.withCommand=With command:]
    eiPanel.add(new JLabel(s_stringMgr.getString("popupeditableIoPanel.withCommand")), gbc);

    // add combo box for command to execute
    gbc.gridx++;
    externalCommandCombo = new JComboBox(
      CellImportExportInfoSaver.getInstance().getCmdList());
    externalCommandCombo.setSelectedIndex(-1)// no entry selected
    externalCommandCombo.setEditable(true);

    // make this the same size as the fileNameField
    externalCommandCombo.setPreferredSize(fileNameField.getPreferredSize());

    eiPanel.add(externalCommandCombo, gbc);

    // add button to execute external command
    // i18n[popupeditableIoPanel.execute34=Execute]
    JButton externalCommandButton = new JButton(s_stringMgr.getString("popupeditableIoPanel.execute34"));
    externalCommandButton.setActionCommand("execute");
    externalCommandButton.addActionListener(this);

    gbc.gridx++;
    eiPanel.add(externalCommandButton, gbc);

    // add button for applying file & cmd info without doing anything else
    // i18n[popupeditableIoPanel.applyFile=Apply File & Cmd]
    JButton applyButton = new JButton(s_stringMgr.getString("popupeditableIoPanel.applyFile"));
    applyButton.setActionCommand("apply");
    applyButton.addActionListener(this);

    gbc.gridx++;
    gbc.gridwidth = 2;
    eiPanel.add(applyButton, gbc);
    gbc.gridwidth = 1// reset width to normal 

    // add note to user about including file name in command
    gbc.gridy++;
    gbc.gridx = 0;
    gbc.gridwidth = GridBagConstraints.REMAINDER;


    // i18n[popupeditableIoPanel.replaceFile=(In command, the string {0} is replaced by the file name when Executed.)]
    eiPanel.add(new JLabel(s_stringMgr.getString("popupeditableIoPanel.replaceFile", FILE_REPLACE_FLAG)), gbc);

    // load filename and command with previously entered info
    // if not the default
    CellImportExportInfo info =
      CellImportExportInfoSaver.getInstance().get(_colDef.getFullTableColumnName());
    if (info != null) {
      // load the info into the text fields
      fileNameField.setText(info.getFileName());
      externalCommandCombo.getEditor().setItem(info.getCommand());
    }

    return eiPanel;
  }


  /**
   * Return the contents of the editable text area as an Object
   * converted by the correct DataType function.  Errors in converting
   * from the text form into the Object are reported
   * through the messageBuffer.
   */
  public Object getObject(StringBuffer messageBuffer) {
    String text = null;
    try {
      text = getTextAreaCannonicalForm();
    }
    catch (Exception e) {
      messageBuffer.append(
        "Failed to convert binary text; error was:\n"+e.getMessage());
      return null;
    }
    return CellComponentFactory.validateAndConvertInPopup(_colDef,
          originalValue, text, messageBuffer);
  }

  /**
   * When focus is passed to this panel, automatically pass it
   * on to the text area.
   */
  public void requestFocus() {
    _ta.requestFocus();
  }

  /**
   * Handle actions on the buttons in the file operations panel
   */
  public void actionPerformed(ActionEvent e) {

    //File object for doing IO
    File file;

    if (e.getActionCommand().equals("browse")) {
      JFileChooser chooser = new JFileChooser();
      String filename = fileNameField.getText();
            if (filename != null && !"".equals(filename)) {
                File f = new File(filename);
                String path = f.getAbsolutePath();
                if (path != null && !"".equals(path)) {
                    chooser.setCurrentDirectory(new File(path));
                }
            }
      int returnVal = chooser.showOpenDialog(this);
      if(returnVal == JFileChooser.APPROVE_OPTION) {
        //  System.out.println("You chose to open this file: " +
        //    chooser.getSelectedFile().getName());
        try {
          fileNameField.setText(chooser.getSelectedFile().getCanonicalPath());
        }
        catch (Exception ex) {
          // should not happen since the file that was selected was
          // just being shown in the Chooser dialog, but just to be safe...
          JOptionPane.showMessageDialog(this,
            // i18n[popupeditableIoPanel.errorGettingPath=Error getting full path name for selected file]
            s_stringMgr.getString("popupeditableIoPanel.errorGettingPath"),
            // i18n[popupeditableIoPanel.fileChooserError=File Chooser Error]
            s_stringMgr.getString("popupeditableIoPanel.fileChooserError"),JOptionPane.ERROR_MESSAGE);
        }
      }
    }

    else if (e.getActionCommand().equals("apply")) {
      // If file name default and cmd is null or empty,
      // make sure this entry is not being held in CellImportExportInfoSaver
      if ( (fileNameField.getText() != null &&
          fileNameField.getText().equals(TEMP_FILE_FLAG)) &&
        (externalCommandCombo.getEditor().getItem() == null ||
          ((String)externalCommandCombo.getEditor().getItem()).length() == 0)) {
        // user has not entered anything or has reset to defaults,
        // so make sure there is no entry for this column in the
        // saved info
        CellImportExportInfoSaver.remove(_colDef.getFullTableColumnName());
      }
      else {
        // user has entered some non-default info, so save it
        CellImportExportInfoSaver.getInstance().save(
          _colDef.getFullTableColumnName(),fileNameField.getText(),
          ((String)externalCommandCombo.getEditor().getItem()));
      }

    }

     else if (e.getActionCommand().equals("import")) {

       // IMPORT OBJECT FROM OSX_FILE

       if (fileNameField.getText() == null ||
         fileNameField.getText().equals(TEMP_FILE_FLAG)) {
         // not allowed - must have existing file for import
         JOptionPane.showMessageDialog(this,
           // i18n[popupeditableIoPanel.selectImportDataFile=You must select an existing file to import data from.]
            s_stringMgr.getString("popupeditableIoPanel.selectImportDataFile"),
           // i18n[popupeditableIoPanel.noFile=No File Selected]
            s_stringMgr.getString("popupeditableIoPanel.noFile"),JOptionPane.ERROR_MESSAGE);
        return// do not do import
       }

       // get name of file, which must exist
      if (fileNameField.getText() == null)
        fileNameField.setText("")// guard against something really stupid
      file = new File(fileNameField.getText());
      if ( ! file.exists() || ! file.isFile() || ! file.canRead()) {
        // not something we can read

        // i18n[popupeditableIoPanel.fileDoesNotExist=File {0} does not exist,\nor is not a readable, normal file.\nPlease enter a valid file name or use Browse to select a file.]
        String msg = s_stringMgr.getString("popupeditableIoPanel.fileDoesNotExist", fileNameField.getText());

         JOptionPane.showMessageDialog(this, msg,

            // i18n[popupeditableIoPanel.fileError=File Name Error]
            s_stringMgr.getString("popupeditableIoPanel.fileError"),JOptionPane.ERROR_MESSAGE);
        return// do not do import
      }

      // Now that we have the file, do the import.
      //
      // Note: the sequence of operations is divided into two sections
      // at this point.  The preceeding code ensures that we have
      // a readable file, and the code in the following method call
      // does the import.  The reason for splitting at this point is
      // that the Execute operation needs to do an import, and it will
      // already have the file to do the import from (which is the same
      // as the file it exported into).
      importData(file);

      // save the user options - we know that it is not the default
      // because we do not allow importing from "temp file"
      CellImportExportInfoSaver.getInstance().save(
        _colDef.getFullTableColumnName(), fileNameField.getText(),
        ((String)externalCommandCombo.getEditor().getItem()));

     }

    else {

      // GET OSX_FILE FOR EXPORT & EXTERNAL PROCESSING

      String canonicalFilePathName = fileNameField.getText();

      // file name verification operations are the same for both
      // export and execute, so do that work here for both.
      //
      // If file name is null or empty, do not proceed
      if (fileNameField.getText() == null ||
        fileNameField.getText().equals("")) {

        JOptionPane.showMessageDialog(this,

          // i18n[popupeditableIoPanel.noExportFile=No file name given for export.\nPlease enter a file name  or use Browse before clicking Export.]
          s_stringMgr.getString("popupeditableIoPanel.noExportFile"),
          // i18n[popupeditableIoPanel.exportError=Export Error]
          s_stringMgr.getString("popupeditableIoPanel.exportError"),JOptionPane.ERROR_MESSAGE);
        return;
      }

      // create the file to open
      if (fileNameField.getText().equals(TEMP_FILE_FLAG)) {
        // user wants us to create a temp file
        try {
          file = File.createTempFile("squirrel", ".tmp");

          // get the real name for use later
          canonicalFilePathName = file.getCanonicalPath();
        }
        catch (Exception ex) {
          JOptionPane.showMessageDialog(this,
            // i18n[popupeditableIoPanel.cannotCreateTempFile=Cannot create temp file..\nError was:\n{0}]
            s_stringMgr.getString("popupeditableIoPanel.cannotCreateTempFile", ex.getMessage()),
            // i18n[popupeditableIoPanel.exportError2=Export Error]
            s_stringMgr.getString("popupeditableIoPanel.exportError2"),
            JOptionPane.ERROR_MESSAGE);
          return;
        }
      }
      else {
        //user must have supplied a file name.
        file = new File(fileNameField.getText());

        try {
          canonicalFilePathName = file.getCanonicalPath();
        }
        catch (Exception ex) {
          // an error here may mean that the file cannot be
          // reached or has moved or some such.  In any case,
          // the file cannot be used for export.
          JOptionPane.showMessageDialog(this,
            // i18n[popupeditableIoPanel.cannotAccessFile=Cannot access file name {0}\nAborting export.]
            s_stringMgr.getString("popupeditableIoPanel.cannotAccessFile", fileNameField.getText()),

            // i18n[popupeditableIoPanel.exportError3=Export Error]
            s_stringMgr.getString("popupeditableIoPanel.exportError3"),JOptionPane.ERROR_MESSAGE);
            return;
        }

        // see if file exists
        if (file.exists()) {
          if ( ! file.isFile()) {
            JOptionPane.showMessageDialog(this,
              // i18n[popupeditableIoPanel.notANormalFile=File is not a normal file.\n Cannot do export to a directory or system file.]
              s_stringMgr.getString("popupeditableIoPanel.notANormalFile"),
              // i18n[popupeditableIoPanel.exportError4=Export Error]
              s_stringMgr.getString("popupeditableIoPanel.exportError4"),JOptionPane.ERROR_MESSAGE);
            return;
          }
          if ( ! file.canWrite()) {
            JOptionPane.showMessageDialog(this,
              // i18n[popupeditableIoPanel.notWriteable=File is not writeable.\nChange file permissions or select a differnt file for export.]
              s_stringMgr.getString("popupeditableIoPanel.notWriteable"),
              // i18n[popupeditableIoPanel.exportError5=Export Error]
              s_stringMgr.getString("popupeditableIoPanel.exportError5"),JOptionPane.ERROR_MESSAGE);
            return;
          }
          // file exists, is normal and is writable, so see if user
          // wants to overwrite contents of file
          int option = JOptionPane.showConfirmDialog(this,
            // i18n[popupeditableIoPanel.fileOverwrite=File {0} already exists.\n\nDo you wish to overwrite this file?]
            s_stringMgr.getString("popupeditableIoPanel.fileOverwrite", canonicalFilePathName),
            // i18n[popupeditableIoPanel.overwriteWarning=File Overwrite Warning]
              s_stringMgr.getString("popupeditableIoPanel.overwriteWarning"), JOptionPane.YES_NO_OPTION);
          if (option != JOptionPane.YES_OPTION) {
            // user does not want to overwrite the file

            // we could tell user here that export was canceled,
            // but I don't think its necessary, and that avoids
            // forcing user to do yet another annoying mouse click.
            return;
          }
          // user is ok with overwriting file
          // We do not need to do anything special to overwrite
          // (as opposed to appending) since the OutputString
          // starts at the beginning of the file by default.
        }
        else {
          // file does not already exist, so try to create it
          try {
            if ( ! file.createNewFile()) {
              JOptionPane.showMessageDialog(this,
                // i18n[popupeditableIoPanel.createFileError=Failed to create file {0}.\nChange file name or select a differnt file for export.]
                s_stringMgr.getString("popupeditableIoPanel.createFileError", canonicalFilePathName),
                // i18n[popupeditableIoPanel.exportError6=Export Error]
                s_stringMgr.getString("popupeditableIoPanel.exportError6"),JOptionPane.ERROR_MESSAGE);
              return;
            }
          }
          catch (Exception ex) {

            Object[] args = new Object[]{canonicalFilePathName, ex.getMessage()};
            JOptionPane.showMessageDialog(this,
              // i18n[popupeditableIoPanel.cannotOpenFile=Cannot open file {0}.\nError was:{1}]
              s_stringMgr.getString("popupeditableIoPanel.cannotOpenFile", args),
              // i18n[popupeditableIoPanel.exportError7=Export Error]
              s_stringMgr.getString("popupeditableIoPanel.exportError7"),JOptionPane.ERROR_MESSAGE);
            return;
          }
        }
      }

      // at this point we have an actual file that we can output to,
      // so create the output stream
      // (so that data type objects do not have to).

      // We have done everything we can prior to this point
      // to ensure that the the file is accessible, but it is
      // still possible that an existing file was removed
      // at a bad moment.  Also, the compiler insists that we
      // put this in a try statement
      FileOutputStream outStream;
      try {
        outStream = new FileOutputStream(file);
      }
      catch (Exception ex) {
        JOptionPane.showMessageDialog(this,
          // i18n[popupeditableIoPanel.cannotFindFile=Cannot find file {0}\nCheck file name and re-try export.]
          s_stringMgr.getString("popupeditableIoPanel.cannotFindFile", canonicalFilePathName),
          // i18n[popupeditableIoPanel.exportError8=Export Error]
          s_stringMgr.getString("popupeditableIoPanel.exportError8"),JOptionPane.ERROR_MESSAGE);
        return;
      }

            String extCmdComboItemStr = null;
            if (externalCommandCombo != null
                    && externalCommandCombo.getEditor() != null)
            {
                extCmdComboItemStr =
                    (String)externalCommandCombo.getEditor().getItem();
            }
           
      // if user did anything other than default, then save
      // their options
      if ( ! TEMP_FILE_FLAG.equals(fileNameField.getText())
                    || (extCmdComboItemStr != null
                            && extCmdComboItemStr.length() > 0)) {

        // This may be called either when the table is editable or when it is
        // read-only.  When it is read-only, there is no command to be saved,
        // but when it is editable, there may be a command.
        String commandString = extCmdComboItemStr;

        CellImportExportInfoSaver.getInstance().save(
          _colDef.getFullTableColumnName(), fileNameField.getText(),
          commandString);
      }

      if (e.getActionCommand().equals("export")) {

        // EXPORT OBJECT TO OSX_FILE

        if (exportData(outStream, canonicalFilePathName) == true) {

          // if we get here, then everything worked correctly, so
          // tell user that data was put into file.
          // This is different from the Import strategy
          // because the user may not know the name of the file
          // that was used if they selected the automatic temp file
          // operation, or they may not know what directory the file
          // was actually put into, so this tells them the full file path.
          JOptionPane.showMessageDialog(this,
            // i18n[popupeditableIoPanel.exportedToFile=Data Successfully exported to file {0}]
            s_stringMgr.getString("popupeditableIoPanel.exportedToFile", canonicalFilePathName),
            // i18n[popupeditableIoPanel.exportSuccess=Export Success]
            s_stringMgr.getString("popupeditableIoPanel.exportSuccess"),JOptionPane.INFORMATION_MESSAGE);
        }
      }

      else if (e.getActionCommand().equals("execute")) {

        // EXPORT OBJECT TO OSX_FILE, EXECUTE PROGRAM ON IT, IMPORT IT BACK

        if (((String)externalCommandCombo.getEditor().getItem()) == null ||
          ((String)externalCommandCombo.getEditor().getItem()).length() == 0) {
          // cannot execute a null command
          JOptionPane.showMessageDialog(this,
            // i18n[popupeditableIoPanel.cannotExec=Cannot execute a null command.\nPlease enter a command in the Command field before clicking on Execute.]
            s_stringMgr.getString("popupeditableIoPanel.cannotExec"),
            // i18n[popupeditableIoPanel.executeError=Execute Error]
            s_stringMgr.getString("popupeditableIoPanel.executeError"),JOptionPane.ERROR_MESSAGE);
          return;
        }

        // replace any instance of flag in command with file name
        String command = ((String)externalCommandCombo.getEditor().getItem());

        int index;
        while ((index = command.indexOf(FILE_REPLACE_FLAG)) >= 0) {
          command = command.substring(0, index) +
            canonicalFilePathName +
            command.substring(index + FILE_REPLACE_FLAG.length());
        }

        // export data to file
        if (exportData(outStream, canonicalFilePathName) == false) {
          // bad export - do not proceed with command
          // The exportData() method has already put up a message
          // to the user saying the export failed.
          return;
        }

        int commandResult;
        BufferedReader err = null;
        try {
          // execute command
          Process cmdProcess = Runtime.getRuntime().exec(command);

          // wait for command to complete
          commandResult = cmdProcess.waitFor();

          // check the error stream for a problem
          //
          // This is a bit questionable since it is possible
          // for processes to output something on stderr
          // but continue processing.  But without this, some
          // problems are not seen (e.g. "bad argument" type
          // messages from the process).
          err = new BufferedReader(
            new InputStreamReader(cmdProcess.getErrorStream()));

          String errMsg = err.readLine();
          if (errMsg != null)
            throw new IOException(
              "text on error stream from command starting with:\n"+errMsg);
        }
        catch (Exception ex) {

          Object[] args = new Object[]{command, ex.getMessage()};
          JOptionPane.showMessageDialog(this,
            // i18n[popupeditableIoPanel.errWhileExecutin=Error while executing command.\nThe command was:\n {0}\nThe error was:\n{1}]
            s_stringMgr.getString("popupeditableIoPanel.errWhileExecutin", args),
            // i18n[popupeditableIoPanel.executeError2=Execute Error]
            s_stringMgr.getString("popupeditableIoPanel.executeError2"),JOptionPane.ERROR_MESSAGE);
          return;
        } finally {
            _iou.closeReader(err);
        }

        // check for possibly bad return from child
        if (commandResult != 0) {
          // command returned non-standard value.
          // ask user before proceeding.
          int option = JOptionPane.showConfirmDialog(this,
              // i18n[popupeditableIoPanel.commandReturnNot0=The convention for command returns is that 0 means success, but this command returned {0}.\nDo you wish to import the file contents anyway?]
              s_stringMgr.getString("popupeditableIoPanel.commandReturnNot0", Integer.valueOf(commandResult)),

              // i18n[popupeditableIoPanel.importWarning=Import Warning]
              s_stringMgr.getString("popupeditableIoPanel.importWarning"), JOptionPane.YES_NO_OPTION);
          if (option != JOptionPane.YES_OPTION) {
            return;
          }
        }

        //import the data back from the same file
        importData(file);

        // If the file was a temp file, delete it now.
        // We assume that Export-only operations want to leave the
        // file in place, but Execute operations just want a temp
        // space to work with and do not want it lying around afterwards.
        file.delete();
      }
    } // end of combined export and execute operations
  }

  /**
   * Function to import data from a file.
   * This is a separate function because it is called from two places.
   * One is when the user asks to do an import, and the other is when they
   * ask to run an external command, which involves importing from the file
   * after the command is completed.
   */
  private void importData(File file) {
    // create the imput stream
    // (so that DataType objects don't have to)
    FileInputStream inStream;
    String canonicalFilePathName = fileNameField.getText();
    try {
      inStream = new FileInputStream(file);

      // it is handy to have the cannonical path name
      // to show user in error messages.  Since getting
      // that name might involve an IOException, we need
      // to put it inside a try statement.  However,
      // since the file does exist there is no good reason
      // for getting an IOException at this point, but
      // if we get one there is something seriously wrong
      // and we want to abort.  Therefore it make sense
      // to get that name here and save it for later use.
      canonicalFilePathName = file.getCanonicalPath();
    }
    catch (Exception ex) {

      Object[] args = new Object[]{canonicalFilePathName, ex.getMessage()};

      JOptionPane.showMessageDialog(this,
        // i18n[popupeditableIoPanel.fileOpenError=There was an error opening file {0}.\nThe error was:\n{1}]
        s_stringMgr.getString("popupeditableIoPanel.fileOpenError", args),
        // i18n[popupeditableIoPanel.fileOpenErrorHeader=File Open Error]
        s_stringMgr.getString("popupeditableIoPanel.fileOpenErrorHeader"),JOptionPane.ERROR_MESSAGE);
      return;
    }

    // hand file input stream to DataType object for import
    // Also, handle File IO errors here so that DataType objects
    // do not have to.
    try {

      // The DataObject returns a string to put into the
      // popup which can later be converted to the appropriate
      // object type.
      String replacementText =
        CellComponentFactory.importObject(_colDef, inStream);

      // since the above did not throw an exception,
      // we now have a good new data object, so
      // change the text area to reflect that new object.
      //

      // If the user has selected a non-cannonical Binary format, we need
      // to convert the text appropriately
      if (radixList != null &&
        ! (radixList.getSelectedItem().equals("Hex") &&
          showAscii.isSelected() == false) ) {
        // we need to convert to a different format
        int base = 16// default to hex
        if (radixList.getSelectedItem().equals("Decimal")) base = 10;
        else if (radixList.getSelectedItem().equals("Octal")) base = 8;
        else if (radixList.getSelectedItem().equals("Binary")) base = 2;

        Byte[] bytes = BinaryDisplayConverter.convertToBytes(replacementText,
          16, false);

        // return the expected format for this data
        replacementText = BinaryDisplayConverter.convertToString(bytes,
          base, showAscii.isSelected());
      }

      ((RestorableJTextArea)_ta).updateText(replacementText);
    }
    catch (Exception ex) {

      Object[] args = new Object[]{canonicalFilePathName, ex.getMessage()};
      JOptionPane.showMessageDialog(this,
        // i18n[popupeditableIoPanel.errorReadingFile=There was an error while reading file {0}.\nThe error was:\n{1}]
        s_stringMgr.getString("popupeditableIoPanel.errorReadingFile", args),
        // i18n[popupeditableIoPanel.importError2=Import Error]
        s_stringMgr.getString("popupeditableIoPanel.importError2"),JOptionPane.ERROR_MESSAGE);
      return;
    }

    // cleanup resources used
    try {
      inStream.close();
    }
    catch (Exception ex) {
      // I cannot think of any reason for doing anything
      // at all here
    }

    /*
         * Issue: After importing the data, we could tell the user that
         * it has been successfully imported.  This would give good
         * positive feedback.  However, it would mean that they need
         * to click on yet another button to dismiss that message.
         * On the other hand, since the operation is synchronous,
         * the user cannot proceed to do anything until it is done.
         * If we assume that import usually works correctly unless
         * they are shown an error message, then we do not need to
         * display anything here.
         */
  }


  /**
   * Function to export data to a file.
   * This is a separate function because it is called from two places.
   * One is when the user asks to export, and the other is when they
   * as to run an external command, which involves exporting to file first.
   */
  private boolean exportData(FileOutputStream outStream,
                             String canonicalFilePathName){

    // hand file output stream to DataType object for export
    // Also, handle File IO errors here so that DataType objects
    // do not have to.
    try {

      // Hand the current text to the DataType object.
      // DataType object is responsible for validating
      // that the text makes sense for this type of object
      // and converting it to the proper form for output.
      // All errors are handled as IOExceptions
      CellComponentFactory.exportObject(_colDef, outStream,
        getTextAreaCannonicalForm());

    }
    catch (Exception ex) {

      Object[] args = new Object[]{canonicalFilePathName, ex.getMessage()};

      JOptionPane.showMessageDialog(this,
        // i18n[popupeditableIoPanel.errorWritingFile=There was an error while writing file {0}.\nThe error was:\n{1}]
        s_stringMgr.getString("popupeditableIoPanel.errorWritingFile", args),
        // i18n[popupeditableIoPanel.exportError100=Export Error]
        s_stringMgr.getString("popupeditableIoPanel.exportError100"),JOptionPane.ERROR_MESSAGE);
      return false;
    }

    return true;
  }

  /**
   * catch and handle mouse events to put up a menu
   */
  public void addNotify()
  {
    super.addNotify();
    if (_lis == null)
    {
      _lis = new MouseAdapter()
      {
        public void mousePressed(MouseEvent evt)
        {
          if (evt.isPopupTrigger())
          {
            _popupMenu.show(evt);
          }
        }
        public void mouseReleased(MouseEvent evt)
        {
            if (evt.isPopupTrigger())
          {
            _popupMenu.show(evt);
          }
        }
      };
      _ta.addMouseListener(_lis);
    }
  }

  public void removeNotify()
  {
    super.removeNotify();
    if (_lis != null)
    {
      _ta.removeMouseListener(_lis);
      _lis = null;
    }
  }

  @SuppressWarnings("serial")
  private class LineWrapAction extends BaseAction
  {
    LineWrapAction()
    {
      // i18n[popupEditableIoPanel.wrapLines=Wrap Lines on/off]
      super(s_stringMgr.getString("popupEditableIoPanel.wrapLines"));
    }

    public void actionPerformed(ActionEvent evt)
    {
      if (_ta != null)
      {
        _ta.setLineWrap(!_ta.getLineWrap());
      }
    }
  }

  private class WordWrapAction extends BaseAction
  {
        private static final long serialVersionUID = 1L;

        WordWrapAction()
    {
      // i18n[popupEditableIoPanel.wrapWord=Wrap on Word on/off]
      super(s_stringMgr.getString("popupEditableIoPanel.wrapWord"));
    }

    public void actionPerformed(ActionEvent evt)
    {
      if (_ta != null)
      {
        _ta.setWrapStyleWord(!_ta.getWrapStyleWord());
      }
    }
  }

  private class XMLReformatAction extends BaseAction
  {
        private static final long serialVersionUID = 1L;

        XMLReformatAction()
    {
      // i18n[popupEditableIoPanel.reformatXml=Reformat XML]
      super(s_stringMgr.getString("popupEditableIoPanel.reformatXml"));
    }

    public void actionPerformed(ActionEvent evt)
    {
      if (_ta != null)
      {
        _ta.setText(XmlRefomatter.reformatXml(_ta.getText()));
      }
    }
  }

  /**
   * Helper function that ensures that the data is acceptable to the DataType
   * object. The issue addressed here is that Binary data can be represented
   * in multiple formats (Hex, Octal, etc), and to keep the DataTypes simple
   * we assume that they get only Hex data with ASCII chars shown as their
   * numeric value. This makes sense from the point of view that the different
   * formats are temporary views handled by this class rather than permanent
   * settings applied to either the column or the DataType. Therefore, when we
   * pass the data from the TextArea into the DataType, we may need to do a
   * conversion on the way.
   */
  private String getTextAreaCannonicalForm() {
    // handle null
    if (_ta.getText() == null ||
      _ta.getText().equals("<null>") ||
      _ta.getText().length() == 0)
      return _ta.getText();

    // if the data is not binary, then there is no need for conversion.
    // if the data is Hex with ASCII not shown as chars, then no conversion needed.
    if (radixList == null ||
      (radixList.getSelectedItem().equals("Hex") && ! showAscii.isSelected()) ) {
      // no need for conversion
      return _ta.getText();
    }

    // The field is binary and not in the format expected by the DataType
    int base = 16// default to hex
    if (radixList.getSelectedItem().equals("Decimal")) base = 10;
    else if (radixList.getSelectedItem().equals("Octal")) base = 8;
    else if (radixList.getSelectedItem().equals("Binary")) base = 2;

    // the following can cause and exception if the text is not formatted correctly
    Byte[] bytes = BinaryDisplayConverter.convertToBytes(_ta.getText(),
      base, showAscii.isSelected());

    // return the expected format for this data
    return BinaryDisplayConverter.convertToString(bytes, 16, false);
  }
}
TOP

Related Classes of net.sourceforge.squirrel_sql.fw.datasetviewer.PopupEditableIOPanel$LineWrapAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
script>