Skip to content

Commit

Permalink
Merge pull request #2692 from JabRef/pdfViewer
Browse files Browse the repository at this point in the history
Add PDF Viewer
  • Loading branch information
tobiasdiez committed Apr 8, 2017
2 parents 0c88693 + e7e87d4 commit 65dccbf
Show file tree
Hide file tree
Showing 59 changed files with 1,215 additions and 42 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- Redesigned error console.
- All file dialogs now use the native file selector of the OS. [#1711](https://github.com/JabRef/jabref/issues/1711)
- Switch to the [latex2unicode library](https://github.com/tomtung/latex2unicode) for converting LaTeX to unicode
- We added a document viewer which allows you to have a glance at your PDF documents directly from within JabRef.
- The MS Office XML export now exports the field `volumes` and `pubstate`.
- The integrity checker reports now if a journal is not found in the abbreviation list
- Comments in PDF files can now be displayed inside JabRef in a separate tab
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ dependencies {
compile 'de.codecentric.centerdevice:javafxsvg:1.2.1'
compile 'org.controlsfx:controlsfx:8.40.12'
compile 'org.fxmisc.easybind:easybind:1.0.3'
compile 'org.fxmisc.flowless:flowless:0.5.2'
compile 'de.jensd:fontawesomefx-materialdesignfont:1.7.22-4'


compile 'commons-logging:commons-logging:1.2'
Expand Down
10 changes: 10 additions & 0 deletions external-libraries.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ Projekt: EasyBind
URL: https://github.com/TomasMikula/EasyBind
License: BSD-2-Clause

Id: org.fxmisc.flowless:flowless
Projekt: Flowless
URL: https://github.com/TomasMikula/Flowless
License: BSD-2-Clause

Id: de.jensd:fontawesomefx-materialdesignfont
Projekt: FontAwesomeFX
URL: https://bitbucket.org/Jerady/fontawesomefx
License: Apache-2.0

Id: org.jsoup:jsoup
Project: jsoup
URL: https://github.com/jhy/jsoup/
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/AbstractView.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public Parent getView() {
Parent view = super.getView();

// Add our base css file
view.getStylesheets().add(AbstractDialogView.class.getResource("Main.css").toExternalForm());
view.getStylesheets().add(0, AbstractDialogView.class.getResource("Main.css").toExternalForm());

// Notify controller about the stage, where it is displayed
view.sceneProperty().addListener((observable, oldValue, newValue) -> {
Expand Down
45 changes: 24 additions & 21 deletions src/main/java/org/jabref/gui/BasePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;

import javafx.application.Platform;

import org.jabref.Globals;
import org.jabref.JabRefExecutorService;
import org.jabref.collab.ChangeScanner;
Expand Down Expand Up @@ -237,6 +239,26 @@ public BasePanel(JabRefFrame frame, BibDatabaseContext bibDatabaseContext) {
}
}

public static void runWorker(AbstractWorker worker) throws Exception {
// This part uses Spin's features:
Runnable wrk = worker.getWorker();
// The Worker returned by getWorker() has been wrapped
// by Spin.off(), which makes its methods be run in
// a different thread from the EDT.
CallBack clb = worker.getCallBack();

worker.init(); // This method runs in this same thread, the EDT.
// Useful for initial GUI actions, like printing a message.

// The CallBack returned by getCallBack() has been wrapped
// by Spin.over(), which makes its methods be run on
// the EDT.
wrk.run(); // Runs the potentially time-consuming action
// without freezing the GUI. The magic is that THIS line
// of execution will not continue until run() is finished.
clb.update(); // Runs the update() method on the EDT.
}

// Returns a collection of AutoCompleters, which are populated from the current library
public ContentAutoCompleters getAutoCompleters() {
return autoCompleters;
Expand Down Expand Up @@ -999,26 +1021,6 @@ public void runCommand(final String _command) {
}
}

public static void runWorker(AbstractWorker worker) throws Exception {
// This part uses Spin's features:
Runnable wrk = worker.getWorker();
// The Worker returned by getWorker() has been wrapped
// by Spin.off(), which makes its methods be run in
// a different thread from the EDT.
CallBack clb = worker.getCallBack();

worker.init(); // This method runs in this same thread, the EDT.
// Useful for initial GUI actions, like printing a message.

// The CallBack returned by getCallBack() has been wrapped
// by Spin.over(), which makes its methods be run on
// the EDT.
wrk.run(); // Runs the potentially time-consuming action
// without freezing the GUI. The magic is that THIS line
// of execution will not continue until run() is finished.
clb.update(); // Runs the update() method on the EDT.
}

private boolean saveDatabase(File file, boolean selectedOnly, Charset enc,
SavePreferences.DatabaseSaveType saveType) throws SaveException {
SaveSession session;
Expand Down Expand Up @@ -1230,7 +1232,8 @@ private void createMainTable() {
mainTable.addFocusListener(selectionListener);

// Add the listener that binds selection to state manager (TODO: should be replaced by proper JavaFX binding as soon as table is implemented in JavaFX)
mainTable.addSelectionListener(listEvent -> Globals.stateManager.setSelectedEntries(mainTable.getSelectedEntries()));
mainTable.addSelectionListener(listEvent ->
Platform.runLater(() -> Globals.stateManager.setSelectedEntries(mainTable.getSelectedEntries())));

String clearSearch = "clearSearch";
mainTable.getInputMap().put(Globals.getKeyPrefs().getKey(KeyBinding.CLEAR_SEARCH), clearSearch);
Expand Down
33 changes: 18 additions & 15 deletions src/main/java/org/jabref/gui/IconTheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,21 @@ public class IconTheme {
private static javafx.scene.text.Font FX_FONT;

static {
try (InputStream stream = FontBasedIcon.class.getResourceAsStream("/fonts/materialdesignicons-webfont.ttf")) {
try (InputStream stream = getMaterialDesignIconsStream()) {
FONT = Font.createFont(Font.TRUETYPE_FONT, stream);
FONT_16 = FONT.deriveFont(Font.PLAIN, 16f);
try (InputStream stream2 = FontBasedIcon.class.getResourceAsStream("/fonts/materialdesignicons-webfont.ttf")) {
try (InputStream stream2 = getMaterialDesignIconsStream()) {
FX_FONT = javafx.scene.text.Font.loadFont(stream2, JabRefPreferences.getInstance().getInt(JabRefPreferences.ICON_SIZE_LARGE));
}
} catch (FontFormatException | IOException e) {
LOGGER.warn("Error loading font", e);
}
}

private static InputStream getMaterialDesignIconsStream() {
return FontBasedIcon.class.getResourceAsStream("/fonts/materialdesignicons-webfont.ttf");
}

public static javafx.scene.paint.Color getDefaultColor() {
return javafx.scene.paint.Color.rgb(DEFAULT_COLOR.getRed(), DEFAULT_COLOR.getGreen(), DEFAULT_COLOR.getBlue(), DEFAULT_COLOR.getAlpha() / 255.0);
}
Expand Down Expand Up @@ -146,6 +150,18 @@ private static Map<String, String> readIconThemeFile(URL url, String prefix) {
return result;
}

public static List<java.awt.Image> getLogoSet() {
List<java.awt.Image> jabrefLogos = new ArrayList<>();
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon16")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon20")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon32")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon40")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon48")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon64")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon128")).getImage());

return jabrefLogos;
}

public enum JabRefIcon {

Expand Down Expand Up @@ -344,17 +360,4 @@ public FontBasedIcon createWithNewColor(Color newColor) {
return new FontBasedIcon(this.iconCode, newColor, this.size);
}
}

public static List<java.awt.Image> getLogoSet() {
List<java.awt.Image> jabrefLogos = new ArrayList<>();
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon16")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon20")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon32")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon40")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon48")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon64")).getImage());
jabrefLogos.add(new ImageIcon(getIconUrl("jabrefIcon128")).getImage());

return jabrefLogos;
}
}
3 changes: 3 additions & 0 deletions src/main/java/org/jabref/gui/JabRefFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import org.jabref.gui.bibtexkeypattern.BibtexKeyPatternDialog;
import org.jabref.gui.customentrytypes.EntryCustomizationDialog;
import org.jabref.gui.dbproperties.DatabasePropertiesDialog;
import org.jabref.gui.documentviewer.ShowDocumentViewerAction;
import org.jabref.gui.exporter.ExportAction;
import org.jabref.gui.exporter.ExportCustomizationDialog;
import org.jabref.gui.exporter.SaveAllAction;
Expand Down Expand Up @@ -324,6 +325,7 @@ public void actionPerformed(ActionEvent e) {
tlb.setVisible(!tlb.isVisible());
}
});
private final AbstractAction showPdvViewer = new ShowDocumentViewerAction();
private final AbstractAction addToGroup = new GeneralAction(Actions.ADD_TO_GROUP, Localization.lang("Add to group") + ELLIPSES);
private final AbstractAction removeFromGroup = new GeneralAction(Actions.REMOVE_FROM_GROUP,
Localization.lang("Remove from group") + ELLIPSES);
Expand Down Expand Up @@ -1173,6 +1175,7 @@ private void fillMenu() {
view.add(new JCheckBoxMenuItem(enableToggle(generalFetcher.getToggleAction())));
view.add(new JCheckBoxMenuItem(groupSelector.getToggleAction()));
view.add(new JCheckBoxMenuItem(togglePreview));
view.add(showPdvViewer);
view.add(getNextPreviewStyleAction());
view.add(getPreviousPreviewStyleAction());

Expand Down
28 changes: 28 additions & 0 deletions src/main/java/org/jabref/gui/Main.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
* A dark gray as background
*/
-fx-dark-background: #757575;

/*
* A strong blue for backgrounds of active items (toggle button, selected list item)
*/
-fx-active-background: #6A9FCD;

}

