package org.jabref.gui.externalfiletype; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionListener; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.jabref.Globals; import org.jabref.gui.DialogService; import org.jabref.gui.FXDialogService; import org.jabref.gui.IconTheme; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.logic.l10n.Localization; import org.jabref.logic.util.OS; import org.jabref.preferences.JabRefPreferences; import com.jgoodies.forms.builder.ButtonBarBuilder; import com.jgoodies.forms.builder.FormBuilder; import com.jgoodies.forms.layout.FormLayout; /** * This class produces a dialog box for editing an external file type. */ public class ExternalFileTypeEntryEditor { private JFrame fParent; private JDialog dParent; private JDialog diag; private final JTextField extension = new JTextField(); private final JTextField name = new JTextField(); private final JTextField mimeType = new JTextField(); private final JTextField application = new JTextField(); private final JLabel icon = new JLabel(IconTheme.JabRefIcon.FILE.getSmallIcon()); private final JButton ok = new JButton(Localization.lang("OK")); private final JButton cancel = new JButton(Localization.lang("Cancel")); private final JRadioButton useDefault = new JRadioButton(Localization.lang("Default")); private final JRadioButton other = new JRadioButton(""); private final String editFileTitle = Localization.lang("Edit file type"); private final String newFileTitle = Localization.lang("Add new file type"); private ExternalFileType entry; private boolean okPressed; private final ActionListener browsePressed = e -> { String appDir = application.getText().trim(); if (appDir.isEmpty()) { appDir = Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY); } FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .withInitialDirectory(Paths.get(appDir)).build(); DialogService ds = new FXDialogService(); Optional<Path> path = DefaultTaskExecutor .runInJavaFXThread(() -> ds.showFileOpenDialog(fileDialogConfiguration)); path.ifPresent(applicationDir -> { if (applicationDir.getParent() != null) { Globals.prefs.put(JabRefPreferences.WORKING_DIRECTORY, applicationDir.getParent().toString()); } application.setText(applicationDir.toString()); }); }; public ExternalFileTypeEntryEditor(JFrame parent, ExternalFileType entry) { fParent = parent; init(entry); } public ExternalFileTypeEntryEditor(JDialog parent, ExternalFileType entry) { dParent = parent; init(entry); } private void init(ExternalFileType inEntry) { entry = inEntry; icon.setText(null); ButtonGroup bg = new ButtonGroup(); bg.add(useDefault); bg.add(other); FormBuilder builder = FormBuilder.create(); builder.layout(new FormLayout("left:pref, 4dlu, fill:150dlu, 4dlu, fill:pref", "p, 2dlu, p, 2dlu, p, 2dlu, p, 2dlu, p, 2dlu, p")); builder.add(Localization.lang("Icon")).xy(1, 1); builder.add(icon).xy(3, 1); builder.add(Localization.lang("Name")).xy(1, 3); builder.add(name).xy(3, 3); builder.add(Localization.lang("Extension")).xy(1, 5); builder.add(extension).xy(3, 5); builder.add(Localization.lang("MIME type")).xy(1, 7); builder.add(mimeType).xy(3, 7); builder.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); builder.add(Localization.lang("Application")).xy(1, 9); JButton browseBut = new JButton(Localization.lang("Browse")); if (OS.WINDOWS) { builder.add(useDefault).xy(3, 9); builder.appendRows("2dlu, p"); JPanel p1 = new JPanel(); builder.add(p1).xy(1, 11); JPanel p2 = new JPanel(); application.setPreferredSize(new Dimension(300, application.getPreferredSize().height)); BorderLayout bl = new BorderLayout(); bl.setHgap(4); p2.setLayout(bl); p2.add(other, BorderLayout.WEST); p2.add(application, BorderLayout.CENTER); builder.add(p2).xy(3, 11); builder.add(browseBut).xy(5, 11); } else { builder.add(application).xy(3, 9); builder.add(browseBut).xy(5, 9); } ButtonBarBuilder bb = new ButtonBarBuilder(); bb.addGlue(); bb.addButton(ok); bb.addButton(cancel); bb.addGlue(); ok.addActionListener(e -> { okPressed = true; storeSettings(ExternalFileTypeEntryEditor.this.entry); diag.dispose(); }); cancel.addActionListener(e -> diag.dispose()); if (OS.WINDOWS) { application.getDocument().addDocumentListener(new DocumentListener() { private void handle() { if (application.getText().isEmpty()) { useDefault.setSelected(true); } else { other.setSelected(true); } } @Override public void insertUpdate(DocumentEvent documentEvent) { handle(); } @Override public void removeUpdate(DocumentEvent documentEvent) { handle(); } @Override public void changedUpdate(DocumentEvent documentEvent) { handle(); } }); } String title = editFileTitle; if (entry.getName().isEmpty()) { title = newFileTitle; } if (dParent == null) { diag = new JDialog(fParent, title, true); } else { diag = new JDialog(dParent, title, true); } diag.getContentPane().add(builder.getPanel(), BorderLayout.CENTER); diag.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH); diag.pack(); browseBut.addActionListener(browsePressed); if (dParent == null) { diag.setLocationRelativeTo(fParent); } else { diag.setLocationRelativeTo(dParent); } setValues(entry); } public void setEntry(ExternalFileType entry) { this.entry = entry; if (entry.getName().isEmpty()) { diag.setTitle(newFileTitle); } else { diag.setTitle(editFileTitle); } setValues(entry); } public void setVisible(boolean visible) { if (visible) { okPressed = false; } diag.setVisible(visible); } private void setValues(ExternalFileType entry) { name.setText(entry.getName()); extension.setText(entry.getExtension()); mimeType.setText(entry.getMimeType()); application.setText(entry.getOpenWithApplication()); icon.setIcon(entry.getIcon()); if (application.getText().isEmpty()) { useDefault.setSelected(true); } else { other.setSelected(true); } } private void storeSettings(ExternalFileType fileTypeEntry) { fileTypeEntry.setName(name.getText().trim()); fileTypeEntry.setMimeType(mimeType.getText().trim()); // Set extension, but remove initial dot if user has added that: String ext = extension.getText().trim(); if (!ext.isEmpty() && (ext.charAt(0) == '.')) { fileTypeEntry.setExtension(ext.substring(1)); } else { fileTypeEntry.setExtension(ext); } if (OS.WINDOWS) { // On Windows, store application as empty if the "Default" option is selected, // or if the application name is empty: if (useDefault.isSelected() || application.getText().trim().isEmpty()) { fileTypeEntry.setOpenWith(""); } else { fileTypeEntry.setOpenWith(application.getText().trim()); } } else { fileTypeEntry.setOpenWith(application.getText().trim()); } } public boolean okPressed() { return okPressed; } }