Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add Text File Export for "Find Unlinked Files" #3979

Merged
merged 7 commits into from
May 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
## [Unreleased]

### Changed
We added RFC, a new entry generator ID type. [#3971](https://github.com/JabRef/jabref/issues/3971)
- We added a text file export for 'Find Unlinked Files'. [#3341](https://github.com/JabRef/jabref/issues/3341)
- We added a new entry generator ID type. [#3971](https://github.com/JabRef/jabref/issues/3971)

### Fixed
We fixed an issue where the export to clipboard functionality could not be invoked [#3994](https://github.com/JabRef/jabref/issues/3994)

Expand Down
89 changes: 87 additions & 2 deletions src/main/java/org/jabref/gui/FindUnlinkedFilesDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
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.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;
Expand Down Expand Up @@ -74,6 +77,7 @@
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.l10n.Localization;
import org.jabref.model.EntryTypes;
import org.jabref.model.database.BibDatabaseContext;
Expand Down Expand Up @@ -123,6 +127,7 @@ public class FindUnlinkedFilesDialog extends JabRefDialog {
private JPanel panelImportArea;
private JButton buttonBrowse;
private JButton buttonScan;
private JButton buttonExport;
private JButton buttonApply;

private JButton buttonClose;
Expand All @@ -141,6 +146,7 @@ public class FindUnlinkedFilesDialog extends JabRefDialog {
private JLabel labelSearchingDirectoryInfo;

private JLabel labelImportingInfo;
private JLabel labelExportingInfo;
private JTree tree;
private JScrollPane scrollpaneTree;
private JComboBox<FileFilter> comboBoxFileTypeSelection;
Expand Down Expand Up @@ -175,6 +181,7 @@ public FindUnlinkedFilesDialog(Frame owner, JabRefFrame frame, BasePanel panel)

initialize();
buttonApply.setEnabled(false);
buttonExport.setEnabled(false);
}

/**
Expand Down Expand Up @@ -493,6 +500,7 @@ private void startImport() {

progressBarImporting.setVisible(true);
labelImportingInfo.setVisible(true);
buttonExport.setVisible(false);
buttonApply.setVisible(false);
buttonClose.setVisible(false);
disOrEnableDialog(false);
Expand Down Expand Up @@ -527,6 +535,72 @@ public void stateChanged(ChangeEvent e) {
});
}

/**
* This starts the export of all files of all selected nodes in this
* dialogs tree view. <br>
* <br>
* 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. <br>
* <br>
* When the export has finished, the {@link #exportFinishedHandler()} is
* invoked.
*/
private void startExport() {
if (treeModel == null) {
return;
}
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

CheckableTreeNode root = (CheckableTreeNode) treeModel.getRoot();

final List<File> fileList = getFileListFromNode(root);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be preferable if you change the return type from File to Path of the method, as the Path-Class is part of the java.nio and therefore the more modern way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is used for the importing which I basically copied and then modified to do the exporting.

if ((fileList == null) || fileList.isEmpty()) {
return;
}

buttonExport.setVisible(false);
buttonApply.setVisible(false);
buttonClose.setVisible(false);
disOrEnableDialog(false);

FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
.withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build();
DialogService ds = new FXDialogService();

Optional<Path> exportPath = DefaultTaskExecutor
.runInJavaFXThread(() -> ds.showFileSaveDialog(fileDialogConfiguration));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a check if exportPath is present. If not (i.e. the user clicked cancel), then we should return early.

if (!exportPath.isPresent()) {
exportFinishedHandler();
return;
}

threadState.set(true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this variable/method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure exactly. It is a hold over from the import method which I based the export method on. I guessed that it was needed to start the thread.

JabRefExecutorService.INSTANCE.execute(() -> {
try (BufferedWriter writer =
Files.newBufferedWriter(exportPath.get(), StandardCharsets.UTF_8,
StandardOpenOption.CREATE)) {
for (File file : fileList) {
writer.write(file.toString() + "\n");
}

} catch (IOException e) {
LOGGER.warn("IO Error.", e);
}
});

exportFinishedHandler();
}

private void exportFinishedHandler() {
buttonExport.setVisible(true);
buttonApply.setVisible(true);
buttonClose.setVisible(true);
disOrEnableDialog(true);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.getCurrentBasePanel().markBaseChanged();
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are on it - please remove the method comment 😇 - or add description. The functionality is not exactly clear by the method name.

/**
*
* @param errors
Expand All @@ -548,6 +622,7 @@ private void importFinishedHandler(List<String> errors) {

progressBarImporting.setVisible(false);
labelImportingInfo.setVisible(false);
buttonExport.setVisible(true);
buttonApply.setVisible(true);
buttonClose.setVisible(true);
disOrEnableDialog(true);
Expand Down Expand Up @@ -578,6 +653,7 @@ private void searchFinishedHandler(CheckableTreeNode rootNode) {

disOrEnableDialog(true);
buttonApply.setEnabled(true);
buttonExport.setEnabled(true);
}

/**
Expand Down Expand Up @@ -608,8 +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. <br>
*/
ActionListener actionListenerImportEntrys = e -> startImport();
buttonApply.addActionListener(actionListenerImportEntrys);
buttonExport.addActionListener(e -> startExport());
buttonApply.addActionListener(e -> startImport());
buttonClose.addActionListener(e -> dispose());
}

Expand Down Expand Up @@ -691,6 +767,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."));
Expand Down Expand Up @@ -733,6 +812,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();

Expand Down Expand Up @@ -815,6 +897,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,
Expand All @@ -832,6 +916,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();
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down