package org.jabref.gui.auximport; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.nio.file.Path; import java.util.Optional; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.BorderFactory; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JTextField; import org.jabref.Globals; import org.jabref.gui.BasePanel; import org.jabref.gui.DialogService; import org.jabref.gui.FXDialogService; import org.jabref.gui.JabRefDialog; import org.jabref.gui.JabRefFrame; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.logic.auxparser.AuxParser; import org.jabref.logic.auxparser.AuxParserResult; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.FileExtensions; import org.jabref.model.database.BibDatabase; import org.jabref.preferences.JabRefPreferences; import com.jgoodies.forms.builder.ButtonBarBuilder; import com.jgoodies.forms.builder.DefaultFormBuilder; import com.jgoodies.forms.layout.FormLayout; /** * A wizard dialog for generating a new sub database from existing TeX AUX file */ public class FromAuxDialog extends JabRefDialog { private final JPanel statusPanel = new JPanel(); private final JPanel buttons = new JPanel(); private final JButton generateButton = new JButton(); private final JButton cancelButton = new JButton(); private final JButton parseButton = new JButton(); private final JComboBox<String> dbChooser = new JComboBox<>(); private JTextField auxFileField; private JList<String> notFoundList; private JTextArea statusInfos; // all open databases from JabRefFrame private final JTabbedPane parentTabbedPane; private boolean generatePressed; private AuxParser auxParser; private final JabRefFrame parentFrame; public FromAuxDialog(JabRefFrame frame, String title, boolean modal, JTabbedPane viewedDBs) { super(frame, title, modal, FromAuxDialog.class); parentTabbedPane = viewedDBs; parentFrame = frame; jbInit(); pack(); setSize(600, 500); } private void jbInit() { JPanel panel1 = new JPanel(); panel1.setLayout(new BorderLayout()); generateButton.setText(Localization.lang("Generate")); generateButton.setEnabled(false); generateButton.addActionListener(e -> { generatePressed = true; dispose(); }); cancelButton.setText(Localization.lang("Cancel")); cancelButton.addActionListener(e -> dispose()); parseButton.setText(Localization.lang("Parse")); parseButton.addActionListener(e -> parseActionPerformed()); initPanels(); // insert the buttons ButtonBarBuilder bb = new ButtonBarBuilder(); JPanel buttonPanel = bb.getPanel(); buttonPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); bb.addGlue(); bb.addButton(parseButton); bb.addRelatedGap(); bb.addButton(generateButton); bb.addButton(cancelButton); bb.addGlue(); this.setModal(true); this.setResizable(true); this.setTitle(Localization.lang("AUX file import")); JLabel desc = new JLabel("<html><h3>" + Localization.lang("AUX file import") + "</h3><p>" + Localization.lang("This feature generates a new library based on which entries " + "are needed in an existing LaTeX document.") + "</p>" + "<p>" + Localization.lang("You need to select one of your open libraries from which to choose " + "entries, as well as the AUX file produced by LaTeX when compiling your document.") + "</p></html>"); desc.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); panel1.add(desc, BorderLayout.NORTH); JPanel centerPane = new JPanel(new BorderLayout()); centerPane.add(buttons, BorderLayout.NORTH); centerPane.add(statusPanel, BorderLayout.CENTER); getContentPane().add(panel1, BorderLayout.NORTH); getContentPane().add(centerPane, BorderLayout.CENTER); getContentPane().add(buttonPanel, BorderLayout.SOUTH); // Key bindings: ActionMap am = statusPanel.getActionMap(); InputMap im = statusPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); im.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE_DIALOG), "close"); am.put("close", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { dispose(); } }); } private void initPanels() { // collect the names of all open databases int len = parentTabbedPane.getTabCount(); int toSelect = -1; for (int i = 0; i < len; i++) { dbChooser.addItem(parentTabbedPane.getTitleAt(i)); if (parentFrame.getBasePanelAt(i) == parentFrame.getCurrentBasePanel()) { toSelect = i; } } if (toSelect >= 0) { dbChooser.setSelectedIndex(toSelect); } auxFileField = new JTextField("", 25); JButton browseAuxFileButton = new JButton(Localization.lang("Browse")); FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .addExtensionFilter(FileExtensions.AUX) .withDefaultExtension(FileExtensions.AUX) .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); DialogService ds = new FXDialogService(); browseAuxFileButton.addActionListener(e -> { Optional<Path> file = DefaultTaskExecutor .runInJavaFXThread(() -> ds.showFileOpenDialog(fileDialogConfiguration)); file.ifPresent(f -> auxFileField.setText(f.toAbsolutePath().toString())); }); notFoundList = new JList<>(); JScrollPane listScrollPane = new JScrollPane(notFoundList); statusInfos = new JTextArea("", 5, 20); JScrollPane statusScrollPane = new JScrollPane(statusInfos); statusInfos.setEditable(false); DefaultFormBuilder b = new DefaultFormBuilder( new FormLayout("left:pref, 4dlu, fill:pref:grow, 4dlu, left:pref", ""), buttons); b.appendSeparator(Localization.lang("Options")); b.append(Localization.lang("Reference library") + ":"); b.append(dbChooser, 3); b.nextLine(); b.append(Localization.lang("LaTeX AUX file") + ":"); b.append(auxFileField); b.append(browseAuxFileButton); b.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); b = new DefaultFormBuilder(new FormLayout("fill:pref:grow, 4dlu, fill:pref:grow", "pref, pref, fill:pref:grow"), statusPanel); b.appendSeparator(Localization.lang("Result")); b.append(Localization.lang("Unknown BibTeX entries") + ":"); b.append(Localization.lang("Messages") + ":"); b.nextLine(); b.append(listScrollPane); b.append(statusScrollPane); b.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); } private void parseActionPerformed() { parseButton.setEnabled(false); BasePanel bp = (BasePanel) parentTabbedPane.getComponentAt(dbChooser.getSelectedIndex()); notFoundList.removeAll(); statusInfos.setText(null); BibDatabase refBase = bp.getDatabase(); String auxName = auxFileField.getText(); if ((auxName != null) && (refBase != null) && !auxName.isEmpty()) { auxParser = new AuxParser(auxName, refBase); AuxParserResult result = auxParser.parse(); notFoundList.setListData(result.getUnresolvedKeys().toArray(new String[result.getUnresolvedKeys().size()])); statusInfos.append(result.getInformation(false)); generateButton.setEnabled(true); // the generated database contains no entries -> no active generate-button if (!result.getGeneratedBibDatabase().hasEntries()) { statusInfos.append("\n" + Localization.lang("empty library")); generateButton.setEnabled(false); } } else { generateButton.setEnabled(false); } parseButton.setEnabled(true); } public boolean generatePressed() { return generatePressed; } public BibDatabase getGenerateDB() { return auxParser.parse().getGeneratedBibDatabase(); } }