.hyperlink {
Expand All @@ -48,9 +54,31 @@
.icon {
-fx-font-family: 'Material Design Icons';
-fx-font-size: 16.0;
}

.glyph-icon {
-fx-font-size: 16.0;
-glyph-size: 16.0;
}

.tooltip {
-fx-background-color: #757575; /* For some reason it does not work if we use -fx-dark-background here */
-fx-effect:none;
}

.flatButton {
-fx-shadow-highlight-color: transparent;
-fx-outer-border: transparent;
-fx-inner-border: transparent;
-fx-focus-color: #6A9FCD;
-fx-faint-focus-color: transparent;
-fx-background-color: transparent;
-fx-text-background-color: dimgray;
-fx-padding: 0.5em;
}

.flatButton:selected {
-fx-background-color: -fx-active-background;
-fx-text-fill: white;
-fx-fill: white;
}
9 changes: 6 additions & 3 deletions src/main/java/org/jabref/gui/StateManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,11 @@ public ReadOnlyObjectProperty<Optional<GroupTreeNode>> activeGroupProperty() {
}

public ObservableList<BibEntry> getSelectedEntries() {
return FXCollections.unmodifiableObservableList(selectedEntries);
return selectedEntries;
}

public void setSelectedEntries(List<BibEntry> newSelectedEntries) {
selectedEntries.clear();
selectedEntries.addAll(newSelectedEntries);
selectedEntries.setAll(newSelectedEntries);
}

public void setSelectedGroup(BibDatabaseContext database, GroupTreeNode newSelectedGroup) {
Expand All @@ -72,6 +71,10 @@ public void clearSelectedGroup(BibDatabaseContext database) {
selectedGroups.remove(database);
}

public Optional<BibDatabaseContext> getActiveDatabase() {
return activeDatabase.get();
}

public List<BibEntry> getEntriesInCurrentDatabase() {
return OptionalUtil.flatMap(activeDatabase.get(), BibDatabaseContext::getEntries)
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.jabref.gui.documentviewer;

import javafx.scene.image.Image;

/**
* Represents the view model for a page in the document viewer.
*/
public abstract class DocumentPageViewModel {

/**
* Renders this page and returns an image representation of itself.
* @param width
* @param height
*/
public abstract Image render(int width, int height);

/**
* Get the page number of the current page in the document.
*/
public abstract int getPageNumber();

/**
* Calculates the aspect ratio (width / height) of the page.
*/
public abstract double getAspectRatio();
}
19 changes: 19 additions & 0 deletions src/main/java/org/jabref/gui/documentviewer/DocumentViewModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.jabref.gui.documentviewer;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.ObservableList;

public abstract class DocumentViewModel {
private IntegerProperty maxPages = new SimpleIntegerProperty();

public abstract ObservableList<DocumentPageViewModel> getPages();

public int getMaxPages() {
return maxPages.get();
}

public IntegerProperty maxPagesProperty() {
return maxPages;
}
}
10 changes: 10 additions & 0 deletions src/main/java/org/jabref/gui/documentviewer/DocumentViewer.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#mainPane {
-fx-background-color: -fx-accented-background;
-fx-padding: 0;
}

.document-viewer .page {
-fx-padding: 0em 0em 1em 0em;
-fx-background-insets: 0;
}

Loading

0 comments on commit 65dccbf

Please sign in to comment.