Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into customizeEntrydlg
Browse files Browse the repository at this point in the history
# By dependabot-preview[bot] (2) and others
# Via GitHub (1) and github actions (1)
* upstream/master:
  New Crowdin translations (#5864)
  Bump antlr4 from 4.7.2 to 4.8-1 (#5852)
  Reintroducing master table index column (#5844)
  Bump antlr4-runtime from 4.7.2 to 4.8-1 (#5851)
  Improve performance by throttling database change events (#5843)
  Squashed 'src/main/resources/csl-styles/' changes from 9c0f5c6..f0c7374

# Conflicts:
#	src/main/resources/l10n/JabRef_en.properties
  • Loading branch information
Siedlerchr committed Jan 25, 2020
2 parents beec426 + a140fca commit 4dcbf9b
Show file tree
Hide file tree
Showing 32 changed files with 496 additions and 213 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#

### Changed

- We reintroduced the index column. [#5844](https://github.com/JabRef/jabref/pull/5844)

### Fixed

- We fixed an issue where the Medline fetcher was only working when JabRef was running from source. [#5645](https://github.com/JabRef/jabref/issues/5645)
- We fixed some visual issues in the dark theme. [#5764](https://github.com/JabRef/jabref/pull/5764) [#5753](https://github.com/JabRef/jabref/issues/5753)
- We fixed an issue where non-default previews didn't handle unicode characters. [#5779](https://github.com/JabRef/jabref/issues/5779)
- We improved the performance, especially changing field values in the entry should feel smoother now.
- We fixed an issue where the ampersand character wasn't rendering correctly on previews. [#3840](https://github.com/JabRef/jabref/issues/3840)
- We fixed an issue where an erroneous "The library has been modified by another program" message was shown when saving. [#4877](https://github.com/JabRef/jabref/issues/4877)
- We fixed an issue where the file extension was missing after downloading a file (we now fall-back to pdf). [#5816](https://github.com/JabRef/jabref/issues/5816)
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ dependencies {
antlr3 'org.antlr:antlr:3.5.2'
compile 'org.antlr:antlr-runtime:3.5.2'

antlr4 'org.antlr:antlr4:4.7.2'
compile 'org.antlr:antlr4-runtime:4.7.2'
antlr4 'org.antlr:antlr4:4.8-1'
compile 'org.antlr:antlr4-runtime:4.8-1'

compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.5.3'

Expand Down
5 changes: 4 additions & 1 deletion src/main/java/org/jabref/gui/groups/GroupNodeViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.jabref.gui.util.TaskExecutor;
import org.jabref.logic.groups.DefaultGroupsFactory;
import org.jabref.logic.layout.format.LatexToUnicodeFormatter;
import org.jabref.logic.util.DelayTaskThrottler;
import org.jabref.model.FieldChange;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
Expand Down Expand Up @@ -56,6 +57,7 @@ public class GroupNodeViewModel {
private final TaskExecutor taskExecutor;
private final CustomLocalDragboard localDragBoard;
private final ObservableList<BibEntry> entriesList;
private final DelayTaskThrottler throttler;

public GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager stateManager, TaskExecutor taskExecutor, GroupTreeNode groupNode, CustomLocalDragboard localDragBoard) {
this.databaseContext = Objects.requireNonNull(databaseContext);
Expand Down Expand Up @@ -88,6 +90,7 @@ public GroupNodeViewModel(BibDatabaseContext databaseContext, StateManager state
// The wrapper created by the FXCollections will set a weak listener on the wrapped list. This weak listener gets garbage collected. Hence, we need to maintain a reference to this list.
entriesList = databaseContext.getDatabase().getEntries();
entriesList.addListener(this::onDatabaseChanged);
throttler = new DelayTaskThrottler(1000);

ObservableList<Boolean> selectedEntriesMatchStatus = EasyBind.map(stateManager.getSelectedEntries(), groupNode::matches);
anySelectedEntriesMatched = BindingsHelper.any(selectedEntriesMatchStatus, matched -> matched);
Expand Down Expand Up @@ -218,7 +221,7 @@ public GroupTreeNode getGroupNode() {
* Gets invoked if an entry in the current database changes.
*/
private void onDatabaseChanged(ListChangeListener.Change<? extends BibEntry> change) {
calculateNumberOfMatches();
throttler.schedule(this::calculateNumberOfMatches);
}

private void calculateNumberOfMatches() {
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/org/jabref/gui/maintable/MainTableColumnFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import javax.swing.undo.UndoManager;

import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
Expand All @@ -22,6 +23,7 @@
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;

import org.jabref.Globals;
import org.jabref.gui.DialogService;
Expand Down Expand Up @@ -82,6 +84,9 @@ public MainTableColumnFactory(BibDatabaseContext database, ColumnPreferences pre
preferences.getColumns().forEach(column -> {

switch (column.getType()) {
case INDEX:
columns.add(createIndexColumn(column));
break;
case GROUPS:
columns.add(createGroupColumn(column));
break;
Expand Down Expand Up @@ -125,6 +130,24 @@ private void setExactWidth(TableColumn<?, ?> column, double width) {
column.setMaxWidth(width);
}

/**
* Creates a text column to display any standard field.
*/
private TableColumn<BibEntryTableViewModel, String> createIndexColumn(MainTableColumnModel columnModel) {
TableColumn<BibEntryTableViewModel, String> column = new MainTableColumn<>(columnModel);
Node header = new Text("#");
Tooltip.install(header, new Tooltip(MainTableColumnModel.Type.INDEX.getDisplayName()));
column.setGraphic(header);
column.setStyle("-fx-alignment: CENTER-RIGHT;");
column.setCellValueFactory(cellData -> new ReadOnlyObjectWrapper<>(
String.valueOf(cellData.getTableView().getItems().indexOf(cellData.getValue()) + 1)));
new ValueTableCellFactory<BibEntryTableViewModel, String>()
.withText(text -> text)
.install(column);
column.setSortable(false);
return column;
}

/**
* Creates a column for group color bars.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class MainTableColumnModel {
private static final Logger LOGGER = LoggerFactory.getLogger(MainTableColumnModel.class);

public enum Type {
INDEX("index", Localization.lang("Index")),
EXTRAFILE("extrafile", Localization.lang("File type")),
FILES("files", Localization.lang("Linked files")),
GROUPS("groups", Localization.lang("Groups")),
Expand Down Expand Up @@ -132,7 +133,8 @@ public String getName() {
}

public String getDisplayName() {
if (Type.ICON_COLUMNS.contains(typeProperty.getValue()) && qualifierProperty.getValue().isBlank()) {
if ((Type.ICON_COLUMNS.contains(typeProperty.getValue()) && qualifierProperty.getValue().isBlank())
|| typeProperty.getValue() == Type.INDEX) {
return typeProperty.getValue().getDisplayName();
} else {
return FieldsUtil.getNameWithType(FieldFactory.parseField(qualifierProperty.getValue()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public void setValues() {
availableColumnsProperty.clear();

availableColumnsProperty.addAll(
new MainTableColumnModel(MainTableColumnModel.Type.INDEX),
new MainTableColumnModel(MainTableColumnModel.Type.LINKED_IDENTIFIER),
new MainTableColumnModel(MainTableColumnModel.Type.GROUPS),
new MainTableColumnModel(MainTableColumnModel.Type.FILES),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.jabref.logic.util.DelayTaskThrottler;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.database.event.AutosaveEvent;
import org.jabref.model.database.event.BibDatabaseContextChangedEvent;
Expand All @@ -25,40 +23,34 @@
public class AutosaveManager {

private static final Logger LOGGER = LoggerFactory.getLogger(AutosaveManager.class);
private static final int AUTO_SAVE_DELAY = 200;

private static Set<AutosaveManager> runningInstances = new HashSet<>();

private final BibDatabaseContext bibDatabaseContext;
private final ScheduledExecutorService executor;

private final EventBus eventBus;
private final CoarseChangeFilter changeFilter;
private Future<?> scheduledSaveAction;
private final DelayTaskThrottler throttler;

private AutosaveManager(BibDatabaseContext bibDatabaseContext) {
this.bibDatabaseContext = bibDatabaseContext;
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
executor.setRemoveOnCancelPolicy(true); // This prevents memory leaks
this.executor = executor;
this.throttler = new DelayTaskThrottler(2000);
this.eventBus = new EventBus();
this.changeFilter = new CoarseChangeFilter(bibDatabaseContext);
changeFilter.registerListener(this);
}

@Subscribe
public synchronized void listen(@SuppressWarnings("unused") BibDatabaseContextChangedEvent event) {
if (scheduledSaveAction != null) {
scheduledSaveAction.cancel(false);
}
scheduledSaveAction = executor.schedule(() -> {
throttler.schedule(() -> {
eventBus.post(new AutosaveEvent());
}, AUTO_SAVE_DELAY, TimeUnit.MILLISECONDS);
});
}

private void shutdown() {
changeFilter.unregisterListener(this);
changeFilter.shutdown();
executor.shutdown();
throttler.shutdown();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.jabref.logic.bibtex.InvalidFieldValueException;
import org.jabref.logic.exporter.AtomicFileWriter;
import org.jabref.logic.exporter.BibtexDatabaseWriter;
import org.jabref.logic.exporter.SavePreferences;
import org.jabref.logic.util.DelayTaskThrottler;
import org.jabref.logic.util.io.FileUtil;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.database.event.BibDatabaseContextChangedEvent;
Expand Down Expand Up @@ -46,17 +43,15 @@ public class BackupManager {

private final BibDatabaseContext bibDatabaseContext;
private final JabRefPreferences preferences;
private final ExecutorService executor;
private final Runnable backupTask = () -> determineBackupPath().ifPresent(this::performBackup);
private final DelayTaskThrottler throttler;
private final CoarseChangeFilter changeFilter;
private final BibEntryTypesManager entryTypesManager;

private BackupManager(BibDatabaseContext bibDatabaseContext, BibEntryTypesManager entryTypesManager, JabRefPreferences preferences) {
this.bibDatabaseContext = bibDatabaseContext;
this.entryTypesManager = entryTypesManager;
this.preferences = preferences;
BlockingQueue<Runnable> workerQueue = new ArrayBlockingQueue<>(1);
this.executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, workerQueue);
this.throttler = new DelayTaskThrottler(15000);

changeFilter = new CoarseChangeFilter(bibDatabaseContext);
changeFilter.registerListener(this);
Expand All @@ -71,8 +66,6 @@ static Path getBackupPath(Path originalPath) {
* As long as no database file is present in {@link BibDatabaseContext}, the {@link BackupManager} will do nothing.
*
* @param bibDatabaseContext Associated {@link BibDatabaseContext}
* @param entryTypesManager
* @param preferences
*/
public static BackupManager start(BibDatabaseContext bibDatabaseContext, BibEntryTypesManager entryTypesManager, JabRefPreferences preferences) {
BackupManager backupManager = new BackupManager(bibDatabaseContext, entryTypesManager, preferences);
Expand Down Expand Up @@ -151,11 +144,7 @@ public synchronized void listen(@SuppressWarnings("unused") BibDatabaseContextCh
}

private void startBackupTask() {
try {
executor.submit(backupTask);
} catch (RejectedExecutionException e) {
LOGGER.debug("Rejecting while another backup process is already running.");
}
throttler.schedule(() -> determineBackupPath().ifPresent(this::performBackup));
}

/**
Expand All @@ -165,7 +154,7 @@ private void startBackupTask() {
private void shutdown() {
changeFilter.unregisterListener(this);
changeFilter.shutdown();
executor.shutdown();
throttler.shutdown();
determineBackupPath().ifPresent(this::deleteBackupFile);
}

Expand Down
51 changes: 51 additions & 0 deletions src/main/java/org/jabref/logic/util/DelayTaskThrottler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.jabref.logic.util;

import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This class allows to throttle a list of tasks.
* Use case: you have an event that occurs often, and every time you want to invoke the same task.
* However, if a lot of events happen in a relatively short time span, then only one task should be invoked.
*
* @implNote Once {@link #schedule(Runnable)} is called, the task is delayed for a given time span.
* If during this time, {@link #schedule(Runnable)} is called again, then the original task is canceled and the new one scheduled.
*/
public class DelayTaskThrottler {

private static final Logger LOGGER = LoggerFactory.getLogger(DelayTaskThrottler.class);

private final ScheduledThreadPoolExecutor executor;
private final int delay;

private Future<?> scheduledTask;

/**
* @param delay delay in milliseconds
*/
public DelayTaskThrottler(int delay) {
this.delay = delay;
this.executor = new ScheduledThreadPoolExecutor(1);
this.executor.setRemoveOnCancelPolicy(true);
}

public void schedule(Runnable command) {
if (scheduledTask != null) {
scheduledTask.cancel(false);
}
try {
scheduledTask = executor.schedule(command, delay, TimeUnit.MILLISECONDS);
} catch (RejectedExecutionException e) {
LOGGER.debug("Rejecting while another process is already running.");
}
}

public void shutdown() {
executor.shutdown();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
<term name="editor" form="verb-short">ed.</term>
<term name="translator" form="verb-short">tr.</term>
<term name="editortranslator" form="verb-short">ed. and tr.</term>
<!--Ordinals' in superscript-->
<term name="ordinal">ᵗʰ</term>
<term name="ordinal-01">ˢᵗ</term>
<term name="ordinal-02">ⁿᵈ</term>
<term name="ordinal-03">ʳᵈ</term>
<term name="ordinal-11">ᵗʰ</term>
<term name="ordinal-12">ᵗʰ</term>
<term name="ordinal-13">ᵗʰ</term>
</terms>
</locale>
<!--Authors and Persons-->
Expand Down Expand Up @@ -98,7 +106,7 @@
<else-if type="patent">
<text macro="patent"/>
</else-if>
<else>
<else-if type="bill legal_case legislation" match="none">
<names variable="author">
<name delimiter-precedes-last="never" and="text" delimiter=", " initialize="false" initialize-with="" form="short"/>
<substitute>
Expand All @@ -107,7 +115,7 @@
<text macro="title"/>
</substitute>
</names>
</else>
</else-if>
</choose>
</macro>
<macro name="author">
Expand Down Expand Up @@ -200,7 +208,7 @@
<macro name="title-short">
<choose>
<if type="book legislation webpage thesis motion_picture manuscript legal_case" match="any">
<text variable="title-short" font-style="italic" text-case="title"/>
<text variable="title" form="short" font-style="italic" text-case="title"/>
</if>
<else>
<text variable="title" quotes="true" text-case="title" form="short"/>
Expand Down
Loading

0 comments on commit 4dcbf9b

Please sign in to comment.