Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into moveFileDir
Browse files Browse the repository at this point in the history
* upstream/master:
  Fix error when path is no valid directory (#2527)
  French localization: translation of a string
  French menu: localization
  Highlight groups that match any/all of the entries selected in the main table. (#2515)
  Fix % sign cleanup (#2521)
  Revert "Fix repeated escaping of % sign" (#2520)
  Fix repeated escaping of % sign (#2519)
  fix for #2482 deadlock on PDF import (#2517)
  • Loading branch information
Siedlerchr committed Feb 8, 2017
2 parents 367f992 + 4e3b48f commit d888684
Show file tree
Hide file tree
Showing 52 changed files with 1,146 additions and 1,332 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- Add tab which shows the MathSciNet review website if the `MRNumber` field is present.
- Partly switched to new UI technology (JavaFX).
- Redesigned group panel.
- Number of matched entries is always shown.
- The background color of the hit counter signals whether the group contains all/any of the entries selected in the main table.
- Redesigned about dialog.
- Redesigned key bindings dialog.
- Redesigned journal abbreviations dialog.
Expand All @@ -27,6 +29,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- Fix import of journal title in ris format. [#2506](https://github.com/JabRef/jabref/issues/2506)
- We fixed the export of the `number` field in MS-Office XML export. [#2509](https://github.com/JabRef/jabref/issues/2509)
- The field `issue` is now always exported to the corresponding `issue` field in MS-Office XML.
- We fixed an issue with repeated escaping of the %-sign when running the LaTeXCleanup more than once. [#2451](https://github.com/JabRef/jabref/issues/2451)
### Removed


Expand Down
783 changes: 363 additions & 420 deletions src/main/java/net/sf/jabref/gui/BasePanel.java

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion src/main/java/net/sf/jabref/gui/FileDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.awt.Component;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
Expand Down Expand Up @@ -59,7 +60,10 @@ public FileDialog(Component parent, String dir) {

public FileDialog(Component parent, Path dir) {
Objects.requireNonNull(dir, "Directory must not be null");

//Dir must be a folder, not a file
if (!Files.isDirectory(dir)) {
dir = dir.getParent();
}
fileChooser = new FileChooser();
configurationBuilder = new FileDialogConfiguration.Builder();
configurationBuilder = configurationBuilder.withInitialDirectory(dir);
Expand Down Expand Up @@ -137,6 +141,7 @@ public Optional<Path> showDialogAndGetSelectedDirectory() {

return runInJavaFXThread(() -> Optional.ofNullable(directoryChooser.showDialog(null)).map(File::toPath));
}

/**
* 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
Expand Down
1,025 changes: 472 additions & 553 deletions src/main/java/net/sf/jabref/gui/JabRefFrame.java

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/main/java/net/sf/jabref/gui/StateManager.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package net.sf.jabref.gui;

import java.util.List;
import java.util.Optional;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import net.sf.jabref.model.database.BibDatabaseContext;
import net.sf.jabref.model.entry.BibEntry;
import net.sf.jabref.model.groups.GroupTreeNode;

/**
Expand All @@ -20,6 +24,7 @@ public class StateManager {

private final ObjectProperty<Optional<BibDatabaseContext>> activeDatabase = new SimpleObjectProperty<>(Optional.empty());
private final ObjectProperty<Optional<GroupTreeNode>> activeGroup = new SimpleObjectProperty<>(Optional.empty());
private final ObservableList<BibEntry> selectedEntries = FXCollections.observableArrayList();

public ObjectProperty<Optional<BibDatabaseContext>> activeDatabaseProperty() {
return activeDatabase;
Expand All @@ -28,4 +33,13 @@ public ObjectProperty<Optional<BibDatabaseContext>> activeDatabaseProperty() {
public ObjectProperty<Optional<GroupTreeNode>> activeGroupProperty() {
return activeGroup;
}

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

public void setSelectedEntries(List<BibEntry> newSelectedEntries) {
selectedEntries.clear();
selectedEntries.addAll(newSelectedEntries);
}
}
3 changes: 0 additions & 3 deletions src/main/java/net/sf/jabref/gui/actions/Actions.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ public class Actions {
public static final String GLOBAL_SEARCH = "globalSearch";
public static final String SELECT_ALL = "selectAll";
public static final String SEND_AS_EMAIL = "sendAsEmail";
public static final String TOGGLE_HIGHLIGHTS_GROUPS_MATCHING_ALL = "toggleHighlightGroupsMatchingAll";
public static final String TOGGLE_HIGHLIGHTS_GROUPS_MATCHING_ANY = "toggleHighlightGroupsMatchingAny";
public static final String TOGGLE_HIGHLIGHTS_GROUPS_MATCHING_DISABLE = "toggleHighlightGroupsMatchingDisable";
public static final String TOGGLE_GROUPS = "toggleGroups";
public static final String TOGGLE_PREVIEW = "togglePreview";
public static final String UNABBREVIATE = "unabbreviate";
Expand Down
28 changes: 22 additions & 6 deletions src/main/java/net/sf/jabref/gui/groups/GroupNodeViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.ObservableList;

import net.sf.jabref.gui.StateManager;
import net.sf.jabref.gui.util.BindingsHelper;
import net.sf.jabref.logic.l10n.Localization;
import net.sf.jabref.model.database.BibDatabaseContext;
import net.sf.jabref.model.entry.event.EntryEvent;
Expand All @@ -28,31 +31,44 @@ public class GroupNodeViewModel {
private final GroupTreeNode groupNode;
private final SimpleIntegerProperty hits;
private final SimpleBooleanProperty hasChildren;
private final BooleanBinding anySelectedEntriesMatched;
private final BooleanBinding allSelectedEntriesMatched;

public GroupNodeViewModel(BibDatabaseContext databaseContext, GroupTreeNode groupNode) {
public GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager stateManager, GroupTreeNode groupNode) {
this.databaseContext = Objects.requireNonNull(databaseContext);
this.groupNode = Objects.requireNonNull(groupNode);

name = groupNode.getName();
isRoot = groupNode.isRoot();
iconCode = "";
children = EasyBind.map(groupNode.getChildren(), child -> new GroupNodeViewModel(databaseContext, child));
children = EasyBind.map(groupNode.getChildren(), child -> new GroupNodeViewModel(databaseContext, stateManager, child));
hasChildren = new SimpleBooleanProperty();
hasChildren.bind(Bindings.isNotEmpty(children));
hits = new SimpleIntegerProperty(0);
calculateNumberOfMatches();

// Register listener
databaseContext.getDatabase().registerListener(this);

ObservableList<Boolean> selectedEntriesMatchStatus = EasyBind.map(stateManager.getSelectedEntries(), groupNode::matches);
anySelectedEntriesMatched = BindingsHelper.any(selectedEntriesMatchStatus, matched -> matched);
allSelectedEntriesMatched = BindingsHelper.all(selectedEntriesMatchStatus, matched -> matched);
}

public GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager stateManager, AbstractGroup group) {
this(databaseContext, stateManager, new GroupTreeNode(group));
}

static GroupNodeViewModel getAllEntriesGroup(BibDatabaseContext newDatabase, StateManager stateManager) {
return new GroupNodeViewModel(newDatabase, stateManager, new AllEntriesGroup(Localization.lang("All entries")));
}

public GroupNodeViewModel(BibDatabaseContext databaseContext, AbstractGroup group) {
this(databaseContext, new GroupTreeNode(group));
public BooleanBinding anySelectedEntriesMatchedProperty() {
return anySelectedEntriesMatched;
}

static GroupNodeViewModel getAllEntriesGroup(BibDatabaseContext newDatabase) {
return new GroupNodeViewModel(newDatabase, new AllEntriesGroup(Localization.lang("All entries")));
public BooleanBinding allSelectedEntriesMatchedProperty() {
return allSelectedEntriesMatched;
}

public SimpleBooleanProperty hasChildrenProperty() {
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/net/sf/jabref/gui/groups/GroupTree.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
-fx-background-radius: 10px;
}

.numberColumn > .hits:any-selected {
-fx-background-color: #c6c44f;
}

.numberColumn > .hits:all-selected {
-fx-background-color: #4dc64f;
}

.disclosureNodeColumn {
-fx-alignment: top-right;
-fx-font-size: 12px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import net.sf.jabref.gui.AbstractController;
import net.sf.jabref.gui.DialogService;
import net.sf.jabref.gui.StateManager;
import net.sf.jabref.gui.util.BindingsHelper;
import net.sf.jabref.gui.util.RecursiveTreeItem;
import net.sf.jabref.gui.util.ViewModelTreeTableCellFactory;
import net.sf.jabref.logic.l10n.Localization;
Expand Down Expand Up @@ -59,10 +60,16 @@ public void initialize() {
);

// Number of hits
PseudoClass anySelected = PseudoClass.getPseudoClass("any-selected");
PseudoClass allSelected = PseudoClass.getPseudoClass("all-selected");
numberColumn.setCellFactory(new ViewModelTreeTableCellFactory<GroupNodeViewModel, GroupNodeViewModel>()
.withGraphic(viewModel -> {
final StackPane node = new StackPane();
node.getStyleClass().setAll("hits");
if (!viewModel.isRoot()) {
BindingsHelper.includePseudoClassWhen(node, anySelected, viewModel.anySelectedEntriesMatchedProperty());
BindingsHelper.includePseudoClassWhen(node, allSelected, viewModel.allSelectedEntriesMatchedProperty());
}
Text text = new Text();
text.textProperty().bind(viewModel.getHits().asString());
text.getStyleClass().setAll("text");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ private void onActiveDatabaseChanged(Optional<BibDatabaseContext> newDatabase) {
GroupNodeViewModel newRoot = newDatabase
.map(BibDatabaseContext::getMetaData)
.flatMap(MetaData::getGroups)
.map(root -> new GroupNodeViewModel(newDatabase.get(), root))
.orElse(GroupNodeViewModel.getAllEntriesGroup(newDatabase.get()));
.map(root -> new GroupNodeViewModel(newDatabase.get(), stateManager, root))
.orElse(GroupNodeViewModel.getAllEntriesGroup(newDatabase.get(), stateManager));
rootGroup.setValue(newRoot);
}
}
Expand Down
47 changes: 47 additions & 0 deletions src/main/java/net/sf/jabref/gui/util/BindingsHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package net.sf.jabref.gui.util;

import java.util.function.Predicate;

import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.BooleanPropertyBase;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.css.PseudoClass;
import javafx.scene.Node;

/**
* Helper methods for javafx binding.
* Some methods are taken from https://bugs.openjdk.java.net/browse/JDK-8134679
*/
public class BindingsHelper {
public static <T> BooleanBinding any(ObservableList<T> source, Predicate<T> predicate) {
return Bindings.createBooleanBinding(() -> source.stream().anyMatch(predicate), source);
}

public static <T> BooleanBinding all(ObservableList<T> source, Predicate<T> predicate) {
// Stream.allMatch() (in contrast to Stream.anyMatch() returns 'true' for empty streams, so this has to be checked explicitly.
return Bindings.createBooleanBinding(() -> !source.isEmpty() && source.stream().allMatch(predicate), source);
}

public static void includePseudoClassWhen(Node node, PseudoClass pseudoClass, ObservableValue<? extends Boolean> condition) {
BooleanProperty pseudoClassState = new BooleanPropertyBase(false) {
@Override
protected void invalidated() {
node.pseudoClassStateChanged(pseudoClass, get());
}

@Override
public Object getBean() {
return node;
}

@Override
public String getName() {
return pseudoClass.getPseudoClassName();
}
};
pseudoClassState.bind(condition);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
package net.sf.jabref.logic.formatter.bibtexfields;

import java.util.regex.Pattern;

import net.sf.jabref.logic.l10n.Localization;
import net.sf.jabref.model.cleanup.Formatter;

public class LatexCleanupFormatter implements Formatter {

private static final Pattern REMOVE_REDUNDANT = Pattern
.compile("(?<!\\\\[\\p{Alpha}]{0,100}\\{[^\\}]{0,100})\\}([-/ ]?)\\{");

private static final Pattern REPLACE_WITH_AT = Pattern.compile("(^|[^\\\\$])\\$");
private static final Pattern REPLACE_EVERY_OTHER_AT = Pattern.compile("([^@]*)@@([^@]*)@@");
private static final Pattern MOVE_NUMBERS_WITH_OPERATORS = Pattern.compile("([0-9\\(\\.]+[ ]?[-+/]?[ ]?)\\$");
private static final Pattern MOVE_NUMBERS_RIGHT_INTO_EQUATION = Pattern.compile("@@([ ]?[-+/]?[ ]?[0-9\\)\\.]+)");
private static final Pattern ESCAPE_PERCENT_SIGN_ONCE = Pattern.compile("(^|[^\\\\%])%");

@Override
public String getName() {
return Localization.lang("LaTeX cleanup");
Expand All @@ -20,19 +31,25 @@ public String format(String oldString) {
String newValue = oldString;

// Remove redundant $, {, and }, but not if the } is part of a command argument: \mbox{-}{GPS} should not be adjusted
newValue = newValue.replace("$$", "").replaceAll("(?<!\\\\[\\p{Alpha}]{0,100}\\{[^\\}]{0,100})\\}([-/ ]?)\\{",
"$1");
newValue = newValue.replace("$$", "");
newValue = REMOVE_REDUNDANT.matcher(newValue).replaceAll("$1");

// Move numbers, +, -, /, and brackets into equations
newValue = newValue.replaceAll("(([^$]|\\\\\\$)*)\\$", "$1@@"); // Replace $, but not \$ with @@
newValue = newValue.replaceAll("([^@]*)@@([^@]*)@@", "$1\\$$2@@"); // Replace every other @@ with $
newValue = REPLACE_WITH_AT.matcher(newValue).replaceAll("$1@@"); // Replace $, but not \$ with @@

newValue = REPLACE_EVERY_OTHER_AT.matcher(newValue).replaceAll("$1\\$$2@@"); // Replace every other @@ with $
//newValue = newValue.replaceAll("([0-9\\(\\.]+) \\$","\\$$1\\\\ "); // Move numbers followed by a space left of $ inside the equation, e.g., 0.35 $\mu$m
newValue = newValue.replaceAll("([0-9\\(\\.]+[ ]?[-+/]?[ ]?)\\$", "\\$$1"); // Move numbers, possibly with operators +, -, or /, left of $ into the equation
newValue = newValue.replaceAll("@@([ ]?[-+/]?[ ]?[0-9\\)\\.]+)", " $1@@"); // Move numbers right of @@ into the equation

newValue = MOVE_NUMBERS_WITH_OPERATORS.matcher(newValue).replaceAll("\\$$1"); // Move numbers, possibly with operators +, -, or /, left of $ into the equation
newValue = MOVE_NUMBERS_RIGHT_INTO_EQUATION.matcher(newValue).replaceAll(" $1@@"); // Move numbers right of @@ into the equation

newValue = newValue.replace("@@", "$"); // Replace all @@ with $
newValue = newValue.replace(" ", " "); // Clean up
newValue = newValue.replace("$$", "");
newValue = newValue.replace(" )$", ")$");
newValue = newValue.replace("%", "\\%"); // escape % used for comments in TeX

newValue = ESCAPE_PERCENT_SIGN_ONCE.matcher(newValue).replaceAll("$1\\\\%"); // escape %, but do not escapee \% again, used for comments in TeX

return newValue;
}

Expand Down
8 changes: 8 additions & 0 deletions src/main/java/net/sf/jabref/model/groups/GroupTreeNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,12 @@ public int calculateNumberOfMatches(List<BibEntry> entries) {
public int calculateNumberOfMatches(BibDatabase database) {
return calculateNumberOfMatches(database.getEntries());
}

/**
* Returns whether this group matches the specified {@link BibEntry} while taking the hierarchical information
* into account.
*/
public boolean matches(BibEntry entry) {
return getSearchMatcher().isMatch(entry);
}
}
4 changes: 3 additions & 1 deletion src/main/java/net/sf/jabref/pdfimport/PdfImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,9 @@ private void doContentImport(String fileName, List<BibEntry> res) {
Globals.prefs.getBibtexKeyPatternPreferences());
DroppedFileHandler dfh = new DroppedFileHandler(frame, panel);
dfh.linkPdfToEntry(fileName, entry);
panel.highlightEntry(entry);

SwingUtilities.invokeLater(() -> panel.highlightEntry(entry));

if (Globals.prefs.getBoolean(JabRefPreferences.AUTO_OPEN_FORM)) {
EntryEditor editor = panel.getEntryEditor(entry);
panel.showEntryEditor(editor);
Expand Down

This file was deleted.

Loading

0 comments on commit d888684

Please sign in to comment.