Package net.sf.jabref.external

Source Code of net.sf.jabref.external.ExternalFilePanel

package net.sf.jabref.external;

import java.awt.Component;
import java.awt.GridLayout;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.xml.transform.TransformerException;

import net.sf.jabref.BibtexDatabase;
import net.sf.jabref.BibtexEntry;
import net.sf.jabref.BibtexFields;
import net.sf.jabref.EntryEditor;
import net.sf.jabref.FieldEditor;
import net.sf.jabref.Globals;
import net.sf.jabref.JabRefFrame;
import net.sf.jabref.MetaData;
import net.sf.jabref.OpenFileFilter;
import net.sf.jabref.UrlDragDrop;
import net.sf.jabref.Util;
import net.sf.jabref.gui.FileDialogs;
import net.sf.jabref.net.URLDownload;
import net.sf.jabref.util.XMPUtil;

/**
* Initial Version:
*
* @author alver
* @version Date: May 7, 2005 Time: 7:17:42 PM
*
* Current Version:
*
* @author $Author: mortenalver $
* @version $Revision: 2950 $ ($Date: 2009-04-14 20:17:08 +0200 (Tue, 14 Apr 2009) $)
*
*/
public class ExternalFilePanel extends JPanel {

  private static final long serialVersionUID = 3653290879640642718L;

  private JButton browseBut, download, auto, xmp;

  private EntryEditor entryEditor;

    private JabRefFrame frame;

  private OpenFileFilter off;

  private BibtexEntry entry;
 
  private BibtexDatabase database;

  private MetaData metaData;

  public ExternalFilePanel(final String fieldName, final MetaData metaData,
    final BibtexEntry entry, final FieldEditor editor, final OpenFileFilter off) {
    this(null, metaData, null, fieldName, off, editor);
    this.entry = entry;
        this.entryEditor = null;
    }

