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

Export pdf/linked files #3147

Merged
merged 36 commits into from
Nov 1, 2017
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9d38d12
First approach for implementing PDF Exporter
Siedlerchr Apr 2, 2017
00eccc7
First approach for implementing PDF Exporter
Siedlerchr Oct 7, 2017
50e9716
Add to File menu and context menu
Siedlerchr Oct 7, 2017
26a7e1f
Remove separator from tools menu
Siedlerchr Oct 7, 2017
ec7c44b
fix fileUtil and localzation from rebase
Siedlerchr Oct 7, 2017
68e1562
Remove empty line
Siedlerchr Oct 7, 2017
d1b53eb
Move service to new class
Siedlerchr Oct 8, 2017
7021371
Fix translation
Siedlerchr Oct 8, 2017
6b02e9c
Add idea for list view dialog
Siedlerchr Oct 8, 2017
edec73d
Merge remote-tracking branch 'upstream/master' into exportPdf
Siedlerchr Oct 11, 2017
95474ea
Merge remote-tracking branch 'upstream/master' into exportPdf
Siedlerchr Oct 19, 2017
bed0a54
Add TableView to show log message
Siedlerchr Oct 19, 2017
e347bc9
Add class for table view data
Siedlerchr Oct 19, 2017
090a4cd
Add Green/Red icons for status
Siedlerchr Oct 19, 2017
93f72b2
fix checkstyle and make cancel button close button
Siedlerchr Oct 19, 2017
353e9ad
fix codacy
Siedlerchr Oct 20, 2017
f29066c
Merge remote-tracking branch 'upstream/master' into exportPdf
Siedlerchr Oct 20, 2017
aa10731
Renamings
Siedlerchr Oct 20, 2017
9e6cffc
Remove setter
Siedlerchr Oct 20, 2017
b61082c
Add fxml and move to package
Siedlerchr Oct 20, 2017
713ecec
fix controller
Siedlerchr Oct 20, 2017
cfa74e5
Merge remote-tracking branch 'upstream/master' into exportPdf
Siedlerchr Oct 21, 2017
4c01181
add button data
Siedlerchr Oct 21, 2017
cc30b98
Add new wrapper class for injection
Siedlerchr Oct 21, 2017
a67cd4e
Add todos hinting at empty
Siedlerchr Oct 21, 2017
5d96526
Fix injection of data
Siedlerchr Oct 21, 2017
8011e6e
rebame and fix checkstyle
Siedlerchr Oct 21, 2017
bb1a304
Make variables private
Siedlerchr Oct 21, 2017
5e1117a
Merge remote-tracking branch 'upstream/master' into exportPdf
Siedlerchr Oct 22, 2017
8dabe6d
Merge remote-tracking branch 'upstream/master' into exportPdf
Siedlerchr Oct 25, 2017
fc7a2a1
fix merge error in lang files
Siedlerchr Oct 25, 2017
ba35360
Fix some coday warnings
Siedlerchr Oct 25, 2017
88faa7c
Rename l10n
Siedlerchr Oct 26, 2017
658d97e
Merge remote-tracking branch 'upstream/master' into exportPdf
Siedlerchr Oct 31, 2017
8f14cc7
fix showing of progress bar
Siedlerchr Oct 31, 2017
07ee6ea
Merge branch 'exportPdf' of https://github.com/JabRef/jabref into exp…
Siedlerchr Oct 31, 2017
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We now set the WM_CLASS of the UI to org-jabref-JabRefMain to allow certain Un*x window managers to properly identify its windows
- We changed the default paths for the OpenOffice/LibreOffice binaries to the default path for LibreOffice
- We no longer create a new entry editor when selecting a new entry to increase performance. [#3187](https://github.com/JabRef/jabref/pull/3187)
- We added the possibility to copy linked files from entries to a single output folder [#2539](https://github.com/JabRef/jabref/pull/2593)

### Fixed
- We fixed the translation of \textendash in the entry preview [#3307](https://github.com/JabRef/jabref/issues/3307)
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/org/jabref/gui/DialogService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.List;
import java.util.Optional;

import javafx.concurrent.Service;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.DialogPane;
Expand All @@ -13,6 +14,8 @@
import org.jabref.gui.util.FileDialogConfiguration;
import org.jabref.logic.l10n.Localization;

import org.controlsfx.dialog.ProgressDialog;

/**
* This interface provides methods to create dialogs and show them to the user.
*/
Expand Down Expand Up @@ -121,6 +124,12 @@ Optional<ButtonType> showCustomButtonDialogAndWait(Alert.AlertType type, String
*/
<R> Optional<R> showCustomDialogAndWait(Dialog<R> dialog);

/**
* Constructs and shows a canceable {@link ProgressDialog}. Clicking cancel will cancel the underlying service and close the dialog
* @param service The {@link Service} which executes the work and for which to show the dialog
*/
<V> void showCanceableProgressDialogAndWait(Service<V> service);

/**
* Notify the user in an non-blocking way (i.e., update status message instead of showing a dialog).
* @param message the message to show.
Expand Down Expand Up @@ -173,4 +182,5 @@ Optional<ButtonType> showCustomButtonDialogAndWait(Alert.AlertType type, String
* @return A configured instance of the {@link FileChooser}
*/
FileChooser getConfiguredFileChooser(FileDialogConfiguration fileDialogConfiguration);

}
18 changes: 18 additions & 0 deletions src/main/java/org/jabref/gui/FXDialogService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import java.util.Optional;
import java.util.stream.Collectors;

import javafx.concurrent.Service;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.control.DialogPane;
Expand All @@ -22,6 +24,7 @@
import org.jabref.logic.l10n.Localization;

import org.controlsfx.dialog.ExceptionDialog;
import org.controlsfx.dialog.ProgressDialog;

/**
* This class provides methods to create default
Expand Down Expand Up @@ -127,6 +130,21 @@ public <R> Optional<R> showCustomDialogAndWait(Dialog<R> dialog) {
return dialog.showAndWait();
}

@Override
public <V> void showCanceableProgressDialogAndWait(Service<V> service) {
ProgressDialog progressDialog = new ProgressDialog(service);
progressDialog.setOnCloseRequest(evt -> service.cancel());
DialogPane dialogPane = progressDialog.getDialogPane();
dialogPane.getButtonTypes().add(ButtonType.CANCEL);
Button cancelButton = (Button) dialogPane.lookupButton(ButtonType.CANCEL);
cancelButton.setOnAction(evt -> {
service.cancel();
progressDialog.close();
});
progressDialog.showAndWait();

}

@Override
public void notify(String message) {
JabRefGUI.getMainFrame().output(message);
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/org/jabref/gui/JabRefFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import org.jabref.gui.actions.AutoLinkFilesAction;
import org.jabref.gui.actions.ConnectToSharedDatabaseAction;
import org.jabref.gui.actions.ErrorConsoleAction;
import org.jabref.gui.actions.ExportLinkedFilesAction;
import org.jabref.gui.actions.IntegrityCheckAction;
import org.jabref.gui.actions.LookupIdentifierAction;
import org.jabref.gui.actions.ManageKeywordsAction;
Expand Down Expand Up @@ -389,6 +390,7 @@ public void actionPerformed(ActionEvent e) {
Localization.menuTitle("Unabbreviate journal names"),
Localization.lang("Unabbreviate journal names of the selected entries"),
Globals.getKeyPrefs().getKey(KeyBinding.UNABBREVIATE));
private final AbstractAction exportLinkedFiles = new ExportLinkedFilesAction();
private final AbstractAction manageJournals = new ManageJournalsAction();
private final AbstractAction databaseProperties = new DatabasePropertiesAction();
private final AbstractAction bibtexKeyPattern = new BibtexKeyPatternAction();
Expand Down Expand Up @@ -1059,6 +1061,7 @@ private void fillMenu() {
file.add(importCurrent);
file.add(exportAll);
file.add(exportSelected);
file.add(exportLinkedFiles);
file.addSeparator();
file.add(connectToSharedDatabaseAction);
file.add(pullChangesFromSharedDatabase);
Expand Down Expand Up @@ -1440,7 +1443,7 @@ dupliCheck, autoSetFile, newEntryAction, newSpec, customizeAction, plainTextImpo
twoEntriesOnlyActions.addAll(Arrays.asList(mergeEntries));

atLeastOneEntryActions.clear();
atLeastOneEntryActions.addAll(Arrays.asList(downloadFullText, lookupIdentifiers));
atLeastOneEntryActions.addAll(Arrays.asList(downloadFullText, lookupIdentifiers, exportLinkedFiles));

tabbedPane.addChangeListener(event -> updateEnabledState());

Expand Down
50 changes: 50 additions & 0 deletions src/main/java/org/jabref/gui/actions/CopyFilesResultViewModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.jabref.gui.actions;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;

public class CopyFilesResultViewModel {

private final StringProperty file = new SimpleStringProperty("");
private final ObjectProperty<MaterialDesignIcon> icon = new SimpleObjectProperty<>(MaterialDesignIcon.ALERT);

private final StringProperty message = new SimpleStringProperty("");

public CopyFilesResultViewModel(String file, boolean success, String message) {
Copy link
Member

Choose a reason for hiding this comment

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

maybe change the name Result -> ResultItem to make it clearer that is one item in the result window.

Copy link
Member

Choose a reason for hiding this comment

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

Please change the file from string to path

this.file.setValue(file);
this.message.setValue(message);
if (success) {
this.icon.setValue(MaterialDesignIcon.CHECK);
}

}

public StringProperty getFile() {
return file;
}

public void setFile(String file) {
Copy link
Member

Choose a reason for hiding this comment

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

are these setters needed? I find an immutable solution better.

this.file.setValue(file);
}

public StringProperty getMessage() {
return message;
}

public void setMessage(String message) {
this.message.setValue(message);
}

public ObjectProperty<MaterialDesignIcon> getIcon() {
return icon;
}

@Override
public String toString() {
return "CopyFilesResultViewModel [file=" + file.get() + ", message=" + message.get() + "]";
}
}
143 changes: 143 additions & 0 deletions src/main/java/org/jabref/gui/actions/ExportLinkedFilesAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package org.jabref.gui.actions;

import java.awt.event.ActionEvent;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Optional;

import javax.swing.AbstractAction;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Service;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;

import org.jabref.Globals;
import org.jabref.JabRefGUI;
import org.jabref.gui.DialogService;
import org.jabref.gui.FXDialogService;
import org.jabref.gui.util.DefaultTaskExecutor;
import org.jabref.gui.util.DirectoryDialogConfiguration;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.preferences.JabRefPreferences;

import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
import de.jensd.fx.glyphs.materialdesignicons.utils.MaterialDesignIconFactory;

public class ExportLinkedFilesAction extends AbstractAction {

private final DialogService dialogService = new FXDialogService();
private BibDatabaseContext databaseContext;
private List<BibEntry> entries;

public ExportLinkedFilesAction() {
super(Localization.lang("Copy attached files to folder..."));
}

@Override
public void actionPerformed(ActionEvent e) {

DirectoryDialogConfiguration dirDialogConfiguration = new DirectoryDialogConfiguration.Builder()
.withInitialDirectory(Paths.get(Globals.prefs.get(JabRefPreferences.EXPORT_WORKING_DIRECTORY)))
.build();
entries = JabRefGUI.getMainFrame().getCurrentBasePanel().getSelectedEntries();

Optional<Path> exportPath = DefaultTaskExecutor
.runInJavaFXThread(() -> dialogService.showDirectorySelectionDialog(dirDialogConfiguration));

exportPath.ifPresent(path -> {
databaseContext = JabRefGUI.getMainFrame().getCurrentBasePanel().getDatabaseContext();

Service<List<CopyFilesResultViewModel>> exportService = new ExportLinkedFilesService(databaseContext, entries, path);
startServiceAndshowProgessDialog(exportService);
});
}

private void startServiceAndshowProgessDialog(Service<List<CopyFilesResultViewModel>> exportService) {
DefaultTaskExecutor.runInJavaFXThread(() -> {
exportService.setOnSucceeded(value -> {
DefaultTaskExecutor.runInJavaFXThread(() -> showDialog(exportService.getValue()));
});
exportService.start();
DialogService dlgService = new FXDialogService();
Copy link
Member

Choose a reason for hiding this comment

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

you already have a dialog service at class level -> reuse?

dlgService.showCanceableProgressDialogAndWait(exportService);

});
}

private void showDialog(List<CopyFilesResultViewModel> data) {
Dialog<ButtonType> dlg = new Dialog<>();
Copy link
Member

Choose a reason for hiding this comment

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

Can you please extract the result dialog to a seperate fxml file, as all the other dialogs.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will do later. All other issues should be resolved now

dlg.setTitle(Localization.lang("Result"));
ObservableList<CopyFilesResultViewModel> tableData = FXCollections.observableArrayList(data);

TableView<CopyFilesResultViewModel> tv = createTable();
ScrollPane sp = new ScrollPane();
sp.setContent(tv);

dlg.getDialogPane().setContent(sp);
tv.setItems(tableData);

sp.setFitToHeight(true);
sp.setFitToWidth(true);

dlg.getDialogPane().getButtonTypes().add(ButtonType.CLOSE);
dlg.setResizable(true);
dlg.showAndWait();
}

private static TableView<CopyFilesResultViewModel> createTable() {
TableView<CopyFilesResultViewModel> tableResult = new TableView<>();

TableColumn<CopyFilesResultViewModel, String> colFile = new TableColumn<>(Localization.lang("File"));
TableColumn<CopyFilesResultViewModel, MaterialDesignIcon> colIcon = new TableColumn<>(Localization.lang("Status"));
TableColumn<CopyFilesResultViewModel, String> colMessage = new TableColumn<>(Localization.lang("Message"));

colFile.setCellValueFactory(cellData -> cellData.getValue().getFile());
colMessage.setCellValueFactory(cellData -> cellData.getValue().getMessage());
colIcon.setCellValueFactory(cellData -> cellData.getValue().getIcon());

colIcon.setCellFactory(column -> {
return new TableCell<CopyFilesResultViewModel, MaterialDesignIcon>() {
Copy link
Member

Choose a reason for hiding this comment

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

I think there is a table cell factory helper (similar to list view). If not, then I would be nice if you could create one.


@Override
protected void updateItem(MaterialDesignIcon item, boolean empty) {
super.updateItem(item, empty);

if ((item == null) || empty) {
setText(null);
setStyle("");
} else {
Text icon = MaterialDesignIconFactory.get().createIcon(item);

//Green checkmark
if (item == MaterialDesignIcon.CHECK) {
icon.setFill(Color.GREEN);
}
//Red Alert symbol
if (item == MaterialDesignIcon.ALERT) {
icon.setFill(Color.RED);
}
setGraphic(icon);

}
}
};
});
tableResult.getColumns().add(colIcon);
tableResult.getColumns().add(colMessage);
tableResult.getColumns().add(colFile);

return tableResult;
}

}
Loading