From 4017bbe5d2010cf7b1eb3745dccfb7817c089aa1 Mon Sep 17 00:00:00 2001 From: Jeffrey Sander Date: Wed, 25 Apr 2018 10:50:25 -0400 Subject: [PATCH 1/5] Add Text File Export for "Find Unlinked Files" --- CHANGELOG.md | 1 + .../jabref/gui/FindUnlinkedFilesDialog.java | 114 ++++++++++++++++++ src/main/resources/l10n/JabRef_en.properties | 3 + 3 files changed, 118 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3a426f15c7..d2375092739 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# ## [Unreleased] ### Changed +- Added text file export for 'Find Unlinked Files'. [#3341](https://github.com/JabRef/jabref/issues/3341) - Added "*.*" (any file type) to the Import File Filter Dialog. [#3757](https://github.com/JabRef/jabref/issues/3757) - Abbreviate journal names functionality is now running parallel, increasing performance significantly. [#2831](https://github.com/JabRef/jabref/issues/2831) - Changed order of items in context menu [#298](https://github.com/koppor/jabref/issues/298) diff --git a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java index cdab1ab29c8..2cd5e7bfcdc 100644 --- a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java +++ b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.FileFilter; import java.io.IOException; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -74,6 +75,8 @@ import org.jabref.gui.importer.UnlinkedPDFFileFilter; import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.DirectoryDialogConfiguration; +import org.jabref.gui.util.FileDialogConfiguration; +import org.jabref.logic.exporter.VerifyingWriter; import org.jabref.logic.l10n.Localization; import org.jabref.model.EntryTypes; import org.jabref.model.database.BibDatabaseContext; @@ -123,6 +126,7 @@ public class FindUnlinkedFilesDialog extends JabRefDialog { private JPanel panelImportArea; private JButton buttonBrowse; private JButton buttonScan; + private JButton buttonExport; private JButton buttonApply; private JButton buttonClose; @@ -141,6 +145,7 @@ public class FindUnlinkedFilesDialog extends JabRefDialog { private JLabel labelSearchingDirectoryInfo; private JLabel labelImportingInfo; + private JLabel labelExportingInfo; private JTree tree; private JScrollPane scrollpaneTree; private JComboBox comboBoxFileTypeSelection; @@ -175,6 +180,7 @@ public FindUnlinkedFilesDialog(Frame owner, JabRefFrame frame, BasePanel panel) initialize(); buttonApply.setEnabled(false); + buttonExport.setEnabled(false); } /** @@ -493,6 +499,7 @@ private void startImport() { progressBarImporting.setVisible(true); labelImportingInfo.setVisible(true); + buttonExport.setVisible(false); buttonApply.setVisible(false); buttonClose.setVisible(false); disOrEnableDialog(false); @@ -527,6 +534,100 @@ public void stateChanged(ChangeEvent e) { }); } + /** + * This will start the import of all file of all selected nodes in this + * dialogs tree view.
+ *
+ * The import itself will run in a seperate thread, whilst this dialog will + * be showing a progress bar, until the thread has finished its work.
+ *
+ * When the import has finished, the {@link #importFinishedHandler(java.util.List)} is + * invoked. + */ + private void startExport() { + + if (treeModel == null) { + return; + } + setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + + CheckableTreeNode root = (CheckableTreeNode) treeModel.getRoot(); + + final List fileList = getFileListFromNode(root); + + if ((fileList == null) || fileList.isEmpty()) { + return; + } + + progressBarImporting.setVisible(true); + labelExportingInfo.setVisible(true); + buttonExport.setVisible(false); + buttonApply.setVisible(false); + buttonClose.setVisible(false); + disOrEnableDialog(false); + + labelExportingInfo.setEnabled(true); + + progressBarImporting.setMinimum(0); + progressBarImporting.setMaximum(fileList.size()); + progressBarImporting.setValue(0); + progressBarImporting.setString(""); + + FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() + .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); + DialogService ds = new FXDialogService(); + + Optional exportPath = DefaultTaskExecutor + .runInJavaFXThread(() -> ds.showFileSaveDialog(fileDialogConfiguration)); + + VerifyingWriter verifyingWriter; + try { + verifyingWriter = new VerifyingWriter(Files.newOutputStream(exportPath.get()), Charset.defaultCharset()); + } catch (Exception e) { + LOGGER.warn("Error while opening file.", e); + exportFinishedHandler(); + return; + } + + threadState.set(true); + JabRefExecutorService.INSTANCE.execute(() -> { + List errors = new LinkedList<>(); + int counter = 0; + for (File file : fileList) { + try { + verifyingWriter.write(file.toString() + "\n"); + } catch (IOException e) { + LOGGER.warn("Could not write to file.", e); + } + counter++; + progressBarImporting.setValue(counter); + progressBarImporting.setString(Localization.lang("%0 of %1", Integer.toString(counter), + Integer.toString(progressBarImporting.getMaximum()))); + } + try { + verifyingWriter.close(); + } catch (IOException e) { + LOGGER.warn("Could not close stream.", e); + } + + exportFinishedHandler(); + }); + } + + /** + */ + private void exportFinishedHandler() { + + progressBarImporting.setVisible(false); + labelExportingInfo.setVisible(false); + buttonExport.setVisible(true); + buttonApply.setVisible(true); + buttonClose.setVisible(true); + disOrEnableDialog(true); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + frame.getCurrentBasePanel().markBaseChanged(); + } + /** * * @param errors @@ -548,6 +649,7 @@ private void importFinishedHandler(List errors) { progressBarImporting.setVisible(false); labelImportingInfo.setVisible(false); + buttonExport.setVisible(true); buttonApply.setVisible(true); buttonClose.setVisible(true); disOrEnableDialog(true); @@ -578,6 +680,7 @@ private void searchFinishedHandler(CheckableTreeNode rootNode) { disOrEnableDialog(true); buttonApply.setEnabled(true); + buttonExport.setEnabled(true); } /** @@ -609,6 +712,8 @@ private void setupActions() { * selected nodes in this dialogs tree view.
*/ ActionListener actionListenerImportEntrys = e -> startImport(); + ActionListener actionListenerExportEntrys = e -> startExport(); + buttonExport.addActionListener(actionListenerExportEntrys); buttonApply.addActionListener(actionListenerImportEntrys); buttonClose.addActionListener(e -> dispose()); } @@ -691,6 +796,9 @@ public void windowClosing(WindowEvent e) { buttonScan = new JButton(Localization.lang("Scan directory")); buttonScan.setMnemonic('S'); buttonScan.setToolTipText(Localization.lang("Searches the selected directory for unlinked files.")); + buttonExport = new JButton(Localization.lang("Export")); + buttonExport.setMnemonic('E'); + buttonExport.setToolTipText(Localization.lang("Export to text file.")); buttonApply = new JButton(Localization.lang("Apply")); buttonApply.setMnemonic('I'); buttonApply.setToolTipText(Localization.lang("Starts the import of BibTeX entries.")); @@ -733,6 +841,9 @@ public void windowClosing(WindowEvent e) { labelImportingInfo = new JLabel(Localization.lang("Importing into Library...")); labelImportingInfo.setHorizontalAlignment(SwingConstants.CENTER); labelImportingInfo.setVisible(false); + labelExportingInfo = new JLabel(Localization.lang("Exporting into file...")); + labelExportingInfo.setHorizontalAlignment(SwingConstants.CENTER); + labelExportingInfo.setVisible(false); tree = new JTree(); @@ -815,6 +926,8 @@ GridBagConstraints.HORIZONTAL, GridBagConstraints.WEST, new Insets(18, 3, 18, 6) GridBagConstraints.HORIZONTAL, GridBagConstraints.WEST, basicInsets, 0, 1, 2, 1, 0, 0, 0, 0); FindUnlinkedFilesDialog.addComponent(gbl, panelImportArea, labelImportingInfo, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(6, 6, 0, 6), 0, 1, 1, 1, 1, 0, 0, 0); + FindUnlinkedFilesDialog.addComponent(gbl, panelImportArea, labelExportingInfo, GridBagConstraints.HORIZONTAL, + GridBagConstraints.CENTER, new Insets(6, 6, 0, 6), 0, 1, 1, 1, 1, 0, 0, 0); FindUnlinkedFilesDialog.addComponent(gbl, panelImportArea, progressBarImporting, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, new Insets(0, 6, 6, 6), 0, 2, 1, 1, 1, 0, 0, 0); FindUnlinkedFilesDialog.addComponent(gbl, panelButtons, panelImportArea, GridBagConstraints.NONE, @@ -832,6 +945,7 @@ GridBagConstraints.HORIZONTAL, GridBagConstraints.SOUTHWEST, new Insets(12, 6, 2 ButtonBarBuilder bb = new ButtonBarBuilder(); bb.addGlue(); + bb.addButton(buttonExport); bb.addButton(buttonApply); bb.addButton(buttonClose); bb.addGlue(); diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index 0c9ef2f7893..a374292660b 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -447,6 +447,8 @@ Export\ properties=Export properties Export\ to\ clipboard=Export to clipboard +Export\ to\ text\ file.=Export to text file. + Exporting=Exporting Extension=Extension @@ -1584,6 +1586,7 @@ These\ files\ are\ not\ linked\ in\ the\ active\ library.=These files are not li Entry\ type\ to\ be\ created\:=Entry type to be created: Searching\ file\ system...=Searching file system... Importing\ into\ Library...=Importing into Library... +Exporting\ into\ file...=Exporting into file... Select\ directory=Select directory Select\ files=Select files BibTeX\ entry\ creation=BibTeX entry creation From f66fa01d02e29a7e3e79fe232594bb62a32a741d Mon Sep 17 00:00:00 2001 From: Jeffrey Sander Date: Wed, 25 Apr 2018 15:20:18 -0400 Subject: [PATCH 2/5] Add Text File Export for "Find Unlinked Files" --- .../jabref/gui/FindUnlinkedFilesDialog.java | 49 ++++++++----------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java index 2cd5e7bfcdc..3508c4920df 100644 --- a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java +++ b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java @@ -18,13 +18,16 @@ import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.BufferedWriter; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; @@ -535,13 +538,13 @@ public void stateChanged(ChangeEvent e) { } /** - * This will start the import of all file of all selected nodes in this + * This will start the export of all files of all selected nodes in this * dialogs tree view.
*
- * The import itself will run in a seperate thread, whilst this dialog will + * The export itself will run in a seperate thread, whilst this dialog will * be showing a progress bar, until the thread has finished its work.
*
- * When the import has finished, the {@link #importFinishedHandler(java.util.List)} is + * When the export has finished, the {@link #exportFinishedHandler(java.util.List)} is * invoked. */ private void startExport() { @@ -580,38 +583,26 @@ private void startExport() { Optional exportPath = DefaultTaskExecutor .runInJavaFXThread(() -> ds.showFileSaveDialog(fileDialogConfiguration)); - VerifyingWriter verifyingWriter; - try { - verifyingWriter = new VerifyingWriter(Files.newOutputStream(exportPath.get()), Charset.defaultCharset()); - } catch (Exception e) { - LOGGER.warn("Error while opening file.", e); - exportFinishedHandler(); - return; - } - threadState.set(true); JabRefExecutorService.INSTANCE.execute(() -> { - List errors = new LinkedList<>(); - int counter = 0; - for (File file : fileList) { - try { - verifyingWriter.write(file.toString() + "\n"); - } catch (IOException e) { - LOGGER.warn("Could not write to file.", e); + try (BufferedWriter writer = + Files.newBufferedWriter(exportPath.get(), StandardCharsets.UTF_8, + StandardOpenOption.CREATE)) { + int counter = 0; + for (File file : fileList) { + writer.write(file.toString() + "\n"); + counter++; + progressBarImporting.setValue(counter); + progressBarImporting.setString(Localization.lang("%0 of %1", Integer.toString(counter), + Integer.toString(progressBarImporting.getMaximum()))); } - counter++; - progressBarImporting.setValue(counter); - progressBarImporting.setString(Localization.lang("%0 of %1", Integer.toString(counter), - Integer.toString(progressBarImporting.getMaximum()))); - } - try { - verifyingWriter.close(); + } catch (IOException e) { - LOGGER.warn("Could not close stream.", e); + LOGGER.warn("IO Error.", e); } - - exportFinishedHandler(); }); + + exportFinishedHandler(); } /** From d5a78d07b62b336e3f20bd107d417cdec6df72df Mon Sep 17 00:00:00 2001 From: Jeffrey Sander Date: Wed, 25 Apr 2018 15:34:00 -0400 Subject: [PATCH 3/5] Add Text File Export for "Find Unlinked Files" --- src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java index 3508c4920df..7a84dcc0c6e 100644 --- a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java +++ b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java @@ -22,7 +22,6 @@ import java.io.File; import java.io.FileFilter; import java.io.IOException; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -79,7 +78,6 @@ import org.jabref.gui.util.DefaultTaskExecutor; import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.gui.util.FileDialogConfiguration; -import org.jabref.logic.exporter.VerifyingWriter; import org.jabref.logic.l10n.Localization; import org.jabref.model.EntryTypes; import org.jabref.model.database.BibDatabaseContext; From ee09704e17343c925469532ecca0be56f36b2d9b Mon Sep 17 00:00:00 2001 From: Jeffrey Sander Date: Fri, 27 Apr 2018 15:44:43 -0400 Subject: [PATCH 4/5] Add Text File Export for "Find Unlinked Files" --- src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java index 7a84dcc0c6e..ecf2432bf95 100644 --- a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java +++ b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java @@ -536,7 +536,7 @@ public void stateChanged(ChangeEvent e) { } /** - * This will start the export of all files of all selected nodes in this + * This starts the export of all files of all selected nodes in this * dialogs tree view.
*
* The export itself will run in a seperate thread, whilst this dialog will @@ -546,7 +546,6 @@ public void stateChanged(ChangeEvent e) { * invoked. */ private void startExport() { - if (treeModel == null) { return; } @@ -555,7 +554,6 @@ private void startExport() { CheckableTreeNode root = (CheckableTreeNode) treeModel.getRoot(); final List fileList = getFileListFromNode(root); - if ((fileList == null) || fileList.isEmpty()) { return; } @@ -606,7 +604,6 @@ private void startExport() { /** */ private void exportFinishedHandler() { - progressBarImporting.setVisible(false); labelExportingInfo.setVisible(false); buttonExport.setVisible(true); From d78dde4967e358e73a94327da0653fec61b80aaa Mon Sep 17 00:00:00 2001 From: Jeffrey Sander Date: Tue, 1 May 2018 14:47:21 -0400 Subject: [PATCH 5/5] Add Text File Export for "Find Unlinked Files" --- .../jabref/gui/FindUnlinkedFilesDialog.java | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java index ecf2432bf95..aea7055cf98 100644 --- a/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java +++ b/src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java @@ -542,7 +542,7 @@ public void stateChanged(ChangeEvent e) { * The export itself will run in a seperate thread, whilst this dialog will * be showing a progress bar, until the thread has finished its work.
*
- * When the export has finished, the {@link #exportFinishedHandler(java.util.List)} is + * When the export has finished, the {@link #exportFinishedHandler()} is * invoked. */ private void startExport() { @@ -558,20 +558,11 @@ private void startExport() { return; } - progressBarImporting.setVisible(true); - labelExportingInfo.setVisible(true); buttonExport.setVisible(false); buttonApply.setVisible(false); buttonClose.setVisible(false); disOrEnableDialog(false); - labelExportingInfo.setEnabled(true); - - progressBarImporting.setMinimum(0); - progressBarImporting.setMaximum(fileList.size()); - progressBarImporting.setValue(0); - progressBarImporting.setString(""); - FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() .withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build(); DialogService ds = new FXDialogService(); @@ -579,18 +570,18 @@ private void startExport() { Optional exportPath = DefaultTaskExecutor .runInJavaFXThread(() -> ds.showFileSaveDialog(fileDialogConfiguration)); + if (!exportPath.isPresent()) { + exportFinishedHandler(); + return; + } + threadState.set(true); JabRefExecutorService.INSTANCE.execute(() -> { try (BufferedWriter writer = Files.newBufferedWriter(exportPath.get(), StandardCharsets.UTF_8, StandardOpenOption.CREATE)) { - int counter = 0; for (File file : fileList) { writer.write(file.toString() + "\n"); - counter++; - progressBarImporting.setValue(counter); - progressBarImporting.setString(Localization.lang("%0 of %1", Integer.toString(counter), - Integer.toString(progressBarImporting.getMaximum()))); } } catch (IOException e) { @@ -601,11 +592,7 @@ private void startExport() { exportFinishedHandler(); } - /** - */ private void exportFinishedHandler() { - progressBarImporting.setVisible(false); - labelExportingInfo.setVisible(false); buttonExport.setVisible(true); buttonApply.setVisible(true); buttonClose.setVisible(true); @@ -697,10 +684,8 @@ private void setupActions() { * Actions on this button will start the import of all file of all * selected nodes in this dialogs tree view.
*/ - ActionListener actionListenerImportEntrys = e -> startImport(); - ActionListener actionListenerExportEntrys = e -> startExport(); - buttonExport.addActionListener(actionListenerExportEntrys); - buttonApply.addActionListener(actionListenerImportEntrys); + buttonExport.addActionListener(e -> startExport()); + buttonApply.addActionListener(e -> startImport()); buttonClose.addActionListener(e -> dispose()); }