  public ExternalFilePanel(final JabRefFrame frame, final MetaData metaData,
    final EntryEditor entryEditor, final String fieldName, final OpenFileFilter off,
    final FieldEditor editor) {

    this.frame = frame;
    this.metaData = metaData;
    this.off = off;
    this.entryEditor = entryEditor;

        setLayout(new GridLayout(2, 2));

    browseBut = new JButton(Globals.lang("Browse"));
    download = new JButton(Globals.lang("Download"));
    auto = new JButton(Globals.lang("Auto"));
    xmp = new JButton(Globals.lang("Write XMP"));
    xmp.setToolTipText(Globals.lang("Write BibtexEntry as XMP-metadata to PDF."));

    browseBut.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        browseFile(fieldName, editor);
        // editor.setText(chosenValue);
        entryEditor.storeFieldAction.actionPerformed(new ActionEvent(editor, 0, ""));
      }
    });

    download.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        downLoadFile(fieldName, editor, frame);
      }
    });

    auto.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        autoSetFile(fieldName, editor);
      }
    });
    xmp.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        pushXMP(fieldName, editor);
      }
    });

    add(browseBut);
    add(download);
    add(auto);
    add(xmp);

    // Add drag and drop support to the field
    if (editor != null)
      ((JComponent) editor).setDropTarget(new DropTarget((Component) editor,
        DnDConstants.ACTION_NONE, new UrlDragDrop(entryEditor, frame, editor)));
  }

  /**
   * Change which entry this panel is operating on. This is used only when
   * this panel is not attached to an entry editor.
   */
  public void setEntry(BibtexEntry entry, BibtexDatabase database) {
    this.entry = entry;
    this.database = database;
  }
 
  public BibtexDatabase getDatabase(){
    return (database != null ? database : entryEditor.getDatabase());
  }

  public BibtexEntry getEntry() {
    return (entry != null ? entry : entryEditor.getEntry());
  }

  protected Object getKey() {
    return getEntry().getField(BibtexFields.KEY_FIELD);
  }

  protected void output(String s) {
    if (frame != null)
      frame.output(s);
  }

  public void pushXMP(final String fieldName, final FieldEditor editor) {


    (new Thread() {
      public void run() {

        output(Globals.lang("Looking for pdf..."));
       
        // Find the default directory for this field type, if any:
        String dir = metaData.getFileDirectory(fieldName);
        File file = null;
        if (dir != null) {
          File tmp = Util.expandFilename(editor.getText(), new String[] { dir, "." });
          if (tmp != null)
            file = tmp;
        }

        if (file == null) {
          file = new File(editor.getText());
        }
       
        final File finalFile = file;
   
        output(Globals.lang("Writing XMP to '%0'...", finalFile.getName()));
        try {
          XMPUtil.writeXMP(finalFile, getEntry(), getDatabase());
          output(Globals.lang("Wrote XMP to '%0'.", finalFile.getName()));
        } catch (IOException e) {
          JOptionPane.showMessageDialog(editor.getParent(), Globals.lang(
            "Error writing XMP to file: %0", e.getLocalizedMessage()), Globals
            .lang("Writing XMP"), JOptionPane.ERROR_MESSAGE);
          Globals.logger(Globals.lang("Error writing XMP to file: %0", finalFile
            .getAbsolutePath()));
          output(Globals.lang("Error writing XMP to file: %0", finalFile.getName()));
         
        } catch (TransformerException e) {
          JOptionPane.showMessageDialog(editor.getParent(), Globals.lang(
            "Error converting Bibtex to XMP: %0", e.getLocalizedMessage()), Globals
            .lang("Writing XMP"), JOptionPane.ERROR_MESSAGE);
          Globals.logger(Globals.lang("Error while converting BibtexEntry to XMP %0",
            finalFile.getAbsolutePath()));
          output(Globals.lang("Error converting XMP to '%0'...", finalFile.getName()));
        }
      }
    }).start();
  }

  public void browseFile(final String fieldName, final FieldEditor editor) {

    String directory = metaData.getFileDirectory(fieldName);
    if ((directory != null) && directory.equals(""))
      directory = null;

    String dir = editor.getText(), retVal = null;

    if ((directory == null) || !(new File(dir)).isAbsolute()) {
      if (directory != null)
        dir = directory;
      else
        dir = Globals.prefs.get(fieldName + Globals.FILETYPE_PREFS_EXT, "");
    }

    String chosenFile = FileDialogs.getNewFile(frame, new File(dir), "." + fieldName,
      JFileChooser.OPEN_DIALOG, false);

    if (chosenFile != null) {
      File newFile = new File(chosenFile);
      String position = newFile.getParent();

      if ((directory != null) && position.startsWith(directory)) {
        // Construct path relative to pdf base dir
        String relPath = position.substring(directory.length(), position.length())
          + File.separator + newFile.getName();

        // Remove leading path separator
        if (relPath.startsWith(File.separator)) {
          relPath = relPath.substring(File.separator.length(), relPath.length());

          // Set relative path as field value
        }

        retVal = relPath;
      } else
        retVal = newFile.getPath();

      editor.setText(retVal);
      Globals.prefs.put(fieldName + Globals.FILETYPE_PREFS_EXT, newFile.getPath());
    }
  }

  public void downLoadFile(final String fieldName, final FieldEditor fieldEditor,
    final Component parent) {

    final String res = JOptionPane.showInputDialog(parent, Globals
      .lang("Enter URL to download"));

    if (res == null || res.trim().length() == 0)
      return;

    /*
     * If this panel belongs in an entry editor, note which entry is
     * currently shown:
     */
    final BibtexEntry targetEntry;
    if (entryEditor != null)
      targetEntry = entryEditor.getEntry();
    else
      targetEntry = entry;

    (new Thread() {

      public String getPlannedFileName(String res) {
        String suffix = off.getSuffix(res);
        if (suffix == null)
          suffix = "." + fieldName.toLowerCase();

        String plannedName = null;
        if (getKey() != null)
          plannedName = getKey() + suffix;
        else {
          plannedName = JOptionPane.showInputDialog(parent, Globals
            .lang("BibTeX key not set. Enter a name for the downloaded file"));
          if (plannedName != null && !off.accept(plannedName))
            plannedName += suffix;
        }

        /*
         * [ 1548875 ] download pdf produces unsupported filename
         *
         * http://sourceforge.net/tracker/index.php?func=detail&aid=1548875&group_id=92314&atid=600306
         *
         */
        if (Globals.ON_WIN) {
          plannedName = plannedName.replaceAll(
            "\\?|\\*|\\<|\\>|\\||\\\"|\\:|\\.$|\\[|\\]", "");
        } else if (Globals.ON_MAC) {
          plannedName = plannedName.replaceAll(":", "");
        }

        return plannedName;
      }

      public void run() {
        String originalText = fieldEditor.getText();
        fieldEditor.setEnabled(false);
        boolean updateEditor = true;

        try {
          fieldEditor.setText(Globals.lang("Downloading..."));
          output(Globals.lang("Downloading..."));
          String plannedName = getPlannedFileName(res);

          // Find the default directory for this field type:
          String directory = metaData.getFileDirectory(fieldName);

          if (!new File(directory).exists()) {
            JOptionPane.showMessageDialog(parent, Globals.lang(
              "Could not find directory for %0-files: %1", fieldName, directory),
              Globals.lang("Download file"), JOptionPane.ERROR_MESSAGE);
            Globals.logger(Globals.lang("Could not find directory for %0-files: %1",
              fieldName, directory));
            return;
          }
          File file = new File(new File(directory), plannedName);

          URL url = new URL(res);

          URLDownload udl = new URLDownload(parent, url, file);
          try {
            udl.download();
          } catch (IOException e2) {
            JOptionPane.showMessageDialog(parent, Globals.lang("Invalid URL")+": "
              + e2.getMessage(), Globals.lang("Download file"),
              JOptionPane.ERROR_MESSAGE);
            Globals.logger("Error while downloading " + url.toString());
            return;
          }
          output(Globals.lang("Download completed"));

          String textToSet = file.getPath();
          if (textToSet.startsWith(directory)) {
            // Construct path relative to pdf base dir
            textToSet = textToSet.substring(directory.length(), textToSet.length());

            // Remove leading path separator
            if (textToSet.startsWith(File.separator)) {
              textToSet = textToSet.substring(File.separator.length());
            }
          }

          /*
           * Check if we should update the editor text field, or
           * update the target entry directly:
           */
                    if (entryEditor == null || entryEditor.getEntry() != targetEntry) {
            /*
             * Editor has probably changed to show a different
             * entry. So we must update the target entry directly
             * and not set the text of the editor.
             */
            targetEntry.setField(fieldName, textToSet);
                        fieldEditor.setText(textToSet);
                        fieldEditor.setEnabled(true);
                        updateEditor = false;
          } else {
            /*
             * Need to set the fieldEditor first before running
             * updateField-Action, because otherwise we might get a
             * race condition.
             *
             * (Hopefully a) Fix for: [ 1545601 ] downloading pdf
             * corrupts pdf field text
             *
             * http://sourceforge.net/tracker/index.php?func=detail&aid=1545601&group_id=92314&atid=600306
             */
            fieldEditor.setText(textToSet);
            fieldEditor.setEnabled(true);
            updateEditor = false;
            SwingUtilities.invokeLater(new Thread() {
              public void run() {
                entryEditor.updateField(fieldEditor);
              }
            });
          }

        } catch (MalformedURLException e1) {
          JOptionPane.showMessageDialog(parent, Globals.lang("Invalid URL"), Globals
            .lang("Download file"), JOptionPane.ERROR_MESSAGE);
        } finally {
          // If stuff goes wrong along the road, put back original
          // value
          if (updateEditor) {
            fieldEditor.setText(originalText);
            fieldEditor.setEnabled(true);
          }
                }
      }
    }).start();
  }

  /**
   * Starts a thread that searches the external file directory for the given
   * field name, including subdirectories, and looks for files named after the
   * current entry's bibtex key. Returns a reference to the thread for callers
   * that may want to wait for the thread to finish (using join()).
   *
   * @param fieldName
   *            The field to set.
   * @param editor
   *            An EntryEditor instance where to set the value found.
   * @return A reference to the Thread that performs the operation.
   */
  public Thread autoSetFile(final String fieldName, final FieldEditor editor) {
    Object o = getKey();
    if ((o == null) || (Globals.prefs.get(fieldName + "Directory") == null)) {
      output(Globals.lang("You must set both BibTeX key and %0 directory", fieldName
        .toUpperCase())
        + ".");
      return null;
    }
    output(Globals.lang("Searching for %0 file", fieldName.toUpperCase()) + " '" + o + "."
      + fieldName + "'...");
    Thread t = (new Thread() {
      public void run() {
        /*
         * Find the following directories to look in for:
         *
         * default directory for this field type.
         *
         * directory of bibtex-file. // NOT POSSIBLE at the moment.
         *
         * JabRef-directory.
         */
        LinkedList<String> list = new LinkedList<String>();
        list.add(metaData.getFileDirectory(fieldName));

        /*
         * File fileOfDb = frame.basePanel().file(); if (fileOfDb !=
         * null){ list.add(fileOfDb.getParentFile().getPath()); }
         */
        list.add(".");

        String found = Util.findPdf(getEntry(), fieldName, list
          .toArray(new String[list.size()]));// , off);
                                       
                               
        // To activate findFile:
        // String found = Util.findFile(getEntry(), null, dir,
        // ".*[bibtexkey].*");

        if (found != null) {
          editor.setText(found);
          if (entryEditor != null)
            entryEditor.updateField(editor);
          output(Globals.lang("%0 field set", fieldName.toUpperCase()) + ".");
        } else {
          output(Globals.lang("No %0 found", fieldName.toUpperCase()) + ".");
        }

      }
    });

    t.start();
    return t;

  }

}
TOP

Related Classes of net.sf.jabref.external.ExternalFilePanel

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.