diff --git a/CHANGELOG.md b/CHANGELOG.md index f35093a83f7..00c6d9370a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - [#1345](https://github.com/JabRef/jabref/issues/1345) Cleanup ISSN - It is now possible to add your own lists of protected terms, see Options -> Manage protected terms - Automatically generated group names are now converted from LaTeX to Unicode +- Unified dialogs for opening/saving files ### Fixed - Fixed [#1632](https://github.com/JabRef/jabref/issues/1632) User comments (@Comment) with or without brackets are now kept @@ -50,8 +51,9 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Fixed [#1643](https://github.com/JabRef/jabref/issues/1643): Searching with double quotes in a specific field ignores the last character - Fixed [#1288](https://github.com/JabRef/jabref/issues/1288): Newly opened bib-file is not focused - Fixed [#1669](https://github.com/JabRef/jabref/issues/1669): Dialog for manual connection to OpenOffice/LibreOffice works again on Linux -- Fixed [#16682](https://github.com/JabRef/jabref/issues/1682): An entry now must have a BibTeX key to be cited in OpenOffice/LibreOffice - +- Fixed [#1682](https://github.com/JabRef/jabref/issues/1682): An entry now must have a BibTeX key to be cited in OpenOffice/LibreOffice +- Fixed [#1324](https://github.com/JabRef/jabref/issues/1324): Save-Dialog for Lookup fulltext document now opens in the specified working directory +- Fixed [#1609](https://github.com/JabRef/jabref/issues/1324): Adding a file to an entry opened dialog in the parent folder of the working directory ### Removed - It is not longer possible to choose to convert HTML sub- and superscripts to equations diff --git a/src/main/java/net/sf/jabref/external/ExternalFileTypeEditor.java b/src/main/java/net/sf/jabref/external/ExternalFileTypeEditor.java index 374b1778bca..8f2ca3deff2 100644 --- a/src/main/java/net/sf/jabref/external/ExternalFileTypeEditor.java +++ b/src/main/java/net/sf/jabref/external/ExternalFileTypeEditor.java @@ -21,6 +21,7 @@ import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -58,6 +59,7 @@ * Editor for external file types. */ public class ExternalFileTypeEditor extends JDialog { + private JFrame frame; private JDialog dialog; private List fileTypes; @@ -111,6 +113,7 @@ private void init() { dispose(); }); Action cancelAction = new AbstractAction() { + @Override public void actionPerformed(ActionEvent e) { dispose(); @@ -134,9 +137,10 @@ public void actionPerformed(ActionEvent e) { //} }); - add.addActionListener(e -> { + add.addActionListener(e -> { // Generate a new file type: - ExternalFileType type = new ExternalFileType("", "", "", "", "new", IconTheme.JabRefIcon.FILE.getSmallIcon()); + ExternalFileType type = new ExternalFileType("", "", "", "", "new", + IconTheme.JabRefIcon.FILE.getSmallIcon()); // Show the file type editor: getEditor(type).setVisible(true); if (entryEditor.okPressed()) { @@ -246,6 +250,7 @@ public static AbstractAction getAction(JDialog dialog) { return new EditExternalFileTypesAction(dialog); } + class EditListener implements ActionListener { @Override @@ -276,6 +281,7 @@ public Component getTableCellRendererComponent(JTable tab, Object value, boolean } private class FileTypeTableModel extends AbstractTableModel { + @Override public int getColumnCount() { return 5; @@ -354,6 +360,7 @@ public void mouseReleased(MouseEvent e) { } public static class EditExternalFileTypesAction extends MnemonicAwareAction { + private JabRefFrame frame; private JDialog dialog; private ExternalFileTypeEditor editor; diff --git a/src/main/java/net/sf/jabref/external/ExternalFileTypeEntryEditor.java b/src/main/java/net/sf/jabref/external/ExternalFileTypeEntryEditor.java index b584e79ea44..aa738413506 100644 --- a/src/main/java/net/sf/jabref/external/ExternalFileTypeEntryEditor.java +++ b/src/main/java/net/sf/jabref/external/ExternalFileTypeEntryEditor.java @@ -17,16 +17,14 @@ import java.awt.BorderLayout; import java.awt.Dimension; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.io.File; -import java.util.Collections; +import java.nio.file.Path; +import java.util.Optional; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; @@ -36,8 +34,8 @@ import javax.swing.event.DocumentListener; import net.sf.jabref.Globals; -import net.sf.jabref.gui.FileDialogs; import net.sf.jabref.gui.IconTheme; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.logic.util.OS; import net.sf.jabref.preferences.JabRefPreferences; @@ -89,8 +87,8 @@ private void init(ExternalFileType inEntry) { 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.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); @@ -128,6 +126,7 @@ private void init(ExternalFileType inEntry) { ok.addActionListener(e -> { okPressed = true; + storeSettings(ExternalFileTypeEntryEditor.this.entry); diag.dispose(); @@ -177,8 +176,7 @@ public void changedUpdate(DocumentEvent documentEvent) { diag.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH); diag.pack(); - BrowseListener browse = new BrowseListener(application); - browseBut.addActionListener(browse); + browseBut.addActionListener(browsePressed); if (dParent == null) { diag.setLocationRelativeTo(fParent); @@ -248,31 +246,19 @@ public boolean okPressed() { } - static class BrowseListener implements ActionListener { - - private final JTextField comp; - - - public BrowseListener(JTextField comp) { - this.comp = comp; + private final ActionListener browsePressed = e -> { + String appDir = application.getText().trim(); + if (appDir.isEmpty()) { + appDir = Globals.prefs.get(JabRefPreferences.FILE_WORKING_DIRECTORY); } - @Override - public void actionPerformed(ActionEvent e) { - File initial = new File(comp.getText().trim()); - if (comp.getText().trim().isEmpty()) { - // Nothing in the field. Go to the last file dir used: - initial = new File(Globals.prefs.get(JabRefPreferences.FILE_WORKING_DIRECTORY)); - } - String chosen = FileDialogs.getNewFile(null, initial, Collections.emptyList(), - JFileChooser.OPEN_DIALOG, false); - if (chosen != null) { - File newFile = new File(chosen); - // Store the directory for next time: - Globals.prefs.put(JabRefPreferences.FILE_WORKING_DIRECTORY, newFile.getParent()); - comp.setText(newFile.getPath()); - comp.requestFocus(); + Optional path = new NewFileDialogs(fParent, appDir).openDlgAndGetSelectedFile(); + path.ifPresent(applicationDir -> { + if (applicationDir.getParent() != null) { + Globals.prefs.put(JabRefPreferences.FILE_WORKING_DIRECTORY, applicationDir.getParent().toString()); } - } - } + application.setText(applicationDir.toString()); + }); + }; + } diff --git a/src/main/java/net/sf/jabref/external/MoveFileAction.java b/src/main/java/net/sf/jabref/external/MoveFileAction.java index b4bc662daa2..1a2fb893875 100644 --- a/src/main/java/net/sf/jabref/external/MoveFileAction.java +++ b/src/main/java/net/sf/jabref/external/MoveFileAction.java @@ -18,18 +18,19 @@ import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; -import java.util.Collections; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; import java.util.Locale; +import java.util.Optional; import javax.swing.AbstractAction; -import javax.swing.JFileChooser; import javax.swing.JOptionPane; import net.sf.jabref.Globals; -import net.sf.jabref.gui.FileDialogs; import net.sf.jabref.gui.FileListEntry; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.gui.entryeditor.EntryEditor; import net.sf.jabref.gui.fieldeditors.FileListEditor; import net.sf.jabref.gui.util.component.CheckBoxMessage; @@ -44,6 +45,7 @@ * Action for moving or renaming a file that is linked to from an entry in JabRef. */ public class MoveFileAction extends AbstractAction { + private static final Log LOGGER = LogFactory.getLog(MoveFileAction.class); private final JabRefFrame frame; @@ -54,6 +56,7 @@ public class MoveFileAction extends AbstractAction { private static final String MOVE_RENAME = Localization.lang("Move/Rename file"); + public MoveFileAction(JabRefFrame frame, EntryEditor eEditor, FileListEditor editor, boolean toFileDir) { this.frame = frame; this.eEditor = eEditor; @@ -89,7 +92,8 @@ public void actionPerformed(ActionEvent event) { } } if (found < 0) { - JOptionPane.showMessageDialog(frame, Localization.lang("File_directory_is_not_set_or_does_not_exist!"), MOVE_RENAME, JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(frame, Localization.lang("File_directory_is_not_set_or_does_not_exist!"), + MOVE_RENAME, JOptionPane.ERROR_MESSAGE); return; } File file = new File(ln); @@ -123,8 +127,7 @@ public void actionPerformed(ActionEvent event) { answer = JOptionPane.showConfirmDialog(frame, Localization.lang("Move file to file directory?"), MOVE_RENAME, JOptionPane.YES_NO_OPTION); } else { - answer = JOptionPane.showConfirmDialog(frame, cbm, MOVE_RENAME, - JOptionPane.YES_NO_OPTION); + answer = JOptionPane.showConfirmDialog(frame, cbm, MOVE_RENAME, JOptionPane.YES_NO_OPTION); } if (answer != JOptionPane.YES_OPTION) { return; @@ -143,23 +146,15 @@ public void actionPerformed(ActionEvent event) { } chosenFile = sb.toString(); } else { - chosenFile = FileDialogs.getNewFile(frame, file, Collections.singletonList(extension), - JFileChooser.SAVE_DIALOG, false); - } - if (chosenFile == null) { - return; // canceled - } - newFile = new File(chosenFile); - // Check if the file already exists: - if (newFile.exists() && (JOptionPane.showConfirmDialog(frame, - Localization.lang("'%0' exists. Overwrite file?", newFile.getName()), MOVE_RENAME, - JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION)) { - if (toFileDir) { - return; + Optional path = new NewFileDialogs(frame, file.getPath()).saveNewFile(); + if (path.isPresent()) { + chosenFile = path.get().toString(); } else { - repeat = true; + return; } } + newFile = new File(chosenFile); + } if (!newFile.equals(file)) { @@ -170,29 +165,29 @@ public void actionPerformed(ActionEvent event) { } if (success) { // Remove the original file: - if (!file.delete()) { - LOGGER.info("Cannot delete original file"); - } + Files.deleteIfExists(file.toPath()); + // Relativise path, if possible. String canPath = new File(dirs.get(found)).getCanonicalPath(); if (newFile.getCanonicalPath().startsWith(canPath)) { - if ((newFile.getCanonicalPath().length() > canPath.length()) && - (newFile.getCanonicalPath().charAt(canPath.length()) == File.separatorChar)) { + if ((newFile.getCanonicalPath().length() > canPath.length()) + && (newFile.getCanonicalPath().charAt(canPath.length()) == File.separatorChar)) { String newLink = newFile.getCanonicalPath().substring(1 + canPath.length()); - editor.getTableModel().setEntry(selected, new FileListEntry(entry.description, newLink, entry.type)); + editor.getTableModel().setEntry(selected, + new FileListEntry(entry.description, newLink, entry.type)); } else { String newLink = newFile.getCanonicalPath().substring(canPath.length()); - editor.getTableModel().setEntry(selected, new FileListEntry(entry.description, newLink, entry.type)); + editor.getTableModel().setEntry(selected, + new FileListEntry(entry.description, newLink, entry.type)); } } else { String newLink = newFile.getCanonicalPath(); - editor.getTableModel().setEntry(selected, new FileListEntry(entry.description, newLink, entry.type)); + editor.getTableModel().setEntry(selected, + new FileListEntry(entry.description, newLink, entry.type)); } eEditor.updateField(editor); - //JOptionPane.showMessageDialog(frame, Globals.lang("File moved"), - // Globals.lang("Move/Rename file"), JOptionPane.INFORMATION_MESSAGE); frame.output(Localization.lang("File moved")); } else { JOptionPane.showMessageDialog(frame, Localization.lang("Move file failed"), MOVE_RENAME, diff --git a/src/main/java/net/sf/jabref/gui/BasePanel.java b/src/main/java/net/sf/jabref/gui/BasePanel.java index 16adce2909f..aa18e8ffa25 100644 --- a/src/main/java/net/sf/jabref/gui/BasePanel.java +++ b/src/main/java/net/sf/jabref/gui/BasePanel.java @@ -29,6 +29,7 @@ import java.io.StringReader; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -44,7 +45,6 @@ import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.JComponent; -import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSplitPane; @@ -223,6 +223,7 @@ public class BasePanel extends JPanel implements ClipboardOwner, FileUpdateListe private final SearchBar searchBar; private ContentAutoCompleters autoCompleters; + public BasePanel(JabRefFrame frame, BibDatabaseContext bibDatabaseContext) { Objects.requireNonNull(frame); Objects.requireNonNull(bibDatabaseContext); @@ -447,7 +448,7 @@ public void run() { // First check if any entries have keys set already. If so, possibly remove // them from consideration, or warn about overwriting keys. // This is a partial clone of net.sf.jabref.gui.entryeditor.EntryEditor.GenerateKeyAction.actionPerformed(ActionEvent) - for (final Iterator i = entries.iterator(); i.hasNext(); ) { + for (final Iterator i = entries.iterator(); i.hasNext();) { bes = i.next(); if (bes.hasCiteKey()) { if (Globals.prefs.getBoolean(JabRefPreferences.AVOID_OVERWRITING_KEY)) { @@ -688,9 +689,10 @@ public void update() { new SpecialFieldAction(frame, Quality.getInstance(), Quality.getInstance().getValues().get(0).getFieldValue().get(), true, Localization.lang("Toggle quality assured"))); - actions.put(Printed.getInstance().getValues().get(0).getActionName(), new SpecialFieldAction(frame, - Printed.getInstance(), Printed.getInstance().getValues().get(0).getFieldValue().get(), true, - Localization.lang("Toggle print status"))); + actions.put(Printed.getInstance().getValues().get(0).getActionName(), + new SpecialFieldAction(frame, Printed.getInstance(), + Printed.getInstance().getValues().get(0).getFieldValue().get(), true, + Localization.lang("Toggle print status"))); for (SpecialFieldValue prio : Priority.getInstance().getValues()) { actions.put(prio.getActionName(), prio.getAction(this.frame)); @@ -1039,7 +1041,8 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset enc, try { SavePreferences prefs = SavePreferences.loadForSaveFromPreferences(Globals.prefs).withEncoding(enc) .withSaveType(saveType); - BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(FileSaveSession::new); + BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter<>( + FileSaveSession::new); if (selectedOnly) { session = databaseWriter.savePartOfDatabase(bibDatabaseContext, mainTable.getSelectedEntries(), prefs); } else { @@ -1195,6 +1198,7 @@ public SearchBar getSearchBar() { private class GroupTreeListener { private final Runnable task = new Runnable() { + @Override public void run() { // Update group display (for example to reflect that the number of contained entries has changed) @@ -1209,12 +1213,14 @@ public void run() { * Guarded by "task" */ private TimerTask timerTask = new TimerTask() { + @Override public void run() { task.run(); } }; + @Subscribe public void listen(EntryAddedEvent addedEntryEvent) { // if the added entry is an undo don't add it to the current group @@ -1246,6 +1252,7 @@ private void scheduleUpdate() { synchronized (task) { timerTask.cancel(); timerTask = new TimerTask() { + @Override public void run() { task.run(); @@ -1404,7 +1411,8 @@ public void actionPerformed(ActionEvent e) { public void keyPressed(KeyEvent e) { final int keyCode = e.getKeyCode(); final TreePath path = frame.getGroupSelector().getSelectionPath(); - final GroupTreeNodeViewModel node = path == null ? null : (GroupTreeNodeViewModel) path.getLastPathComponent(); + final GroupTreeNodeViewModel node = path == null ? null : (GroupTreeNodeViewModel) path + .getLastPathComponent(); if (e.isControlDown()) { switch (keyCode) { @@ -1464,7 +1472,8 @@ public void setupMainPanel() { adjustSplitter(); // restore last splitting state (before mainTable is created as creation affects the stored size of the entryEditors) // check whether a mainTable already existed and a floatSearch was active - boolean floatSearchActive = (mainTable != null) && (this.tableModel.getSearchState() == MainTableDataModel.DisplayOption.FLOAT); + boolean floatSearchActive = (mainTable != null) + && (this.tableModel.getSearchState() == MainTableDataModel.DisplayOption.FLOAT); createMainTable(); @@ -1743,8 +1752,8 @@ public void entryEditorClosing(EntryEditor editor) { * Closes the entry editor or preview panel if it is showing the given entry. */ public void ensureNotShowingBottomPanel(BibEntry entry) { - if (((mode == BasePanelMode.SHOWING_EDITOR) && (currentEditor.getEntry() == entry)) || - ((mode == BasePanelMode.SHOWING_PREVIEW) && (currentPreview.getEntry() == entry))) { + if (((mode == BasePanelMode.SHOWING_EDITOR) && (currentEditor.getEntry() == entry)) + || ((mode == BasePanelMode.SHOWING_PREVIEW) && (currentPreview.getEntry() == entry))) { hideBottomComponent(); } } @@ -2307,19 +2316,13 @@ public SaveSelectedAction(SavePreferences.DatabaseSaveType saveType) { @Override public void action() throws SaveException { + Optional chosenFile = new NewFileDialogs(frame).withExtension(FileExtensions.BIBTEX_DB).saveNewFile(); - String chosenFile = FileDialogs.getNewFile(frame, - new File(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)), Collections.singletonList(".bib"), - JFileChooser.SAVE_DIALOG, false); - if (chosenFile != null) { - File expFile = new File(chosenFile); - if (!expFile.exists() || (JOptionPane.showConfirmDialog(frame, - Localization.lang("'%0' exists. Overwrite file?", expFile.getName()), - Localization.lang("Save database"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION)) { - saveDatabase(expFile, true, Globals.prefs.getDefaultEncoding(), saveType); - frame.getFileHistory().newFile(expFile.getPath()); - frame.output(Localization.lang("Saved selected to '%0'.", expFile.getPath())); - } + if (chosenFile.isPresent()) { + Path path = chosenFile.get(); + saveDatabase(path.toFile(), true, Globals.prefs.getDefaultEncoding(), saveType); + frame.getFileHistory().newFile(path.toString()); + frame.output(Localization.lang("Saved selected to '%0'.", path.toString())); } } } @@ -2329,6 +2332,7 @@ private static class SearchAndOpenFile { private final BibEntry entry; private final BasePanel basePanel; + public SearchAndOpenFile(final BibEntry entry, final BasePanel basePanel) { this.entry = entry; this.basePanel = basePanel; @@ -2394,6 +2398,7 @@ public Optional searchAndOpen() { } } + /** * Set the preview active state for all BasePanel instances. * diff --git a/src/main/java/net/sf/jabref/gui/EntryCustomizationDialog.java b/src/main/java/net/sf/jabref/gui/EntryCustomizationDialog.java index 3deb0b374f2..9c24e3b197d 100644 --- a/src/main/java/net/sf/jabref/gui/EntryCustomizationDialog.java +++ b/src/main/java/net/sf/jabref/gui/EntryCustomizationDialog.java @@ -324,7 +324,7 @@ private void applyChanges() { private void typeDeletion(String name) { Optional type = EntryTypes.getType(name, bibDatabaseContext.getMode()); - if (type.isPresent() && type.get() instanceof CustomEntryType) { + if (type.isPresent() && (type.get() instanceof CustomEntryType)) { if (! EntryTypes.getStandardType(name, bibDatabaseContext.getMode()).isPresent()) { int reply = JOptionPane.showConfirmDialog (frame, Localization.lang("All entries of this " @@ -378,7 +378,6 @@ public void actionPerformed(ActionEvent e) { } else if (e.getSource() == apply) { applyChanges(); } else if (e.getSource() == typeComp) { - //System.out.println("add: "+e.getActionCommand()); typeComp.selectField(e.getActionCommand()); } } diff --git a/src/main/java/net/sf/jabref/gui/FileDialogs.java b/src/main/java/net/sf/jabref/gui/FileDialogs.java deleted file mode 100644 index 0a050e0b890..00000000000 --- a/src/main/java/net/sf/jabref/gui/FileDialogs.java +++ /dev/null @@ -1,209 +0,0 @@ -/* Copyright (C) 2003-2015 JabRef contributors. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -package net.sf.jabref.gui; - -import java.io.File; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -import javax.swing.JComponent; -import javax.swing.JFileChooser; -import javax.swing.JFrame; - -import net.sf.jabref.Globals; -import net.sf.jabref.logic.util.OS; -import net.sf.jabref.preferences.JabRefPreferences; - -public class FileDialogs { - - /** - * Will return the names of multiple files selected in the given directory - * and the given extensions. - * - * Will return an empty String array if no entry is found. - * - * @param owner - * @param directory - * @param extensions - * @param updateWorkingdirectory - * @return an array of selected file paths, or an empty array if no selection is made. - */ - public static List getMultipleFiles(JFrame owner, File directory, List extensions, - boolean updateWorkingdirectory) { - - Objects.requireNonNull(extensions); - - OpenFileFilter off; - if (extensions.isEmpty()) { - off = new OpenFileFilter(); - } else { - off = new OpenFileFilter(extensions); - } - - Object files = FileDialogs.getNewFileImpl(owner, directory, extensions, null, off, JFileChooser.OPEN_DIALOG, - updateWorkingdirectory, false, true, null); - - if (files instanceof String[]) { - return Arrays.asList((String[]) files); - } - // Fix for: - // http://sourceforge.net/tracker/index.php?func=detail&aid=1538769&group_id=92314&atid=600306 - if (files != null) { - return Collections.singletonList((String) files); - } - return Collections.emptyList(); - } - - public static String getNewFile(JFrame owner, File directory, List extensions, int dialogType, boolean updateWorkingDirectory) { - return FileDialogs.getNewFile(owner, directory, extensions, null, dialogType, updateWorkingDirectory, false, null); - } - - public static String getNewFile(JFrame owner, File directory, List extensions, int dialogType, boolean updateWorkingDirectory, JComponent accessory) { - return FileDialogs.getNewFile(owner, directory, extensions, null, dialogType, updateWorkingDirectory, false, accessory); - } - - public static String getNewFile(JFrame owner, File directory, List extensions, String description, int dialogType, boolean updateWorkingDirectory) { - return FileDialogs.getNewFile(owner, directory, extensions, description, dialogType, updateWorkingDirectory, false, null); - } - - public static String getNewDir(JFrame owner, File directory, List extensions, int dialogType, boolean updateWorkingDirectory) { - return FileDialogs.getNewFile(owner, directory, extensions, null, dialogType, updateWorkingDirectory, true, null); - } - - public static String getNewDir(JFrame owner, File directory, List extensions, String description, int dialogType, boolean updateWorkingDirectory) { - return FileDialogs.getNewFile(owner, directory, extensions, description, dialogType, updateWorkingDirectory, true, null); - } - - private static String getNewFile(JFrame owner, File directory, List extensions, String description, int dialogType, boolean updateWorkingDirectory, boolean dirOnly, JComponent accessory) { - - OpenFileFilter off; - - if (extensions.isEmpty()) { - off = new OpenFileFilter(); - } else { - off = new OpenFileFilter(extensions); - } - - return (String) FileDialogs.getNewFileImpl(owner, directory, extensions, description, off, dialogType, updateWorkingDirectory, dirOnly, false, accessory); - } - - private static Object getNewFileImpl(JFrame owner, File directory, List extensions, String description, - OpenFileFilter off, int dialogType, boolean updateWorkingDirectory, boolean dirOnly, - boolean multipleSelection, JComponent accessory) { - - // Added the !dirOnly condition below as a workaround to the native file dialog - // not supporting directory selection: - if (!dirOnly && OS.OS_X) { - return FileDialogs.getNewFileForMac(owner, directory, dialogType, updateWorkingDirectory); - } - - JFileChooser fc; - try { - fc = new JFileChooser(directory);//JabRefFileChooser(directory); - if (accessory != null) { - fc.setAccessory(accessory); - } - } catch (InternalError errl) { - // This try/catch clause was added because a user reported an - // InternalError getting thrown on WinNT, presumably because of a - // bug in JGoodies Windows PLAF. This clause can be removed if the - // bug is fixed, but for now we just resort to the native file - // dialog, using the same method as is always used on Mac: - return FileDialogs.getNewFileForMac(owner, directory, dialogType, updateWorkingDirectory); - } - - if (dirOnly) { - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - } - - fc.setMultiSelectionEnabled(multipleSelection); - - fc.addChoosableFileFilter(off); - fc.setDialogType(dialogType); - int dialogResult; - if (dialogType == JFileChooser.OPEN_DIALOG) { - dialogResult = fc.showOpenDialog(owner); - } else if (dialogType == JFileChooser.SAVE_DIALOG) { - dialogResult = fc.showSaveDialog(owner); - } else { - dialogResult = fc.showDialog(owner, description); - } - - // the getSelectedFile method returns a valid fileselection - // (if something is selected) indepentently from dialog return status - if (dialogResult != JFileChooser.APPROVE_OPTION) { - return null; - } - - // okay button - File selectedFile = fc.getSelectedFile(); - if (selectedFile == null) { // cancel - return null; - } - - // If this is a save dialog, and the user has not chosen "All files" as - // filter - // we enforce the given extension. But only if extension is not null. - if ((!extensions.isEmpty()) && (dialogType == JFileChooser.SAVE_DIALOG) && (fc.getFileFilter() == off) && !off.accept(selectedFile)) { - - // add the first extension if there are multiple extensions - selectedFile = new File(selectedFile.getPath() + extensions.get(0)); - } - - if (updateWorkingDirectory) { - Globals.prefs.put(JabRefPreferences.WORKING_DIRECTORY, selectedFile.getPath()); - } - - if (multipleSelection) { - File[] files = fc.getSelectedFiles(); - String[] filenames = new String[files.length]; - for (int i = 0; i < files.length; i++) { - filenames[i] = files[i].getAbsolutePath(); - } - return filenames; - } else { - return selectedFile.getAbsolutePath(); - } - } - - private static String getNewFileForMac(JFrame owner, File directory, int dialogType, - boolean updateWorkingDirectory) { - - java.awt.FileDialog fc = new java.awt.FileDialog(owner); - - if (directory != null) { - fc.setDirectory(directory.getParent()); - } - if (dialogType == JFileChooser.OPEN_DIALOG) { - fc.setMode(java.awt.FileDialog.LOAD); - } else { - fc.setMode(java.awt.FileDialog.SAVE); - } - - fc.setVisible(true); - - if (fc.getFile() == null) { - return null; - } else { - if (updateWorkingDirectory) { - Globals.prefs.put(JabRefPreferences.WORKING_DIRECTORY, fc.getDirectory() + fc.getFile()); - } - return fc.getDirectory() + fc.getFile(); - } - } -} diff --git a/src/main/java/net/sf/jabref/gui/FileExtensions.java b/src/main/java/net/sf/jabref/gui/FileExtensions.java new file mode 100644 index 00000000000..0e1e49c15d8 --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/FileExtensions.java @@ -0,0 +1,68 @@ +package net.sf.jabref.gui; + +import net.sf.jabref.logic.l10n.Localization; + +/** + * + * + *This enum contains all kind of file extensions for open and save dialogs + *Important: Enter the extension without a dot! + *The dot is added implicit + */ +public enum FileExtensions { + + //important: No dot before the extension! + BIBTEX_DB( + String.format("%1s %2s", "BibTex", Localization.lang("Database")), "bib"), + BIBTEXML( + Localization.lang("%0 file", "BibTeXML"), "bibx"), + AUX( + Localization.lang("%0 file", "AUX"), "aux"), + SILVER_PLATTERN( + Localization.lang("%0 file", "SilverPlatter"), "dat"), + PUBMED( + Localization.lang("%0 file", "PubMed"), "fcgi"), + RIS( + Localization.lang("%0 file", "RIS"), "ris"), + ENDNOTE( + Localization.lang("%0 file", "Endnote/Refer"), "ref"), + JSTYLE( + Localization.lang("Style file"), "jstyle"), + LAYOUT( + Localization.lang("Custom layout file"), "layout"), + XML( + Localization.lang("%0 file", "XML"), "xml"), + TERMS( + Localization.lang("Protected terms file"), "terms"), + TXT( + Localization.lang("%0 file", Localization.lang("plain text")), "txt"), + CLASS( + Localization.lang("%0 file", "CLASS"), "class"), + JAR( + Localization.lang("%0 file", "JAR"), "jar"), + ZIP( + Localization.lang("%0 file", "ZIP"), "zip"); + + private final String[] extension; + private final String description; + + + private FileExtensions(String description, String... extension) { + this.extension = extension; + this.description = description; + } + + //Array because a) is varags and b) gets passed as varags parameter to FileExtensionNameFilter + public String[] getExtensions() { + return extension; + } + + public String getDescription() { + + return description; + } + + public String getFirstExtensionWithDot() { + return "." + extension[0].trim(); + } +} diff --git a/src/main/java/net/sf/jabref/gui/FileListEntryEditor.java b/src/main/java/net/sf/jabref/gui/FileListEntryEditor.java index 7d6ebfb45d5..b158594c965 100644 --- a/src/main/java/net/sf/jabref/gui/FileListEntryEditor.java +++ b/src/main/java/net/sf/jabref/gui/FileListEntryEditor.java @@ -22,8 +22,8 @@ import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.regex.Pattern; @@ -37,13 +37,10 @@ import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JProgressBar; import javax.swing.JTextField; import javax.swing.SwingConstants; -import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -89,19 +86,24 @@ public class FileListEntryEditor { private ConfirmCloseFileListEntryEditor externalConfirm; private FileListEntry entry; - private final BibDatabaseContext databaseContext; + //Do not make this variable final, as then the lambda action listener will fail on compiöe + private BibDatabaseContext databaseContext; private boolean okPressed; private boolean okDisabledExternally; private boolean openBrowseWhenShown; private boolean dontOpenBrowseUntilDisposed; + //Do not make this variable final, as then the lambda action listener will fail on compile + private JabRefFrame frame; + private static final Pattern REMOTE_LINK_PATTERN = Pattern.compile("[a-z]+://.*"); - public FileListEntryEditor(JabRefFrame frame, FileListEntry entry, boolean showProgressBar, - boolean showOpenButton, BibDatabaseContext databaseContext) { + public FileListEntryEditor(JabRefFrame frame, FileListEntry entry, boolean showProgressBar, boolean showOpenButton, + BibDatabaseContext databaseContext) { this.entry = entry; this.databaseContext = databaseContext; + this.frame = frame; ActionListener okAction = e -> { // If OK button is disabled, ignore this event: @@ -127,27 +129,28 @@ public FileListEntryEditor(JabRefFrame frame, FileListEntry entry, boolean showP } }); - FormBuilder builder = FormBuilder.create().layout(new FormLayout - ("left:pref, 4dlu, fill:150dlu, 4dlu, fill:pref, 4dlu, fill:pref", "p, 2dlu, p, 2dlu, p")); + FormBuilder builder = FormBuilder.create().layout(new FormLayout( + "left:pref, 4dlu, fill:150dlu, 4dlu, fill:pref, 4dlu, fill:pref", "p, 2dlu, p, 2dlu, p")); builder.add(Localization.lang("Link")).xy(1, 1); builder.add(link).xy(3, 1); - final BrowseListener browse = new BrowseListener(frame, link); + //final BrowseListener browse = new BrowseListener(frame, link); //TODO: Maybe use browse action + final JButton browseBut = new JButton(Localization.lang("Browse")); - browseBut.addActionListener(browse); + browseBut.addActionListener(browsePressed); builder.add(browseBut).xy(5, 1); JButton open = new JButton(Localization.lang("Open")); if (showOpenButton) { builder.add(open).xy(7, 1); } builder.add(Localization.lang("Description")).xy(1, 3); - builder.add(description).xyw(3,3,3); + builder.add(description).xyw(3, 3, 3); builder.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); builder.add(Localization.lang("File type")).xy(1, 5); builder.add(types).xyw(3, 5, 3); if (showProgressBar) { builder.appendRows("2dlu, p"); - builder.add(downloadLabel).xy(1,7); - builder.add(prog).xyw(3,7,3); + builder.add(downloadLabel).xy(1, 7); + builder.add(prog).xyw(3, 7, 3); } ButtonBarBuilder bb = new ButtonBarBuilder(); @@ -167,6 +170,7 @@ public FileListEntryEditor(JabRefFrame frame, FileListEntry entry, boolean showP open.addActionListener(e -> openFile()); AbstractAction cancelAction = new AbstractAction() { + @Override public void actionPerformed(ActionEvent e) { diag.dispose(); @@ -210,7 +214,7 @@ public void changedUpdate(DocumentEvent documentEvent) { public void windowActivated(WindowEvent event) { if (openBrowseWhenShown && !dontOpenBrowseUntilDisposed) { dontOpenBrowseUntilDisposed = true; - SwingUtilities.invokeLater(() -> browse.actionPerformed(new ActionEvent(browseBut, 0, ""))); + // SwingUtilities.invokeLater(() -> browse.actionPerformed(new ActionEvent(browseBut, 0, ""))); } } @@ -288,8 +292,7 @@ public boolean isVisible() { private void setValues(FileListEntry entry) { description.setText(entry.description); link.setText(entry.link); - //if (link.getText().length() > 0) - // checkExtension(); + Collection list = ExternalFileTypes.getInstance().getExternalFileTypeSelection(); types.setModel(new DefaultComboBoxModel<>(list.toArray(new ExternalFileType[list.size()]))); @@ -345,41 +348,31 @@ public boolean okPressed() { } - class BrowseListener implements ActionListener { - private final JFrame parent; - private final JTextField comp; - - public BrowseListener(JFrame parent, JTextField comp) { - this.parent = parent; - this.comp = comp; + private final ActionListener browsePressed = e -> { + String filePath = link.getText().trim(); + Optional file = FileUtil.expandFilename(this.databaseContext, filePath); + String workingDir; + // no file set yet or found + if (file.isPresent()) { + workingDir = file.get().getPath(); + } else { + workingDir = Globals.prefs.get(JabRefPreferences.FILE_WORKING_DIRECTORY); } - @Override - public void actionPerformed(ActionEvent e) { - String filePath = comp.getText().trim(); - Optional file = FileUtil.expandFilename(databaseContext, filePath); - File workingDir; - // no file set yet or found - if (file.isPresent()) { - workingDir = new File(file.get().getParent()); - } else { - workingDir = new File(Globals.prefs.get(JabRefPreferences.FILE_WORKING_DIRECTORY)); - } - String selection = FileDialogs.getNewFile(parent, workingDir, Collections.emptyList(), - JFileChooser.OPEN_DIALOG, false); - if (selection != null) { - File newFile = new File(selection); - // Store the directory for next time: - Globals.prefs.put(JabRefPreferences.FILE_WORKING_DIRECTORY, newFile.getParent()); - - // If the file is below the file directory, make the path relative: - List fileDirs = databaseContext.getFileDirectory(); - newFile = FileUtil.shortenFileName(newFile, fileDirs); - - comp.setText(newFile.getPath()); - comp.requestFocus(); - } - } - } + Optional path = new NewFileDialogs(this.frame, workingDir).openDlgAndGetSelectedFile(); + + path.ifPresent(selection -> { + File newFile = selection.toFile(); + // Store the directory for next time: + Globals.prefs.put(JabRefPreferences.FILE_WORKING_DIRECTORY, newFile.getPath()); + + // If the file is below the file directory, make the path relative: + List fileDirs = this.databaseContext.getFileDirectory(); + newFile = FileUtil.shortenFileName(newFile, fileDirs); + + link.setText(newFile.getPath()); + link.requestFocus(); + }); + }; } diff --git a/src/main/java/net/sf/jabref/gui/NewFileDialogs.java b/src/main/java/net/sf/jabref/gui/NewFileDialogs.java new file mode 100644 index 00000000000..18d2b98d22b --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/NewFileDialogs.java @@ -0,0 +1,184 @@ +package net.sf.jabref.gui; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.filechooser.FileNameExtensionFilter; + +import net.sf.jabref.Globals; +import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.preferences.JabRefPreferences; + +public class NewFileDialogs { + + /** + * Custom confirmation dialog + * http://stackoverflow.com/a/3729157 + */ + private final JFileChooser fileChooser = new JFileChooser() { + + @Override + public void approveSelection() { + File file = getSelectedFile(); + if (file.exists() && (getDialogType() == SAVE_DIALOG)) { + int result = JOptionPane.showConfirmDialog(this, + Localization.lang("'%0' exists. Overwrite file?", file.getName()), + Localization.lang("Existing file"), JOptionPane.YES_NO_CANCEL_OPTION); + switch (result) { + case JOptionPane.YES_OPTION: + super.approveSelection(); + return; + case JOptionPane.NO_OPTION: + return; + case JOptionPane.CLOSED_OPTION: + return; + case JOptionPane.CANCEL_OPTION: + cancelSelection(); + return; + default: + return; + } + } + super.approveSelection(); + } + }; + + private final JFrame parent; + private final String directory; + private FileNameExtensionFilter extFilter; + private Collection extensions = EnumSet.noneOf(FileExtensions.class); + + + /** + * Creates a new filedialog showing the current working dir {@link JabRefPreferences#WORKING_DIRECTORY} + * @param parent The parent frame associated with this dialog + */ + public NewFileDialogs(JFrame parent) { + this(parent, getWorkingDir()); + } + + /** + * Creates a new dialog in the given directory + * @param parent The parent frame associated with this dialog + * @param dir The starting directory to show in the dialog + */ + public NewFileDialogs(JFrame parent, String dir) { + Objects.requireNonNull(dir, "Directory must not be null"); + + this.parent = parent; + this.directory = dir; + fileChooser.setCurrentDirectory(Paths.get(dir).toFile()); + } + + /** + * Show only directories instead of files and folders + * @return NewFileDialogs + */ + public NewFileDialogs dirsOnly() { + fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + return this; + } + + /** + * Add a single extension as filter + * @param singleExt The extension + * @return NewFileDialogs + */ + public NewFileDialogs withExtension(FileExtensions singleExt) { + withExtensions(EnumSet.of(singleExt)); + return this; + } + + public NewFileDialogs withExtensions(Collection fileExtensions) { + this.extensions = fileExtensions; + + for (FileExtensions ext : fileExtensions) { + extFilter = new FileNameExtensionFilter(ext.getDescription(), ext.getExtensions()); + fileChooser.addChoosableFileFilter(extFilter); + } + + return this; + } + + /** + * Updates the working directory preference + * @return NewFileDialogs + */ + public NewFileDialogs updateWorkingDirPref() { + Globals.prefs.put(JabRefPreferences.WORKING_DIRECTORY, this.directory); + return this; + } + + /** + * Shows an {@link JFileChooser#OPEN_DIALOG} and allows to select multiple files + * @return List containing the paths of all files or an empty list if dialog is canceled + */ + public List showDlgAndGetMultipleFiles() { + fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); + fileChooser.setMultiSelectionEnabled(true); + + if (showDialogAndIsAccepted()) { + List files = Arrays.stream(fileChooser.getSelectedFiles()).map(File::toString) + .collect(Collectors.toList()); + + return files; + } + + return Collections.emptyList(); + + } + + /** + * Shows an {@link JFileChooser#OPEN_DIALOG} and allows to select a single file/folder + * @return The path of the selected file/folder or {@link Optional#empty()} if dialog is aborted + */ + public Optional openDlgAndGetSelectedFile() { + fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); + + if (showDialogAndIsAccepted()) { + return Optional.of(fileChooser.getSelectedFile().toPath()); + } + return Optional.empty(); + } + + /** + * + * Shows an {@link JFileChooser#SAVE_DIALOG} and allows to save a new file
+ * If an extension is provided, adds the extension to the file
+ * Selecting an existing file will show an overwrite dialog + * @return The path of the new file, or {@link Optional#empty()} if dialog is aborted + */ + public Optional saveNewFile() { + fileChooser.setDialogType(JFileChooser.SAVE_DIALOG); + if (showDialogAndIsAccepted()) { + File file = fileChooser.getSelectedFile(); + if (!extensions.isEmpty() && !fileChooser.accept(file)) { + + return Optional.of(Paths.get(file.getPath() + extensions.iterator().next().getFirstExtensionWithDot())); + } + return Optional.of(file.toPath()); + } + return Optional.empty(); + } + + private boolean showDialogAndIsAccepted() { + return fileChooser.showDialog(parent, null) == JFileChooser.APPROVE_OPTION; + } + + private static String getWorkingDir() { + return Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY); + } + +} diff --git a/src/main/java/net/sf/jabref/gui/OpenFileFilter.java b/src/main/java/net/sf/jabref/gui/OpenFileFilter.java deleted file mode 100644 index c5a8fbb9150..00000000000 --- a/src/main/java/net/sf/jabref/gui/OpenFileFilter.java +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright (C) 2003-2015 JabRef contributors. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -package net.sf.jabref.gui; - -import java.io.File; -import java.io.FilenameFilter; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class OpenFileFilter extends javax.swing.filechooser.FileFilter implements FilenameFilter { - - private final Set extSet = new HashSet<>(); - private final String desc; - - - public OpenFileFilter(List extensions) { - StringBuilder buf = new StringBuilder(); - int numExt = extensions.size(); - - if (numExt > 0) { - buf.append('*'); - buf.append(extensions.get(0)); - - extSet.add(extensions.get(0)); - } - - for (int curExt = 1; curExt < numExt; curExt++) { - buf.append(", *"); - buf.append(extensions.get(curExt)); - - extSet.add(extensions.get(curExt)); - } - - desc = buf.toString(); - } - - public OpenFileFilter() { - this(Arrays.asList( - ".bib", - ".dat", // silverplatter ending - ".txt", // windows puts ".txt" extensions and for scifinder - ".ris", - ".ref", // refer/endnote format - ".fcgi", // default for pubmed - ".bibx", // default for BibTeXML - ".xml" - )); - } - - @Override - public boolean accept(File file) { - if (file.isDirectory()) { - return true; - } - - return accept(file.getName()); - } - - private boolean accept(String filename) { - - String lowerCaseFileName = filename.toLowerCase(); - int dotPos = lowerCaseFileName.lastIndexOf('.'); - - if (dotPos == -1) { - return false; - } - - int dotDotPos = lowerCaseFileName.lastIndexOf('.', dotPos - 1); // for dot.dot extensions - - return extSet.contains(lowerCaseFileName.substring(dotPos)) || - ((dotDotPos >= 0) && extSet.contains(lowerCaseFileName.substring(dotDotPos))); - } - - @Override - public String getDescription() { - return desc; - } - - @Override - public boolean accept(File dir, String name) { - return accept(new File(dir.getPath() + name)); - } -} diff --git a/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java b/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java index 88f5757e662..61ed52997f9 100644 --- a/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java +++ b/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java @@ -17,57 +17,60 @@ import java.awt.event.ActionEvent; import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Collections; -import java.util.List; +import java.util.EnumSet; +import java.util.Set; import javax.swing.AbstractAction; -import javax.swing.JComponent; -import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JTextField; -import net.sf.jabref.gui.FileDialogs; -import net.sf.jabref.gui.util.FocusRequester; +import net.sf.jabref.gui.FileExtensions; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.logic.l10n.Localization; - /** * Action used to produce a "Browse" button for one of the text fields. */ public final class BrowseAction extends AbstractAction { + private final JFrame frame; private final JTextField comp; - private final boolean dir; - private final JComponent focusTarget; - private final List extension; + private final boolean dirsOnly; + private final Set extensions; + public static BrowseAction buildForDir(JFrame frame, JTextField tc) { - return new BrowseAction(frame, tc, true, null, Collections.emptyList()); + return new BrowseAction(frame, tc, true, Collections.emptySet()); } public static BrowseAction buildForDir(JTextField tc) { - return new BrowseAction(null, tc, true, null, Collections.emptyList()); + return new BrowseAction(null, tc, true, Collections.emptySet()); } public static BrowseAction buildForFile(JTextField tc) { - return new BrowseAction(null, tc, false, null, Collections.emptyList()); + + return new BrowseAction(null, tc, false, Collections.emptySet()); } - public static BrowseAction buildForFile(JTextField tc, JComponent focusTarget, List extension) { - return new BrowseAction(null, tc, false, focusTarget, extension); -} + public static BrowseAction buildForFile(JTextField tc, FileExtensions extensions) { - public static BrowseAction buildForDir(JTextField tc, JComponent focusTarget) { - return new BrowseAction(null, tc, true, focusTarget, null); + return new BrowseAction(null, tc, false, EnumSet.of(extensions)); } - private BrowseAction(JFrame frame, JTextField tc, boolean dir, JComponent focusTarget, List extension) { + public static BrowseAction buildForFile(JTextField tc, Set extensions) { + return new BrowseAction(null, tc, false, extensions); + } + + + private BrowseAction(JFrame frame, JTextField tc, boolean dirsOnly, Set extensions) { super(Localization.lang("Browse")); this.frame = frame; - this.dir = dir; + this.dirsOnly = dirsOnly; this.comp = tc; - this.focusTarget = focusTarget; - this.extension = extension; + this.extensions = extensions; } @Override @@ -77,19 +80,23 @@ public void actionPerformed(ActionEvent e) { if (chosen != null) { File newFile = new File(chosen); comp.setText(newFile.getPath()); - if (focusTarget != null) { - new FocusRequester(focusTarget); - } + } } private String askUser() { - if (dir) { - return FileDialogs.getNewDir(frame, new File(comp.getText()), extension, - JFileChooser.OPEN_DIALOG, false); + if (dirsOnly) { + Path path = new NewFileDialogs(frame, comp.getText()).dirsOnly().withExtensions(extensions) + .openDlgAndGetSelectedFile().orElse(Paths.get("")); + String file = path.toString(); + + return file; } else { - return FileDialogs.getNewFile(frame, new File(comp.getText()), extension, - JFileChooser.OPEN_DIALOG, false); + Path path = new NewFileDialogs(frame, comp.getText()).withExtensions(extensions) + .openDlgAndGetSelectedFile().orElse(Paths.get("")); + String file = path.toString(); + + return file; } } } diff --git a/src/main/java/net/sf/jabref/gui/auximport/FromAuxDialog.java b/src/main/java/net/sf/jabref/gui/auximport/FromAuxDialog.java index 809fbbf4c3b..a00264be8be 100644 --- a/src/main/java/net/sf/jabref/gui/auximport/FromAuxDialog.java +++ b/src/main/java/net/sf/jabref/gui/auximport/FromAuxDialog.java @@ -38,8 +38,6 @@ import java.awt.BorderLayout; import java.awt.event.ActionEvent; -import java.io.File; -import java.util.Collections; import javax.swing.AbstractAction; import javax.swing.ActionMap; @@ -49,7 +47,6 @@ import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; @@ -60,8 +57,9 @@ import net.sf.jabref.Globals; import net.sf.jabref.gui.BasePanel; -import net.sf.jabref.gui.FileDialogs; +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.actions.BrowseAction; import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.logic.auxparser.AuxParser; import net.sf.jabref.logic.auxparser.AuxParserResult; @@ -73,6 +71,7 @@ import com.jgoodies.forms.layout.FormLayout; public class FromAuxDialog extends JDialog { + private final JPanel statusPanel = new JPanel(); private final JPanel buttons = new JPanel(); private final JButton generateButton = new JButton(); @@ -95,8 +94,7 @@ public class FromAuxDialog extends JDialog { private final JabRefFrame parentFrame; - public FromAuxDialog(JabRefFrame frame, String title, boolean modal, - JTabbedPane viewedDBs) { + public FromAuxDialog(JabRefFrame frame, String title, boolean modal, JTabbedPane viewedDBs) { super(frame, title, modal); parentTabbedPane = viewedDBs; @@ -141,9 +139,11 @@ private void jbInit() { this.setTitle(Localization.lang("AUX file import")); JLabel desc = new JLabel("

" + Localization.lang("AUX file import") + "

" + Localization.lang("This feature generates a new database based on which entries " - + "are needed in an existing LaTeX document.") + "

" - + "

" + Localization.lang("You need to select one of your open databases from which to choose " - + "entries, as well as the AUX file produced by LaTeX when compiling your document.") + "

"); + + "are needed in an existing LaTeX document.") + + "

" + "

" + + Localization.lang("You need to select one of your open databases from which to choose " + + "entries, as well as the AUX file produced by LaTeX when compiling your document.") + + "

"); desc.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); panel1.add(desc, BorderLayout.NORTH); @@ -160,6 +160,7 @@ private void jbInit() { 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(); @@ -184,15 +185,15 @@ private void initPanels() { auxFileField = new JTextField("", 25); JButton browseAuxFileButton = new JButton(Localization.lang("Browse")); - browseAuxFileButton.addActionListener(new BrowseAction(auxFileField, parentFrame)); + browseAuxFileButton.addActionListener(BrowseAction.buildForFile(auxFileField, FileExtensions.AUX)); 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); + 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 database") + ":"); b.append(dbChooser, 3); @@ -202,8 +203,8 @@ private void initPanels() { 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 = 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") + ":"); @@ -249,28 +250,4 @@ public BibDatabase getGenerateDB() { return auxParser.parse().getGeneratedBibDatabase(); } - /** - * Action used to produce a "Browse" button for one of the text fields. - */ - static class BrowseAction extends AbstractAction { - private final JTextField comp; - private final JabRefFrame frame; - - - public BrowseAction(JTextField tc, JabRefFrame frame) { - super(Localization.lang("Browse")); - this.frame = frame; - comp = tc; - } - - @Override - public void actionPerformed(ActionEvent e) { - String chosen = FileDialogs.getNewFile(frame, new File(comp.getText()), Collections.singletonList(".aux"), - JFileChooser.OPEN_DIALOG, false); - if (chosen != null) { - File newFile = new File(chosen); - comp.setText(newFile.getPath()); - } - } - } } diff --git a/src/main/java/net/sf/jabref/gui/exporter/CustomExportDialog.java b/src/main/java/net/sf/jabref/gui/exporter/CustomExportDialog.java index 706bf9c00ee..15cf0b4ba89 100644 --- a/src/main/java/net/sf/jabref/gui/exporter/CustomExportDialog.java +++ b/src/main/java/net/sf/jabref/gui/exporter/CustomExportDialog.java @@ -21,8 +21,9 @@ import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.io.File; -import java.util.Collections; + +import java.nio.file.Path; +import java.nio.file.Paths; import javax.swing.AbstractAction; import javax.swing.ActionMap; @@ -31,25 +32,29 @@ import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import net.sf.jabref.Globals; -import net.sf.jabref.gui.FileDialogs; +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.actions.BrowseAction; import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.preferences.JabRefPreferences; import com.jgoodies.forms.builder.ButtonBarBuilder; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Dialog for creating or modifying custom exports. */ class CustomExportDialog extends JDialog { + private static final Log LOGGER = LogFactory.getLog(CustomExportDialog.class); + private final JTextField name = new JTextField(60); private final JTextField layoutFile = new JTextField(60); private final JTextField extension = new JTextField(60); @@ -67,15 +72,17 @@ public CustomExportDialog(final JabRefFrame parent, final String exporterName, f public CustomExportDialog(final JabRefFrame parent) { super(parent, Localization.lang("Edit custom export"), true); ActionListener okListener = e -> { + Path layoutFileDir = Paths.get(layoutFile.getText()).getParent(); + if (layoutFileDir != null) { + Globals.prefs.put(JabRefPreferences.EXPORT_WORKING_DIRECTORY, layoutFileDir.toString()); + + } // Check that there are no empty strings. if (layoutFile.getText().isEmpty() || name.getText().isEmpty() || extension.getText().isEmpty() || !layoutFile.getText().endsWith(".layout")) { - //JOptionPane.showMessageDialog - // (parent, Globals.lang("You must provide a name, a search " - // +"string and a field name for this group."), - // Globals.lang("Create group"), - // JOptionPane.ERROR_MESSAGE); + + LOGGER.info("One field is empty!"); //TODO: Better error message return; } @@ -84,12 +91,21 @@ public CustomExportDialog(final JabRefFrame parent) { okPressed = true; dispose(); }; + + layoutFile.setText(Globals.prefs.get(JabRefPreferences.EXPORT_WORKING_DIRECTORY)); + JButton ok = new JButton(Localization.lang("OK")); ok.addActionListener(okListener); name.addActionListener(okListener); layoutFile.addActionListener(okListener); extension.addActionListener(okListener); + JButton cancel = new JButton(Localization.lang("Cancel")); + cancel.addActionListener(e -> dispose()); + + JButton browse = new JButton(Localization.lang("Browse")); + browse.addActionListener(BrowseAction.buildForFile(layoutFile, FileExtensions.LAYOUT)); + AbstractAction cancelAction = new AbstractAction() { @Override @@ -97,26 +113,6 @@ public void actionPerformed(ActionEvent e) { dispose(); } }; - - JButton cancel = new JButton(Localization.lang("Cancel")); - cancel.addActionListener(cancelAction); - - JButton browse = new JButton(Localization.lang("Browse")); - browse.addActionListener(e -> { - File directory = new File(Globals.prefs.get(JabRefPreferences.EXPORT_WORKING_DIRECTORY)); - String chosenStr = FileDialogs.getNewFile(parent, directory, Collections.singletonList(".layout"), - JFileChooser.OPEN_DIALOG, false); - if (chosenStr == null) { - return; - } - File chosen = new File(chosenStr); - - // Update working directory for layout files. - Globals.prefs.put(JabRefPreferences.EXPORT_WORKING_DIRECTORY, chosen.getParent()); - - layoutFile.setText(chosen.getPath()); - }); - // Key bindings: JPanel main = new JPanel(); ActionMap am = main.getActionMap(); @@ -127,9 +123,8 @@ public void actionPerformed(ActionEvent e) { // Layout starts here. GridBagLayout gbl = new GridBagLayout(); main.setLayout(gbl); - main.setBorder(BorderFactory.createTitledBorder - (BorderFactory.createEtchedBorder(), - Localization.lang("Export properties"))); + main.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), + Localization.lang("Export properties"))); // Main panel: GridBagConstraints con = new GridBagConstraints(); diff --git a/src/main/java/net/sf/jabref/gui/exporter/SaveDatabaseAction.java b/src/main/java/net/sf/jabref/gui/exporter/SaveDatabaseAction.java index a36a6593518..c9df0c01c38 100644 --- a/src/main/java/net/sf/jabref/gui/exporter/SaveDatabaseAction.java +++ b/src/main/java/net/sf/jabref/gui/exporter/SaveDatabaseAction.java @@ -20,9 +20,9 @@ import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; -import java.util.Collections; +import java.nio.file.Path; +import java.util.Optional; -import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JTextArea; import javax.swing.SwingUtilities; @@ -31,8 +31,9 @@ import net.sf.jabref.JabRefExecutorService; import net.sf.jabref.collab.ChangeScanner; import net.sf.jabref.gui.BasePanel; -import net.sf.jabref.gui.FileDialogs; +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.gui.worker.AbstractWorker; import net.sf.jabref.gui.worker.CallBack; import net.sf.jabref.gui.worker.Worker; @@ -68,6 +69,7 @@ public class SaveDatabaseAction extends AbstractWorker { private static final Log LOGGER = LogFactory.getLog(SaveDatabaseAction.class); + public SaveDatabaseAction(BasePanel panel) { this.panel = panel; this.frame = panel.frame(); @@ -96,8 +98,10 @@ public void init() throws Throwable { public void update() { if (success) { // Reset title of tab - frame.setTabTitle(panel, panel.getTabTitle(), panel.getBibDatabaseContext().getDatabaseFile().getAbsolutePath()); - frame.output(Localization.lang("Saved database") + " '" + panel.getBibDatabaseContext().getDatabaseFile().getPath() + "'."); + frame.setTabTitle(panel, panel.getTabTitle(), + panel.getBibDatabaseContext().getDatabaseFile().getAbsolutePath()); + frame.output(Localization.lang("Saved database") + " '" + + panel.getBibDatabaseContext().getDatabaseFile().getPath() + "'."); frame.setWindowTitle(); frame.updateAllTabTitles(); } else if (!canceled) { @@ -173,7 +177,7 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) frame.block(); try { SavePreferences prefs = SavePreferences.loadForSaveFromPreferences(Globals.prefs).withEncoding(encoding); - BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(FileSaveSession::new); + BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter<>(FileSaveSession::new); if (selectedOnly) { session = databaseWriter.savePartOfDatabase(panel.getBibDatabaseContext(), panel.getSelectedEntries(), prefs); @@ -184,8 +188,9 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) panel.registerUndoableChanges(session); } catch (UnsupportedCharsetException ex2) { - JOptionPane.showMessageDialog(frame, Localization.lang("Could not save file.") + - Localization.lang("Character encoding '%0' is not supported.", encoding.displayName()), + JOptionPane.showMessageDialog(frame, + Localization.lang("Could not save file.") + + Localization.lang("Character encoding '%0' is not supported.", encoding.displayName()), Localization.lang("Save database"), JOptionPane.ERROR_MESSAGE); throw new SaveException("rt"); } catch (SaveException ex) { @@ -204,11 +209,8 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) LOGGER.error("Problem saving file", ex); } - JOptionPane.showMessageDialog - (frame, Localization.lang("Could not save file.") - + ".\n" + ex.getMessage(), - Localization.lang("Save database"), - JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(frame, Localization.lang("Could not save file.") + ".\n" + ex.getMessage(), + Localization.lang("Save database"), JOptionPane.ERROR_MESSAGE); throw new SaveException("rt"); } finally { @@ -217,7 +219,8 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) boolean commit = true; if (!session.getWriter().couldEncodeAll()) { - FormBuilder builder = FormBuilder.create().layout(new FormLayout("left:pref, 4dlu, fill:pref", "pref, 4dlu, pref")); + FormBuilder builder = FormBuilder.create() + .layout(new FormLayout("left:pref, 4dlu, fill:pref", "pref, 4dlu, pref")); JTextArea ta = new JTextArea(session.getWriter().getProblemCharacters()); ta.setEditable(false); builder.add(Localization.lang("The chosen encoding '%0' could not encode the following characters:", @@ -227,8 +230,7 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) String tryDiff = Localization.lang("Try different encoding"); int answer = JOptionPane.showOptionDialog(frame, builder.getPanel(), Localization.lang("Save database"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, - new String[] {Localization.lang("Save"), tryDiff, - Localization.lang("Cancel")}, tryDiff); + new String[] {Localization.lang("Save"), tryDiff, Localization.lang("Cancel")}, tryDiff); if (answer == JOptionPane.NO_OPTION) { // The user wants to use another encoding. @@ -255,10 +257,10 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset encoding) session.cancel(); } } catch (SaveException e) { - int ans = JOptionPane.showConfirmDialog(null, Localization.lang("Save failed during backup creation") + ". " - + Localization.lang("Save without backup?"), - Localization.lang("Unable to create backup"), - JOptionPane.YES_NO_OPTION); + int ans = JOptionPane.showConfirmDialog(null, + Localization.lang("Save failed during backup creation") + ". " + + Localization.lang("Save without backup?"), + Localization.lang("Unable to create backup"), JOptionPane.YES_NO_OPTION); if (ans == JOptionPane.YES_OPTION) { session.setUseBackup(false); session.commit(file.toPath()); @@ -306,27 +308,22 @@ public void save() throws Throwable { * still runs synchronously using Spin (the method returns only after completing the operation). */ public void saveAs() throws Throwable { - String chosenFile; - File f = null; - while (f == null) { - chosenFile = FileDialogs.getNewFile(frame, new File(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)), - Collections.singletonList(".bib"), JFileChooser.SAVE_DIALOG, false, null); - if (chosenFile == null) { + File file = null; + while (file == null) { + + Optional path = new NewFileDialogs(frame).withExtension(FileExtensions.BIBTEX_DB).saveNewFile(); + if (path.isPresent()) { + file = path.get().toFile(); + + } else { canceled = true; return; // canceled } - f = new File(chosenFile); - // Check if the file already exists: - if (f.exists() && (JOptionPane.showConfirmDialog(frame, - Localization.lang("'%0' exists. Overwrite file?", f.getName()), - Localization.lang("Save database"), JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION)) { - f = null; - } } File oldFile = panel.getBibDatabaseContext().getDatabaseFile(); - panel.getBibDatabaseContext().setDatabaseFile(f); - Globals.prefs.put(JabRefPreferences.WORKING_DIRECTORY, f.getParent()); + panel.getBibDatabaseContext().setDatabaseFile(file); + Globals.prefs.put(JabRefPreferences.WORKING_DIRECTORY, file.getParent()); runCommand(); // If the operation failed, revert the file field and return: if (!success) { @@ -372,7 +369,8 @@ public boolean isCanceled() { */ private boolean checkExternalModification() { // Check for external modifications: - if (panel.isUpdatedExternally() || Globals.getFileUpdateMonitor().hasBeenModified(panel.getFileMonitorHandle())) { + if (panel.isUpdatedExternally() + || Globals.getFileUpdateMonitor().hasBeenModified(panel.getFileMonitorHandle())) { String[] opts = new String[] {Localization.lang("Review changes"), Localization.lang("Save"), Localization.lang("Cancel")}; int answer = JOptionPane.showOptionDialog(panel.frame(), @@ -400,8 +398,7 @@ private boolean checkExternalModification() { scanner.displayResult(resolved -> { if (resolved) { panel.setUpdatedExternally(false); - SwingUtilities - .invokeLater(() -> panel.getSidePaneManager().hide("fileUpdate")); + SwingUtilities.invokeLater(() -> panel.getSidePaneManager().hide("fileUpdate")); } else { canceled = true; } diff --git a/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java b/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java index 928069bbd07..626639d09c9 100644 --- a/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java +++ b/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java @@ -22,6 +22,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -35,6 +36,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import javax.swing.AbstractAction; import javax.swing.Action; @@ -46,7 +48,6 @@ import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -57,12 +58,15 @@ import javax.swing.table.AbstractTableModel; import net.sf.jabref.Globals; -import net.sf.jabref.gui.FileDialogs; + import net.sf.jabref.gui.IconTheme; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.NewFileDialogs; +import net.sf.jabref.gui.actions.BrowseAction; import net.sf.jabref.gui.help.HelpAction; import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.gui.net.MonitoredURLDownload; + import net.sf.jabref.logic.help.HelpFile; import net.sf.jabref.logic.journals.Abbreviation; import net.sf.jabref.logic.journals.JournalAbbreviationLoader; @@ -186,45 +190,31 @@ public ManageJournalsPanel(final JabRefFrame frame) { journalEditPanel = builder2.getPanel(); viewBuiltin.addActionListener(e -> { - JTable table = new JTable(JournalAbbreviationsUtil - .getTableModel(Globals.journalAbbreviationLoader - .getRepository(JournalAbbreviationPreferences.fromPreferences(Globals.prefs)) - .getAbbreviations())); + JTable table = new JTable(JournalAbbreviationsUtil.getTableModel(Globals.journalAbbreviationLoader + .getRepository(JournalAbbreviationPreferences.fromPreferences(Globals.prefs)).getAbbreviations())); JScrollPane pane = new JScrollPane(table); JOptionPane.showMessageDialog(null, pane, Localization.lang("Journal list preview"), JOptionPane.INFORMATION_MESSAGE); }); browseNew.addActionListener(e -> { - String name; - if (!newNameTf.getText().isEmpty()) { - name = FileDialogs.getNewFile(frame, Paths.get(newNameTf.getText()).toFile(), Collections.emptyList(), JFileChooser.SAVE_DIALOG, - false); - } else { - name = FileDialogs.getNewFile(frame, null, Collections.emptyList(), JFileChooser.SAVE_DIALOG, false); - } - - if (name != null) { - newNameTf.setText(name); + Optional path = new NewFileDialogs(frame, newNameTf.getText()).saveNewFile(); + path.ifPresent(fileName -> { + newNameTf.setText(fileName.toString()); newFile.setSelected(true); - } + }); + }); browseOld.addActionListener(e -> { - String name; - if (!personalFile.getText().isEmpty()) { - name = FileDialogs.getNewFile(frame, Paths.get(personalFile.getText()).toFile(), - Collections.emptyList(), JFileChooser.OPEN_DIALOG, false); - } else { - name = FileDialogs.getNewFile(frame, null, Collections.emptyList(), JFileChooser.OPEN_DIALOG, false); - } + Optional path = new NewFileDialogs(frame, personalFile.getText()).openDlgAndGetSelectedFile(); - if (name != null) { - personalFile.setText(name); + path.ifPresent(fileName -> { + personalFile.setText(fileName.toString()); oldFile.setSelected(true); oldFile.setEnabled(true); setupUserTable(); - } + }); }); ok.addActionListener(e -> { @@ -420,19 +410,19 @@ public DownloadAction(JTextField tc) { public void actionPerformed(ActionEvent e) { String chosen; chosen = JOptionPane.showInputDialog(Localization.lang("Choose the URL to download."), ""); - if (chosen == null) { + if ((chosen == null) || comp.getText().isEmpty()) { return; } File toFile; try { - String toName = FileDialogs.getNewFile(frame, new File(System.getProperty("user.home")), - Collections.emptyList(), - JFileChooser.SAVE_DIALOG, false); - if (toName == null) { - return; + + Optional path = new NewFileDialogs(frame, System.getProperty("user.home")).saveNewFile(); + if (path.isPresent()) { + toFile = new File(path.get().toString()); } else { - toFile = new File(toName); + return; } + URL url = new URL(chosen); MonitoredURLDownload.buildMonitoredDownload(comp, url).downloadToFile(toFile); comp.setText(toFile.getPath()); @@ -444,34 +434,6 @@ public void actionPerformed(ActionEvent e) { } } - class BrowseAction extends AbstractAction { - - private final JTextField comp; - private final boolean dir; - - - public BrowseAction(JTextField tc, boolean dir) { - super(Localization.lang("Browse")); - this.dir = dir; - comp = tc; - } - - @Override - public void actionPerformed(ActionEvent e) { - String chosen; - if (dir) { - chosen = FileDialogs.getNewDir(frame, new File(comp.getText()), Collections.emptyList(), - JFileChooser.OPEN_DIALOG, false); - } else { - chosen = FileDialogs.getNewFile(frame, new File(comp.getText()), Collections.emptyList(), - JFileChooser.OPEN_DIALOG, false); - } - if (chosen != null) { - comp.setText(Paths.get(chosen).toString()); - } - } - } - class AbbreviationsTableModel extends AbstractTableModel implements ActionListener { private final String[] names = new String[] {Localization.lang("Journal name"), @@ -577,7 +539,7 @@ public void actionPerformed(ActionEvent e) { } } - class ExternalFileEntry { + private class ExternalFileEntry { private JPanel pan; private final JTextField tf; @@ -599,8 +561,7 @@ public ExternalFileEntry(String filename) { private void setupPanel() { tf.setEditable(false); - BrowseAction browseA = new BrowseAction(tf, false); - browse.addActionListener(browseA); + browse.addActionListener(BrowseAction.buildForFile(tf)); DownloadAction da = new DownloadAction(tf); download.addActionListener(da); FormBuilder builder = FormBuilder.create().layout(new FormLayout( @@ -623,9 +584,10 @@ private void setupPanel() { JOptionPane.showMessageDialog(null, pane, Localization.lang("Journal list preview"), JOptionPane.INFORMATION_MESSAGE); } catch (FileNotFoundException ex) { + LOGGER.debug("File not found", ex); + JOptionPane.showMessageDialog(null, Localization.lang("File '%0' not found", tf.getText()), Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); - LOGGER.debug("File not found", ex); } }); clear.addActionListener(e -> { diff --git a/src/main/java/net/sf/jabref/gui/openoffice/StyleSelectDialog.java b/src/main/java/net/sf/jabref/gui/openoffice/StyleSelectDialog.java index 27379646260..d69b64627d7 100644 --- a/src/main/java/net/sf/jabref/gui/openoffice/StyleSelectDialog.java +++ b/src/main/java/net/sf/jabref/gui/openoffice/StyleSelectDialog.java @@ -23,7 +23,6 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; -import java.util.Collections; import java.util.Objects; import java.util.Optional; @@ -52,6 +51,7 @@ import net.sf.jabref.external.ExternalFileType; import net.sf.jabref.external.ExternalFileTypes; import net.sf.jabref.external.UnknownExternalFileType; +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.IconTheme; import net.sf.jabref.gui.JabRefFrame; import net.sf.jabref.gui.PreviewPanel; @@ -485,7 +485,7 @@ public AddFileDialog() { super(diag, Localization.lang("Add style file"), true); JButton browse = new JButton(Localization.lang("Browse")); - browse.addActionListener(BrowseAction.buildForFile(newFile, null, Collections.singletonList(".jstyle"))); + browse.addActionListener(BrowseAction.buildForFile(newFile, FileExtensions.JSTYLE)); // Build content panel FormBuilder builder = FormBuilder.create(); diff --git a/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java b/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java index 80e7c47336a..0113689c0f5 100644 --- a/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java +++ b/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java @@ -69,8 +69,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.StringWriter; +import java.nio.file.Path; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -86,7 +86,6 @@ import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenu; @@ -113,9 +112,10 @@ import net.sf.jabref.Globals; import net.sf.jabref.gui.ClipBoardManager; import net.sf.jabref.gui.EntryMarker; -import net.sf.jabref.gui.FileDialogs; +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.IconTheme; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.gui.OSXCompatibleToolbar; import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.gui.undo.NamedCompound; @@ -195,7 +195,6 @@ private void jbInit() { typeStr.append(' ').append(Localization.lang("for")).append(' ').append(entry.getType()); } - this.setTitle(typeStr.toString()); getContentPane().add(panel1, BorderLayout.CENTER); @@ -284,7 +283,7 @@ private void initRawPanel() { JLabel desc = new JLabel("

" + Localization.lang("Plain text import") + "

" + Localization.lang("This is a simple copy and paste dialog. First load or paste some text into " - + "the text input area.
After that, you can mark text and assign it to a BibTeX field.") + + "the text input area.
After that, you can mark text and assign it to a BibTeX field.") + "

"); desc.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); @@ -309,16 +308,12 @@ private JPanel setUpFieldListPanel() { inputPanel.setBorder(titledBorder1); inputPanel.setMinimumSize(new Dimension(10, 10)); - JScrollPane fieldScroller = new JScrollPane(fieldList); - fieldScroller.setVerticalScrollBarPolicy( - JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); - + fieldScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); // insert buttons insertButton.addActionListener(event -> insertTextForTag(override.isSelected())); - // Radio buttons append.setToolTipText(Localization.lang("Append the selected text to BibTeX field")); append.setMnemonic(KeyEvent.VK_A); @@ -386,8 +381,6 @@ private void initPopupMenuAndToolbar() { inputMenu.add(appendMenu); inputMenu.add(overrideMenu); - - // Toolbar toolBar.add(clearAction); @@ -418,8 +411,7 @@ private void initSourcePanel() { sourcePreview.setEditable(false); sourcePreview.setFont(new Font("Monospaced", Font.PLAIN, Globals.prefs.getInt(JabRefPreferences.FONT_SIZE))); JScrollPane paneScrollPane = new JScrollPane(sourcePreview); - paneScrollPane.setVerticalScrollBarPolicy( - JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + paneScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); paneScrollPane.setPreferredSize(new Dimension(500, 255)); paneScrollPane.setMinimumSize(new Dimension(10, 10)); @@ -516,7 +508,7 @@ private boolean parseWithFreeCiteAndAddEntries() { text = text.replace("##NEWLINE##", OS.NEWLINE); ParserResult importerResult = fimp.importEntries(text); - if(importerResult.hasWarnings()) { + if (importerResult.hasWarnings()) { frame.showMessage(importerResult.getErrorMessage()); } List importedEntries = importerResult.getDatabase().getEntries(); @@ -542,8 +534,7 @@ private void updateSourceView() { StringWriter sw = new StringWriter(200); try { new BibEntryWriter(new LatexFieldFormatter(LatexFieldFormatterPreferences.fromPreferences(Globals.prefs)), - false).write(entry, sw, - frame.getCurrentBasePanel().getBibDatabaseContext().getMode()); + false).write(entry, sw, frame.getCurrentBasePanel().getBibDatabaseContext().getMode()); sourcePreview.setText(sw.getBuffer().toString()); } catch (IOException ex) { LOGGER.error("Error in entry" + ": " + ex.getMessage(), ex); @@ -571,9 +562,9 @@ private String[] getAllFields() { private class PasteAction extends BasicAction { + public PasteAction() { - super(Localization.lang("Paste"), - Localization.lang("Paste from clipboard"), + super(Localization.lang("Paste"), Localization.lang("Paste from clipboard"), IconTheme.JabRefIcon.PASTE.getIcon()); } @@ -595,19 +586,18 @@ public void actionPerformed(ActionEvent e) { } private class LoadAction extends BasicAction { + public LoadAction() { - super(Localization.lang("Open"), - Localization.lang("Open file"), - IconTheme.JabRefIcon.OPEN.getIcon()); + super(Localization.lang("Open"), Localization.lang("Open file"), IconTheme.JabRefIcon.OPEN.getIcon()); } @Override public void actionPerformed(ActionEvent e) { try { - String chosen = FileDialogs.getNewFile(frame, null, Collections.emptyList(), ".txt", - JFileChooser.OPEN_DIALOG, false); - if (chosen != null) { - File newFile = new File(chosen); + Optional path = new NewFileDialogs(frame).withExtension(FileExtensions.TXT) + .openDlgAndGetSelectedFile(); + if (path.isPresent()) { + File newFile = path.get().toFile(); document.remove(0, document.getLength()); EditorKit eKit = textPane.getEditorKit(); if (eKit != null) { @@ -624,10 +614,9 @@ public void actionPerformed(ActionEvent e) { } private class ClearAction extends BasicAction { + public ClearAction() { - super(Localization.lang("Clear"), - Localization.lang("Clear inputarea"), - IconTheme.JabRefIcon.NEW.getIcon()); + super(Localization.lang("Clear"), Localization.lang("Clear inputarea"), IconTheme.JabRefIcon.NEW.getIcon()); } @Override @@ -637,8 +626,10 @@ public void actionPerformed(ActionEvent e) { } class FieldListSelectionHandler implements ListSelectionListener { + private int lastIndex = -1; + @Override public void valueChanged(ListSelectionEvent e) { ListSelectionModel lsm = (ListSelectionModel) e.getSource(); @@ -665,6 +656,7 @@ public void valueChanged(ListSelectionEvent e) { // simple JList Renderer // based on : Advanced JList Programming at developers.sun.com private class SimpleCellRenderer extends DefaultListCellRenderer { + private final Font baseFont; private final Font usedFont; private final Icon okIcon = IconTheme.JabRefIcon.PLAIN_TEXT_IMPORT_DONE.getSmallIcon(); @@ -672,6 +664,7 @@ private class SimpleCellRenderer extends DefaultListCellRenderer { private final Color requiredColor = Globals.prefs.getColor(JabRefPreferences.TABLE_REQ_FIELD_BACKGROUND); private final Color optionalColor = Globals.prefs.getColor(JabRefPreferences.TABLE_OPT_FIELD_BACKGROUND); + public SimpleCellRenderer(Font normFont) { baseFont = normFont; usedFont = baseFont.deriveFont(Font.ITALIC); @@ -681,9 +674,7 @@ public SimpleCellRenderer(Font normFont) { * reconfigure the Jlabel each time we're called. */ @Override - public Component getListCellRendererComponent( - JList list, - Object value, // value to display + public Component getListCellRendererComponent(JList list, Object value, // value to display int index, // cell index boolean iss, // is the cell selected boolean chf) // the list and the cell have the focus @@ -716,6 +707,7 @@ public Component getListCellRendererComponent( } private class FieldListMouseListener extends MouseAdapter { + @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { @@ -728,6 +720,8 @@ private class MenuTextForTagAction extends AbstractAction { private final String field; private final Boolean overrideField; + + public MenuTextForTagAction(String field, Boolean overrideField) { super(field); this.field = field; @@ -744,8 +738,10 @@ public void actionPerformed(ActionEvent e) { } class PopupListener extends MouseAdapter { + private final JPopupMenu popMenu; + public PopupListener(JPopupMenu menu) { popMenu = menu; } @@ -768,6 +764,7 @@ private void maybeShowPopup(MouseEvent e) { } abstract class BasicAction extends AbstractAction { + public BasicAction(String text, String description, Icon icon) { super(text, icon); putValue(Action.SHORT_DESCRIPTION, description); diff --git a/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java b/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java index 5d167a3b9a1..3c0caf18e11 100644 --- a/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java +++ b/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java @@ -20,17 +20,16 @@ import java.awt.Component; import java.awt.GridLayout; import java.awt.event.ActionEvent; -import java.io.File; +import java.nio.file.Path; import java.util.ArrayList; -import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.prefs.BackingStoreException; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -38,9 +37,11 @@ import net.sf.jabref.Globals; import net.sf.jabref.JabRefException; -import net.sf.jabref.gui.FileDialogs; + +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.GUIGlobals; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.gui.keyboard.KeyBinder; import net.sf.jabref.gui.maintable.MainTable; import net.sf.jabref.logic.exporter.ExportFormats; @@ -132,7 +133,6 @@ public PreferencesDialog(JabRefFrame parent) { cardLayout.show(main, o); }); - JPanel buttons = new JPanel(); buttons.setLayout(new GridLayout(4, 1)); buttons.add(importPreferences, 0); @@ -166,38 +166,33 @@ public PreferencesDialog(JabRefFrame parent) { // Import and export actions: exportPreferences.setToolTipText(Localization.lang("Export preferences to file")); exportPreferences.addActionListener(e -> { - String filename = FileDialogs.getNewFile(frame, new File(System.getProperty("user.home")), - Collections.singletonList(".xml"), JFileChooser.SAVE_DIALOG, false); - if (filename == null) { - return; - } - File file = new File(filename); - if (!file.exists() || (JOptionPane.showConfirmDialog(PreferencesDialog.this, - Localization.lang("'%0' exists. Overwrite file?", file.getName()), - Localization.lang("Export preferences"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION)) { + Optional path = new NewFileDialogs(frame, System.getProperty("user.home")) + .withExtension(FileExtensions.XML).saveNewFile(); + path.ifPresent(exportFile -> { try { - prefs.exportPreferences(filename); + prefs.exportPreferences(exportFile.toString()); } catch (JabRefException ex) { LOGGER.warn(ex.getMessage(), ex); JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), Localization.lang("Export preferences"), JOptionPane.ERROR_MESSAGE); } - } + }); }); importPreferences.setToolTipText(Localization.lang("Import preferences from file")); importPreferences.addActionListener(e -> { - String filename = FileDialogs.getNewFile(frame, new File(System.getProperty("user.home")), - Collections.singletonList(".xml"), JFileChooser.OPEN_DIALOG, false); - if (filename != null) { + + Optional fileName = new NewFileDialogs(frame, System.getProperty("user.home")) + .withExtension(FileExtensions.XML).openDlgAndGetSelectedFile(); + + if (fileName.isPresent()) { try { - prefs.importPreferences(filename); + prefs.importPreferences(fileName.get().toString()); updateAfterPreferenceChanges(); JOptionPane.showMessageDialog(PreferencesDialog.this, Localization.lang("You must restart JabRef for this to come into effect."), - Localization.lang("Import preferences"), - JOptionPane.WARNING_MESSAGE); + Localization.lang("Import preferences"), JOptionPane.WARNING_MESSAGE); } catch (JabRefException ex) { LOGGER.warn(ex.getMessage(), ex); JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), @@ -207,8 +202,7 @@ public PreferencesDialog(JabRefFrame parent) { }); showPreferences.addActionListener( - e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(Globals.prefs), frame) - .setVisible(true)); + e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(Globals.prefs), frame).setVisible(true)); resetPreferences.addActionListener(e -> { if (JOptionPane.showConfirmDialog(PreferencesDialog.this, Localization.lang("Are you sure you want to reset all settings to default values?"), @@ -217,8 +211,7 @@ public PreferencesDialog(JabRefFrame parent) { prefs.clear(); JOptionPane.showMessageDialog(PreferencesDialog.this, Localization.lang("You must restart JabRef for this to come into effect."), - Localization.lang("Reset preferences"), - JOptionPane.WARNING_MESSAGE); + Localization.lang("Reset preferences"), JOptionPane.WARNING_MESSAGE); } catch (BackingStoreException ex) { LOGGER.warn(ex.getMessage(), ex); JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), @@ -241,6 +234,7 @@ private void updateAfterPreferenceChanges() { Globals.prefs.updateEntryEditorTabList(); } + class OkAction extends AbstractAction { public OkAction() { diff --git a/src/main/java/net/sf/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java b/src/main/java/net/sf/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java index 5bc00a64279..d00264cbb7f 100644 --- a/src/main/java/net/sf/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java +++ b/src/main/java/net/sf/jabref/gui/protectedterms/NewProtectedTermsFileDialog.java @@ -2,7 +2,6 @@ import java.awt.BorderLayout; import java.awt.event.ActionEvent; -import java.util.Collections; import javax.swing.AbstractAction; import javax.swing.Action; @@ -14,9 +13,12 @@ import javax.swing.JTextField; import net.sf.jabref.Globals; + +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.JabRefFrame; import net.sf.jabref.gui.actions.BrowseAction; import net.sf.jabref.gui.keyboard.KeyBinding; + import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.logic.protectedterms.ProtectedTermsLoader; @@ -48,7 +50,7 @@ public NewProtectedTermsFileDialog(JabRefFrame mainFrame, ProtectedTermsLoader l private void setupDialog() { JButton browse = new JButton(Localization.lang("Browse")); - browse.addActionListener(BrowseAction.buildForFile(newFile, null, Collections.singletonList(".terms"))); + browse.addActionListener(BrowseAction.buildForFile(newFile, FileExtensions.TERMS)); // Build content panel FormBuilder builder = FormBuilder.create(); diff --git a/src/main/java/net/sf/jabref/gui/protectedterms/ProtectedTermsDialog.java b/src/main/java/net/sf/jabref/gui/protectedterms/ProtectedTermsDialog.java index 7e38c11451f..93f3dcf3756 100644 --- a/src/main/java/net/sf/jabref/gui/protectedterms/ProtectedTermsDialog.java +++ b/src/main/java/net/sf/jabref/gui/protectedterms/ProtectedTermsDialog.java @@ -22,7 +22,6 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; -import java.util.Collections; import java.util.Objects; import java.util.Optional; @@ -54,6 +53,8 @@ import net.sf.jabref.external.ExternalFileType; import net.sf.jabref.external.ExternalFileTypes; import net.sf.jabref.external.UnknownExternalFileType; + +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.IconTheme; import net.sf.jabref.gui.JabRefFrame; import net.sf.jabref.gui.actions.BrowseAction; @@ -71,6 +72,7 @@ import com.jgoodies.forms.builder.ButtonBarBuilder; import com.jgoodies.forms.builder.FormBuilder; import com.jgoodies.forms.layout.FormLayout; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -451,7 +453,7 @@ public AddFileDialog() { super(diag, Localization.lang("Add protected terms file"), true); JButton browse = new JButton(Localization.lang("Browse")); - browse.addActionListener(BrowseAction.buildForFile(newFile, null, Collections.singletonList(".terms"))); + browse.addActionListener(BrowseAction.buildForFile(newFile, FileExtensions.TERMS)); // Build content panel FormBuilder builder = FormBuilder.create(); diff --git a/src/main/java/net/sf/jabref/importer/AppendDatabaseAction.java b/src/main/java/net/sf/jabref/importer/AppendDatabaseAction.java index 73ed24533f7..91d6b9f24cc 100644 --- a/src/main/java/net/sf/jabref/importer/AppendDatabaseAction.java +++ b/src/main/java/net/sf/jabref/importer/AppendDatabaseAction.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.nio.charset.Charset; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import javax.swing.JOptionPane; @@ -28,9 +27,9 @@ import net.sf.jabref.JabRefExecutorService; import net.sf.jabref.MetaData; import net.sf.jabref.gui.BasePanel; -import net.sf.jabref.gui.FileDialogs; import net.sf.jabref.gui.JabRefFrame; import net.sf.jabref.gui.MergeDialog; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.gui.actions.BaseAction; import net.sf.jabref.gui.undo.NamedCompound; import net.sf.jabref.gui.undo.UndoableInsertEntry; @@ -81,11 +80,8 @@ public void action() { md.setLocationRelativeTo(panel); md.setVisible(true); if (md.isOkPressed()) { - List chosen = FileDialogs.getMultipleFiles(frame, - new File(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)), - Collections.emptyList(), false); - //String chosenFile = Globals.getNewFile(frame, new File(Globals.prefs.get("workingDirectory")), - // null, JFileChooser.OPEN_DIALOG, false); + + List chosen = new NewFileDialogs(frame).updateWorkingDirPref().showDlgAndGetMultipleFiles(); if (chosen.isEmpty()) { return; } @@ -95,14 +91,14 @@ public void action() { // Run the actual open in a thread to prevent the program // locking until the file is loaded. - JabRefExecutorService.INSTANCE.execute(() -> openIt(md.importEntries(), md.importStrings(), - md.importGroups(), md.importSelectorWords())); + JabRefExecutorService.INSTANCE.execute( + () -> openIt(md.importEntries(), md.importStrings(), md.importGroups(), md.importSelectorWords())); } } - private void openIt(boolean importEntries, boolean importStrings, - boolean importGroups, boolean importSelectorWords) { + private void openIt(boolean importEntries, boolean importStrings, boolean importGroups, + boolean importSelectorWords) { if (filesToOpen.isEmpty()) { return; } @@ -112,8 +108,8 @@ private void openIt(boolean importEntries, boolean importStrings, // Should this be done _after_ we know it was successfully opened? Charset encoding = Globals.prefs.getDefaultEncoding(); ParserResult pr = OpenDatabaseAction.loadDatabase(file, encoding); - AppendDatabaseAction.mergeFromBibtex(frame, panel, pr, importEntries, importStrings, - importGroups, importSelectorWords); + AppendDatabaseAction.mergeFromBibtex(frame, panel, pr, importEntries, importStrings, importGroups, + importSelectorWords); panel.output(Localization.lang("Imported from database") + " '" + file.getPath() + "'"); } catch (IOException | KeyCollisionException ex) { LOGGER.warn("Could not open database", ex); @@ -123,10 +119,8 @@ private void openIt(boolean importEntries, boolean importStrings, } } - private static void mergeFromBibtex(JabRefFrame frame, BasePanel panel, ParserResult pr, - boolean importEntries, boolean importStrings, - boolean importGroups, boolean importSelectorWords) - throws KeyCollisionException { + private static void mergeFromBibtex(JabRefFrame frame, BasePanel panel, ParserResult pr, boolean importEntries, + boolean importStrings, boolean importGroups, boolean importSelectorWords) throws KeyCollisionException { BibDatabase fromDatabase = pr.getDatabase(); List appendedEntries = new ArrayList<>(); diff --git a/src/main/java/net/sf/jabref/importer/ImportCustomizationDialog.java b/src/main/java/net/sf/jabref/importer/ImportCustomizationDialog.java index c4e120fa669..aa44016e038 100644 --- a/src/main/java/net/sf/jabref/importer/ImportCustomizationDialog.java +++ b/src/main/java/net/sf/jabref/importer/ImportCustomizationDialog.java @@ -22,8 +22,9 @@ import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; +import java.nio.file.Path; +import java.util.EnumSet; +import java.util.Optional; import java.util.zip.ZipFile; import javax.swing.AbstractAction; @@ -34,7 +35,6 @@ import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -44,15 +44,16 @@ import javax.swing.table.TableColumnModel; import net.sf.jabref.Globals; -import net.sf.jabref.gui.FileDialogs; + +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.gui.help.HelpAction; import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.gui.util.FocusRequester; import net.sf.jabref.importer.fileformat.ImportFormat; import net.sf.jabref.logic.help.HelpFile; import net.sf.jabref.logic.l10n.Localization; -import net.sf.jabref.preferences.JabRefPreferences; import com.jgoodies.forms.builder.ButtonBarBuilder; import org.apache.commons.logging.Log; @@ -73,6 +74,7 @@ public class ImportCustomizationDialog extends JDialog { private static final Log LOGGER = LogFactory.getLog(ImportCustomizationDialog.class); + /** * * @param frame @@ -98,17 +100,15 @@ public ImportCustomizationDialog(final JabRefFrame frame) { JButton addFromFolderButton = new JButton(Localization.lang("Add from folder")); addFromFolderButton.addActionListener(e -> { CustomImporter importer = new CustomImporter(); - importer.setBasePath(FileDialogs - .getNewDir(frame, new File(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)), - Collections.emptyList(), Localization.lang("Select Classpath of New Importer"), - JFileChooser.CUSTOM_DIALOG, false)); - String chosenFileStr = null; - if (importer.getBasePath() != null) { - chosenFileStr = FileDialogs.getNewFile(frame, importer.getFileFromBasePath(), - Collections.singletonList(".class"), Localization.lang("Select new ImportFormat subclass"), - JFileChooser.CUSTOM_DIALOG, false); - } - if (chosenFileStr != null) { + + Optional selectedFile = new NewFileDialogs(frame).withExtension(FileExtensions.CLASS) + .openDlgAndGetSelectedFile(); + + if (selectedFile.isPresent() && (selectedFile.get().getParent() != null)) { + importer.setBasePath(selectedFile.get().getParent().toString()); + + String chosenFileStr = selectedFile.toString(); + try { importer.setClassName(pathToClass(importer.getFileFromBasePath(), new File(chosenFileStr))); importer.setName(importer.getInstance().getFormatName()); @@ -125,33 +125,38 @@ public ImportCustomizationDialog(final JabRefFrame frame) { } }); - addFromFolderButton.setToolTipText(Localization.lang("Add a (compiled) custom ImportFormat class from a class path.") + "\n" + Localization.lang("The path need not be on the classpath of JabRef.")); + addFromFolderButton + .setToolTipText(Localization.lang("Add a (compiled) custom ImportFormat class from a class path.") + + "\n" + Localization.lang("The path need not be on the classpath of JabRef.")); JButton addFromJarButton = new JButton(Localization.lang("Add from JAR")); addFromJarButton.addActionListener(e -> { - String basePath = FileDialogs.getNewFile(frame, - new File(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)), Arrays.asList(".zip", ".jar"), - Localization.lang("Select a ZIP-archive"), JFileChooser.CUSTOM_DIALOG, false); + Optional jarZipFile = new NewFileDialogs(frame) + .withExtensions(EnumSet.of(FileExtensions.ZIP, FileExtensions.JAR)).openDlgAndGetSelectedFile(); - if (basePath != null) { - try (ZipFile zipFile = new ZipFile(new File(basePath), ZipFile.OPEN_READ)) { + if (jarZipFile.isPresent()) { + try (ZipFile zipFile = new ZipFile(jarZipFile.get().toFile(), ZipFile.OPEN_READ)) { ZipFileChooser zipFileChooser = new ZipFileChooser(this, zipFile); zipFileChooser.setVisible(true); customImporterTable.revalidate(); customImporterTable.repaint(10); } catch (IOException exc) { LOGGER.info("Could not open ZIP-archive.", exc); - JOptionPane.showMessageDialog(frame, Localization.lang("Could not open %0", basePath) + "\n" - + Localization.lang("Have you chosen the correct package path?")); + JOptionPane.showMessageDialog(frame, + Localization.lang("Could not open %0", jarZipFile.get().toString()) + "\n" + + Localization.lang("Have you chosen the correct package path?")); } catch (NoClassDefFoundError exc) { LOGGER.info("Could not instantiate ZIP-archive reader.", exc); - JOptionPane.showMessageDialog(frame, Localization.lang("Could not instantiate %0", basePath) + "\n" - + Localization.lang("Have you chosen the correct package path?")); + JOptionPane.showMessageDialog(frame, + Localization.lang("Could not instantiate %0", jarZipFile.get().toString()) + "\n" + + Localization.lang("Have you chosen the correct package path?")); } } + }); - addFromJarButton.setToolTipText(Localization.lang("Add a (compiled) custom ImportFormat class from a ZIP-archive.") + "\n" + - Localization.lang("The ZIP-archive need not be on the classpath of JabRef.")); + addFromJarButton + .setToolTipText(Localization.lang("Add a (compiled) custom ImportFormat class from a ZIP-archive.") + + "\n" + Localization.lang("The ZIP-archive need not be on the classpath of JabRef.")); JButton showDescButton = new JButton(Localization.lang("Show description")); showDescButton.addActionListener(e -> { @@ -199,7 +204,6 @@ public void actionPerformed(ActionEvent e) { JButton helpButton = new HelpAction(HelpFile.CUSTOM_IMPORTS).getHelpButton(); - // Key bindings: JPanel mainPanel = new JPanel(); ActionMap am = mainPanel.getActionMap(); @@ -235,8 +239,7 @@ public void actionPerformed(ActionEvent e) { */ @Override public Dimension getSize() { - int width = COL_0_WIDTH + COL_1_WIDTH - + COL_2_WIDTH + COL_3_WIDTH; + int width = COL_0_WIDTH + COL_1_WIDTH + COL_2_WIDTH + COL_3_WIDTH; return new Dimension(width, width / 2); } @@ -282,12 +285,9 @@ public void addOrReplaceImporter(CustomImporter importer) { */ private class ImportTableModel extends AbstractTableModel { - private final String[] columnNames = new String[] { - Localization.lang("Import name"), - Localization.lang("Command line id"), - Localization.lang("ImportFormat class"), - Localization.lang("Contained in") - }; + private final String[] columnNames = new String[] {Localization.lang("Import name"), + Localization.lang("Command line id"), Localization.lang("ImportFormat class"), + Localization.lang("Contained in")}; @Override diff --git a/src/main/java/net/sf/jabref/importer/ImportMenuItem.java b/src/main/java/net/sf/jabref/importer/ImportMenuItem.java index 57c893137af..f47fd2593e8 100644 --- a/src/main/java/net/sf/jabref/importer/ImportMenuItem.java +++ b/src/main/java/net/sf/jabref/importer/ImportMenuItem.java @@ -17,13 +17,11 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; import javax.swing.JMenuItem; @@ -32,9 +30,9 @@ import net.sf.jabref.Globals; import net.sf.jabref.gui.BasePanel; import net.sf.jabref.gui.EntryMarker; -import net.sf.jabref.gui.FileDialogs; import net.sf.jabref.gui.ImportInspectionDialog; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.gui.ParserResultWarningDialog; import net.sf.jabref.gui.undo.NamedCompound; import net.sf.jabref.gui.worker.AbstractWorker; @@ -104,9 +102,8 @@ class MyWorker extends AbstractWorker { @Override public void init() { importError = null; - filenames = FileDialogs.getMultipleFiles(frame, - new File(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)), - importer == null ? Collections.emptyList() : importer.getExtensions(), true); + + filenames = new NewFileDialogs(frame).updateWorkingDirPref().showDlgAndGetMultipleFiles(); if (!filenames.isEmpty()) { frame.block(); @@ -141,8 +138,7 @@ public void run() { frame.showMessage(pr.getErrorMessage()); } - imports.add(new ImportFormatReader.UnknownFormatImport(importer - .getFormatName(), pr)); + imports.add(new ImportFormatReader.UnknownFormatImport(importer.getFormatName(), pr)); } } catch (IOException e) { // This indicates that a specific importer was specified, and that @@ -225,8 +221,7 @@ private ParserResult mergeImportResults(List filesToOpen = new ArrayList<>(); if (showDialog) { - List chosenStrings = FileDialogs.getMultipleFiles(frame, - new File(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)), Collections.singletonList(".bib"), - true); + + List chosenStrings = new NewFileDialogs(frame).withExtension(FileExtensions.BIBTEX_DB) + .showDlgAndGetMultipleFiles(); + for (String chosen : chosenStrings) { - if (chosen != null) { - filesToOpen.add(new File(chosen)); - } + + filesToOpen.add(new File(chosen)); + } } else { LOGGER.info(Action.NAME + " " + e.getActionCommand()); @@ -112,6 +115,7 @@ public void actionPerformed(ActionEvent e) { openFiles(filesToOpen, true); } + /** * Opens the given file. If null or 404, nothing happens * @@ -142,11 +146,12 @@ public void openFiles(List filesToOpen, boolean raisePanel) { int removed = 0; // Check if any of the files are already open: - for (Iterator iterator = filesToOpen.iterator(); iterator.hasNext(); ) { + for (Iterator iterator = filesToOpen.iterator(); iterator.hasNext();) { File file = iterator.next(); for (int i = 0; i < frame.getTabbedPane().getTabCount(); i++) { BasePanel basePanel = frame.getBasePanelAt(i); - if ((basePanel.getBibDatabaseContext().getDatabaseFile() != null) && basePanel.getBibDatabaseContext().getDatabaseFile().equals(file)) { + if ((basePanel.getBibDatabaseContext().getDatabaseFile() != null) + && basePanel.getBibDatabaseContext().getDatabaseFile().equals(file)) { iterator.remove(); removed++; // See if we removed the final one. If so, we must perhaps @@ -176,7 +181,8 @@ public void openFiles(List filesToOpen, boolean raisePanel) { // If no files are remaining to open, this could mean that a file was // already open. If so, we may have to raise the correct tab: else if (toRaise != null) { - frame.output(Localization.lang("File '%0' is already open.", toRaise.getBibDatabaseContext().getDatabaseFile().getPath())); + frame.output(Localization.lang("File '%0' is already open.", + toRaise.getBibDatabaseContext().getDatabaseFile().getPath())); frame.getTabbedPane().setSelectedComponent(toRaise); } @@ -200,12 +206,17 @@ private void openTheFile(File file, boolean raisePanel) { } else if (autoSaveFound) { // We have found a newer autosave, but we are not allowed to use it without // prompting. - int answer = JOptionPane.showConfirmDialog(null, - "" + Localization - .lang("An autosave file was found for this database. This could indicate " - + "that JabRef did not shut down cleanly last time the file was used.") - + "
" + Localization.lang("Do you want to recover the database from the autosave file?") - + "", Localization.lang("Recover from autosave"), JOptionPane.YES_NO_OPTION); + int answer = JOptionPane + .showConfirmDialog( + null, "" + + Localization + .lang("An autosave file was found for this database. This could indicate " + + "that JabRef did not shut down cleanly last time the file was used.") + + "
" + + Localization + .lang("Do you want to recover the database from the autosave file?") + + "", + Localization.lang("Recover from autosave"), JOptionPane.YES_NO_OPTION); if (answer == JOptionPane.YES_OPTION) { fileToLoad = AutoSaveManager.getAutoSaveFile(file); tryingAutosave = true; @@ -220,9 +231,8 @@ private void openTheFile(File file, boolean raisePanel) { if (FileBasedLock.hasLockFile(file.toPath())) { Optional modificationTime = FileBasedLock.getLockFileTimeStamp(file.toPath()); - if ((modificationTime.isPresent()) && ( - (System.currentTimeMillis() - modificationTime.get().toMillis()) - > FileBasedLock.LOCKFILE_CRITICAL_AGE)) { + if ((modificationTime.isPresent()) && ((System.currentTimeMillis() + - modificationTime.get().toMillis()) > FileBasedLock.LOCKFILE_CRITICAL_AGE)) { // The lock file is fairly old, so we can offer to "steal" the file: int answer = JOptionPane.showConfirmDialog(null, "" + Localization.lang("Error opening file") + " '" + fileName + "'. " @@ -318,10 +328,12 @@ private BasePanel addNewDatabase(ParserResult result, final File file, boolean r MetaData meta = result.getMetaData(); if (result.hasWarnings()) { - JabRefExecutorService.INSTANCE.execute(() -> ParserResultWarningDialog.showParserResultWarningDialog(result, frame)); + JabRefExecutorService.INSTANCE + .execute(() -> ParserResultWarningDialog.showParserResultWarningDialog(result, frame)); } - Defaults defaults = new Defaults(BibDatabaseMode.fromPreference(Globals.prefs.getBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE))); + Defaults defaults = new Defaults( + BibDatabaseMode.fromPreference(Globals.prefs.getBoolean(JabRefPreferences.BIBLATEX_DEFAULT_MODE))); BasePanel basePanel = new BasePanel(frame, new BibDatabaseContext(database, meta, file, defaults)); // file is set to null inside the EventDispatcherThread @@ -340,13 +352,13 @@ public static ParserResult loadDatabase(File fileToOpen, Charset defaultEncoding // Open and parse file ParserResult result = new BibtexImporter().importDatabase(fileToOpen.toPath(), defaultEncoding); - if (SpecialFieldsUtils.keywordSyncEnabled()) { - NamedCompound compound = new NamedCompound("SpecialFieldSync"); - for (BibEntry entry : result.getDatabase().getEntries()) { - SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, compound); - } - LOGGER.debug("Synchronized special fields based on keywords"); + if (SpecialFieldsUtils.keywordSyncEnabled()) { + NamedCompound compound = new NamedCompound("SpecialFieldSync"); + for (BibEntry entry : result.getDatabase().getEntries()) { + SpecialFieldsUtils.syncSpecialFieldsFromKeywords(entry, compound); } + LOGGER.debug("Synchronized special fields based on keywords"); + } return result; } diff --git a/src/main/java/net/sf/jabref/logic/cleanup/RenamePdfCleanup.java b/src/main/java/net/sf/jabref/logic/cleanup/RenamePdfCleanup.java index ded4a3b2cf9..d70fd88808d 100644 --- a/src/main/java/net/sf/jabref/logic/cleanup/RenamePdfCleanup.java +++ b/src/main/java/net/sf/jabref/logic/cleanup/RenamePdfCleanup.java @@ -64,7 +64,8 @@ public List cleanup(BibEntry entry) { } StringBuilder newFilename = new StringBuilder( - FileUtil.createFileNameFromPattern(databaseContext.getDatabase(), entry, repositoryLoader, prefs)); + FileUtil.createFileNameFromPattern(databaseContext.getDatabase(), entry, repositoryLoader, prefs) + .trim()); //Add extension to newFilename newFilename.append('.').append(FileUtil.getFileExtension(realOldFilename).orElse("pdf")); diff --git a/src/main/java/net/sf/jabref/logic/integrity/ISSNChecker.java b/src/main/java/net/sf/jabref/logic/integrity/ISSNChecker.java index 41e9d66cfcb..4529793cfcf 100644 --- a/src/main/java/net/sf/jabref/logic/integrity/ISSNChecker.java +++ b/src/main/java/net/sf/jabref/logic/integrity/ISSNChecker.java @@ -3,6 +3,7 @@ import java.util.Collections; import java.util.List; + import net.sf.jabref.logic.integrity.IntegrityCheck.Checker; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.logic.util.ISSN; diff --git a/src/main/resources/l10n/JabRef_da.properties b/src/main/resources/l10n/JabRef_da.properties index 39111c62ffa..99b4f56ebae 100644 --- a/src/main/resources/l10n/JabRef_da.properties +++ b/src/main/resources/l10n/JabRef_da.properties @@ -649,15 +649,12 @@ Searching_for_duplicates...=Søger_efter_dubletter... Searching_for_files=Søger_efter_filer Secondary_sort_criterion=Sekundært_sorteringskriterium Select=Vælg -Select_a_ZIP-archive=Vælg_ZIP-fil Select_action=Vælg_handling Select_all=Vælg_alle -Select_Classpath_of_New_Importer=Vælg_classpath_for_nyt_importformat Select_encoding=Vælg_tegnkodning Select_entry_type=Vælg_posttype Select_external_application=Vælg_ekstern_applikation Select_file_from_ZIP-archive=Vælg_fil_fra_ZIP-fil -Select_new_ImportFormat_subclass=Vælg_klasse_til_nyt_importformat Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Vælg_forgreningerne_for_at_inspicere_og_acceptere_eller_forkaste_ændringer Selected_entries=Valgte_poster @@ -1744,4 +1741,9 @@ Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_de.properties b/src/main/resources/l10n/JabRef_de.properties index a7385c24090..56a4fe1ee28 100644 --- a/src/main/resources/l10n/JabRef_de.properties +++ b/src/main/resources/l10n/JabRef_de.properties @@ -1211,13 +1211,11 @@ Secondary_sort_criterion=Zweites_Sortierkriterium Select=Auswählen -Select_a_ZIP-archive=ZIP-Archiv_auswählen Select_action=Aktion_wählen Select_all=Alle_auswählen -Select_Classpath_of_New_Importer=Klassenpfad_auswählen Select_encoding=Kodierung_wählen @@ -1229,7 +1227,6 @@ Select_file_from_ZIP-archive=Eintrag_aus_der_ZIP-Archiv_auswählen -Select_new_ImportFormat_subclass=Klasse_auswählen Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Wählen_Sie_die_Verzweigungen_aus,_um_die_Änderungen_zu_sehen_und_anzunehmen_oder_zu_verwerfen Selected_entries=Ausgewählte_Einträge @@ -2454,4 +2451,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report=Neuer_technischer_Bericht -Open_OpenOffice/LibreOffice_connection=Öffne_OpenOffice/LibreOffice_Verbindung +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection=Öffne_OpenOffice/LibreOffice_Verbindung \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index a20e6173ec2..81b848a349d 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -1140,14 +1140,10 @@ Secondary_sort_criterion=Secondary_sort_criterion Select=Select -Select_a_ZIP-archive=Select_a_ZIP-archive - Select_action=Select_action Select_all=Select_all -Select_Classpath_of_New_Importer=Select_Classpath_of_New_Importer - Select_encoding=Select_encoding Select_entry_type=Select_entry_type @@ -1155,8 +1151,6 @@ Select_external_application=Select_external_application Select_file_from_ZIP-archive=Select_file_from_ZIP-archive -Select_new_ImportFormat_subclass=Select_new_ImportFormat_subclass - Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Select_the_tree_nodes_to_view_and_accept_or_reject_changes Selected_entries=Selected_entries Set_field=Set_field @@ -2008,7 +2002,6 @@ New_mastersthesis=New_mastersthesis New_phdthesis=New_phdthesis New_proceedings=New_proceedings New_unpublished=New_unpublished -New_technical_report=New_technical_report Next_tab=Next_tab Preamble_editor,_store_changes=Preamble_editor,_store_changes Previous_tab=Previous_tab @@ -2286,4 +2279,11 @@ Please_merge_the_shared_entry_with_yours_and_press_"Merge_entries"_to_resolve_th Canceling_this_operation_will_leave_your_changes_unsynchronized._Cancel_anyway?=Canceling_this_operation_will_leave_your_changes_unsynchronized._Cancel_anyway? The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Keep"_to_recover_the_entry.=The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Keep"_to_recover_the_entry. Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?=Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now? -Open_OpenOffice/LibreOffice_connection=Open_OpenOffice/LibreOffice_connection +New_technical_report=New_technical_report + +%0_file=%0_file +Custom_layout_file=Custom_layout_file +Protected_terms_file=Protected_terms_file +Style_file=Style_file + +Open_OpenOffice/LibreOffice_connection=Open_OpenOffice/LibreOffice_connection \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_es.properties b/src/main/resources/l10n/JabRef_es.properties index e4eeac3222d..d709561c53e 100644 --- a/src/main/resources/l10n/JabRef_es.properties +++ b/src/main/resources/l10n/JabRef_es.properties @@ -606,15 +606,12 @@ Searching_for_duplicates...=Buscando_duplicados... Searching_for_files=Buscando_archivos Secondary_sort_criterion=Criterio_secundario_de_ordenación Select=Seleccionar -Select_a_ZIP-archive=Seleccione_un_archivo_ZIP Select_action=Seleccionar_acción Select_all=Seleccionar_todo -Select_Classpath_of_New_Importer=Seleccionar_classpath_del_nuevo_importador Select_encoding=Seleccionar_codificación Select_entry_type=Seleccionar_tipo_de_entrada Select_external_application=Seleccionar_aplicación_externa Select_file_from_ZIP-archive=Seleccionar_archivo_desde_archivo_ZIP -Select_new_ImportFormat_subclass=Seleccionar_nueva_subclase_de_formato_de_importación Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Seleccionar_nodos_de_árbol_para_ver_y_aceptar_o_rechazar_los_cambios. Selected_entries=Entradas_seleccionadas Set_field=Establecer_campo @@ -1645,4 +1642,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_fa.properties b/src/main/resources/l10n/JabRef_fa.properties index ea3ff0b8acf..7d61bbb1feb 100644 --- a/src/main/resources/l10n/JabRef_fa.properties +++ b/src/main/resources/l10n/JabRef_fa.properties @@ -1172,13 +1172,11 @@ Secondary_sort_criterion= Select= -Select_a_ZIP-archive= Select_action= Select_all= -Select_Classpath_of_New_Importer= Select_encoding= @@ -1190,7 +1188,6 @@ Select_file_from_ZIP-archive= -Select_new_ImportFormat_subclass= Select_the_tree_nodes_to_view_and_accept_or_reject_changes= Selected_entries= @@ -2426,4 +2423,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_fr.properties b/src/main/resources/l10n/JabRef_fr.properties index 3cd7a4ea3d4..313e2b65f5f 100644 --- a/src/main/resources/l10n/JabRef_fr.properties +++ b/src/main/resources/l10n/JabRef_fr.properties @@ -606,15 +606,12 @@ Searching_for_duplicates...=Recherche_des_doublons_en_cours... Searching_for_files=Recherche_de_fichiers... Secondary_sort_criterion=Critère_secondaire_de_tri Select=Sélectionner -Select_a_ZIP-archive=Sélectionner_une_archive_ZIP Select_action=Sélectionner_l'opération Select_all=Tout_sélectionner -Select_Classpath_of_New_Importer=Sélectionner_le_chemin_de_classe_du_nouveau_fil7tre_d'importation Select_encoding=Sélectionner_l'encodage Select_entry_type=Sélectionner_un_type_d'entrée Select_external_application=Sélectionner_une_application_externe Select_file_from_ZIP-archive=Sélectionner_un_fichier_depuis_une_archive_ZIP -Select_new_ImportFormat_subclass=Sélectionner_une_nouvelle_sous-classe_ImportFormat Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Sélectionner_les_noeuds_de_l'arborescence_pour_voir,_et_accepter_ou_rejeter,_les_modifications Selected_entries=Les_entrées_sélectionnées Set_field=Configurer_le_champ @@ -1686,4 +1683,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + Open_OpenOffice/LibreOffice_connection= diff --git a/src/main/resources/l10n/JabRef_in.properties b/src/main/resources/l10n/JabRef_in.properties index e6718e00bbe..2658fdc56b2 100644 --- a/src/main/resources/l10n/JabRef_in.properties +++ b/src/main/resources/l10n/JabRef_in.properties @@ -605,15 +605,12 @@ Searching_for_duplicates...=pencarian_hal_yang_sama... Searching_for_files=Mencari_berkas Secondary_sort_criterion=Kriteria_kedua Select=Pilih -Select_a_ZIP-archive=Pilih_arsip_ZIP Select_action=Pilih_aksi Select_all=Pilih_semua -Select_Classpath_of_New_Importer=Pilih_Classpath_dari_Pengimpor_Baru Select_encoding=Pilih_enkoding Select_entry_type=Pilih_tipe_entri Select_external_application=Pilih_aplikasi_eksternal Select_file_from_ZIP-archive=Pilih_berkas_dari_arsip_ZIP -Select_new_ImportFormat_subclass=Pilih_ImportFormat_subclass_baru Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Pilih_tiga_nodal_untuk_melihat,_menerima_atau_menolak_perubahan Selected_entries=Entri_pilihan Set_field=Pilih_bidang @@ -1661,4 +1658,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + Open_OpenOffice/LibreOffice_connection= diff --git a/src/main/resources/l10n/JabRef_it.properties b/src/main/resources/l10n/JabRef_it.properties index 5e388e4e526..6d29925afca 100644 --- a/src/main/resources/l10n/JabRef_it.properties +++ b/src/main/resources/l10n/JabRef_it.properties @@ -661,15 +661,12 @@ Searching_for_duplicates...=Ricerca_di_duplicati_in_corso... Searching_for_files=Ricerca_dei_file Secondary_sort_criterion=Criterio_di_ordinamento_secondario Select=Seleziona -Select_a_ZIP-archive=Seleziona_un_archivio_ZIP Select_action=Seleziona_l'operazione Select_all=Seleziona_tutto -Select_Classpath_of_New_Importer=Seleziona_il_classpath_del_nuovo_filtro_di_importazione Select_encoding=Seleziona_la_codifica Select_entry_type=Seleziona_un_tipo_di_voce Select_external_application=Seleziona_un'applicazione_esterna Select_file_from_ZIP-archive=Seleziona_un_file_da_un_archivio_ZIP -Select_new_ImportFormat_subclass=Seleziona_una_nuova_sottoclasse_ImportFormat Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Selezionare_i_nodi_dell'albero_per_vedere_ed_accettare_o_rifiutare_le_modifiche Selected_entries=Voci_selezionate @@ -1762,4 +1759,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + Open_OpenOffice/LibreOffice_connection= diff --git a/src/main/resources/l10n/JabRef_ja.properties b/src/main/resources/l10n/JabRef_ja.properties index b4f172ecfb9..efb46797f53 100644 --- a/src/main/resources/l10n/JabRef_ja.properties +++ b/src/main/resources/l10n/JabRef_ja.properties @@ -1191,13 +1191,11 @@ Secondary_sort_criterion=第二整序基準 Select=選択 -Select_a_ZIP-archive=ZIP書庫を選択 Select_action=アクションを選択 Select_all=すべて選択 -Select_Classpath_of_New_Importer=新しい読み込みのクラスパスを選択 Select_encoding=エンコーディングを選択 @@ -1209,7 +1207,6 @@ Select_file_from_ZIP-archive=ZIP書庫からファイルを選択してくださ -Select_new_ImportFormat_subclass=新しいImportFormatサブクラスを選択 Select_the_tree_nodes_to_view_and_accept_or_reject_changes=ツリーノードを選択して表示させ、変更を受諾ないし拒否してください Selected_entries=選択した項目 @@ -2403,4 +2400,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_nl.properties b/src/main/resources/l10n/JabRef_nl.properties index fa50236d368..7b2eb853f85 100644 --- a/src/main/resources/l10n/JabRef_nl.properties +++ b/src/main/resources/l10n/JabRef_nl.properties @@ -1209,13 +1209,11 @@ Secondary_sort_criterion=Secundair_sorteercriterium Select=Selecteer -Select_a_ZIP-archive=Selecteer_een_ZIP-archief Select_action=Selecteer_actie Select_all=Alles_selecteren -Select_Classpath_of_New_Importer=Selecteer_Classpath_van_Nieuwe_Importer Select_encoding=Selecteer_encodering @@ -1227,7 +1225,6 @@ Select_file_from_ZIP-archive=Selecteer_bestand_van_ZIP-archief -Select_new_ImportFormat_subclass=Selecteer_nieuw_ImportFormat_Subklasse Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Selecteer_de_boom_knopen_om_veranderingen_te_tonen_en_te_accepteren_of_afwijzen Selected_entries=Geselecteerde_entries @@ -2435,4 +2432,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_no.properties b/src/main/resources/l10n/JabRef_no.properties index 1cc397279cf..8bff6cb8e2a 100644 --- a/src/main/resources/l10n/JabRef_no.properties +++ b/src/main/resources/l10n/JabRef_no.properties @@ -1297,13 +1297,11 @@ Secondary_sort_criterion=Andre_sorteringskriterium Select=Velg -Select_a_ZIP-archive=Velg_ZIP-fil Select_action=Select_action Select_all=Velg_alle -Select_Classpath_of_New_Importer=Velg_classpath_for_nytt_importformat Select_encoding=Velg_koding @@ -1317,7 +1315,6 @@ Select_file_from_ZIP-archive=Velg_fil_fra_ZIP-fil -Select_new_ImportFormat_subclass=Velg_klasse_for_nytt_importformat Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Velg_trenodene_for_\u00e5_inspisere_og_akseptere_eller_avsl\u00e5_endringer @@ -2827,4 +2824,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_pt_BR.properties b/src/main/resources/l10n/JabRef_pt_BR.properties index 561e9ece2e5..45f7c08cbf0 100644 --- a/src/main/resources/l10n/JabRef_pt_BR.properties +++ b/src/main/resources/l10n/JabRef_pt_BR.properties @@ -606,15 +606,12 @@ Searching_for_duplicates...=Procurando_por_duplicatas... Searching_for_files=Procurando_por_arquivos... Secondary_sort_criterion=Critério_de_ordenação_secundário Select=Selecionar -Select_a_ZIP-archive=Selecionar_um_arquivo_ZIP Select_action=Selecionar_operação Select_all=Selecionar_tudo -Select_Classpath_of_New_Importer=Selecionar_classpath_para_o_novo_filtro_de_importação Select_encoding=Selecionar_codificação Select_entry_type=Selecionar_tipo_de_referência Select_external_application=Selecionar_aplicação_externa Select_file_from_ZIP-archive=Selecionar_arquivo_a_partir_de_um_arquivo_ZIP -Select_new_ImportFormat_subclass=Selecionar_nova_subclasse_ImportFormat Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Selecione_os_nós_da_árvore_para_visualizar_e_aceitar_ou_rejeitar_mudanças Selected_entries=Referências_selecionadas Set_field=Configurar_campo @@ -1658,4 +1655,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_ru.properties b/src/main/resources/l10n/JabRef_ru.properties index fb1c62e0229..8d0848761c5 100644 --- a/src/main/resources/l10n/JabRef_ru.properties +++ b/src/main/resources/l10n/JabRef_ru.properties @@ -1167,13 +1167,11 @@ Secondary_sort_criterion=Вторичный_критерий_сортировк Select=Выбрать -Select_a_ZIP-archive=Выбрать_ZIP-архив Select_action=Выбрать_действие Select_all=Выбрать_все -Select_Classpath_of_New_Importer=Выбрать_путь_класса_для_нового_фильтра_импорта Select_encoding=Выбрать_кодировку @@ -1185,7 +1183,6 @@ Select_file_from_ZIP-archive=Выбрать_файл_из_ZIP-архива -Select_new_ImportFormat_subclass=Выбрать_новый_подкласс_ImportFormat Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Выбрать_узлы_дерева_для_просмотра_и_применения/отклонения_изменений Selected_entries=Записи_выбраны @@ -2404,4 +2401,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_sv.properties b/src/main/resources/l10n/JabRef_sv.properties index fa4549c82cf..f3d7e3092c8 100644 --- a/src/main/resources/l10n/JabRef_sv.properties +++ b/src/main/resources/l10n/JabRef_sv.properties @@ -987,9 +987,7 @@ Searching_for_duplicates...=Söker_efter_dubbletter... Searching_for_files=Söker_efter_filer Secondary_sort_criterion=Andra_sorteringskriteriet Select=Välj -Select_Classpath_of_New_Importer= Select_Writer_document=Välj_Writer-dokument -Select_a_ZIP-archive=Välj_ett_ZIP-arkiv Select_a_directory_where_the_search_shall_start.=Välj_en_mapp_där_sökningen_ska_börja. Select_action=Välj_händelse Select_all=Välj_alla @@ -1003,7 +1001,6 @@ Select_external_application=Välj_program Select_file_from_ZIP-archive=Välj_fil_från_ZIP-arkiv Select_file_type\:=Välj_filtyp\: Select_files=Välj_filer -Select_new_ImportFormat_subclass= Select_style=Välj_stil Select_the_tree_nodes_to_view_and_accept_or_reject_changes= Select_which_open_Writer_document_to_work_on=Välj_vilket_öppet_Writer-dokument_som_ska_användas @@ -1603,4 +1600,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?=Kan_inte_citera_poster_utan_BibTeX-nycklar._Generera_nycklar_nu? New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_tr.properties b/src/main/resources/l10n/JabRef_tr.properties index 8d97a0f4de1..ee5ea2c997b 100644 --- a/src/main/resources/l10n/JabRef_tr.properties +++ b/src/main/resources/l10n/JabRef_tr.properties @@ -606,15 +606,12 @@ Searching_for_duplicates...=Çift_nüshalar_aranıyor... Searching_for_files=Dosyalar_aranıyor Secondary_sort_criterion=İkincil_sıralama_kriteri Select=Seç -Select_a_ZIP-archive=Bir_ZIP-arşivi_seç Select_action=Eylem_seç Select_all=Tümünü_seç -Select_Classpath_of_New_Importer=Yeni_İçe_Aktarıcının_Sınıfyolunu_seç Select_encoding=Kodlamayı_seç Select_entry_type=Girdi_türünü_seç Select_external_application=Harici_uygulamayı_seç Select_file_from_ZIP-archive=ZIP_arşivinden_dosyayı_seçiniz -Select_new_ImportFormat_subclass=Yeni_İçe_Aktarım_Biçemi_Altsınıfını_seçiniz Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Değişiklikleri_görmek_ve_kabul_ya_da_reddetmek_için_ağaç_düğümlerini_seçiniz Selected_entries=Seçili_girdiler Set_field=Alanı_ata @@ -1676,4 +1673,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_vi.properties b/src/main/resources/l10n/JabRef_vi.properties index e81876fd612..4300684dc84 100644 --- a/src/main/resources/l10n/JabRef_vi.properties +++ b/src/main/resources/l10n/JabRef_vi.properties @@ -1195,13 +1195,11 @@ Secondary_sort_criterion=Tiêu_chuẩn_phân_loại_thứ_cấp Select=Chọn -Select_a_ZIP-archive=Chọn_một_tập_tin_ZIP Select_action=Chọn_hành_động Select_all=Chọn_tất_cả -Select_Classpath_of_New_Importer=Chọn_đường_dẫn_lớp_của_trình_nhập_mới Select_encoding=Chọn_bộ_mã_hóa @@ -1213,7 +1211,6 @@ Select_file_from_ZIP-archive=Chọn_tập_tin_từ_tập_tin_ZIP -Select_new_ImportFormat_subclass=Chọn_Lớp.phụ_Định.dạng.nhập_mới Select_the_tree_nodes_to_view_and_accept_or_reject_changes=Chọn_các_nốt_trên_sơ_đồ_hình_cây_để_xem_và_chấp_nhận_hoặc_từ_chối_thay_đổi Selected_entries=Các_mục_được_chọn @@ -2430,4 +2427,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file diff --git a/src/main/resources/l10n/JabRef_zh.properties b/src/main/resources/l10n/JabRef_zh.properties index 5343311ced6..9361124797c 100644 --- a/src/main/resources/l10n/JabRef_zh.properties +++ b/src/main/resources/l10n/JabRef_zh.properties @@ -623,15 +623,12 @@ Searching_for_duplicates...=正在查找重复记录... Searching_for_files=正在查找文件 Secondary_sort_criterion=次要依据 Select=选择 -Select_Classpath_of_New_Importer=选择新导入器的_classpath -Select_a_ZIP-archive=选择一个_ZIP_压缩包 Select_action=选择操作 Select_all=全选 Select_encoding=选择编码 Select_entry_type=选择记录类型 Select_external_application=选择外部程序 Select_file_from_ZIP-archive=从_ZIP-压缩包中选择文件 -Select_new_ImportFormat_subclass=选择新的_ImportFormat_子类 Select_the_tree_nodes_to_view_and_accept_or_reject_changes=选择树节点查看和接受/拒绝修改 Selected_entries=选中的记录 Set_field=设置域内容 @@ -1670,4 +1667,9 @@ The_BibEntry_you_currently_work_on_has_been_deleted_on_the_shared_side._Hit_"Kee Cannot_cite_entries_without_BibTeX_keys._Generate_keys_now?= New_technical_report= -Open_OpenOffice/LibreOffice_connection= +%0_file= +Custom_layout_file= +Protected_terms_file= +Style_file= + +Open_OpenOffice/LibreOffice_connection= \ No newline at end of file