Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into exportPdf
Browse files Browse the repository at this point in the history
* upstream/master:
  Fix NPE when calling with bib file as cmd argument (#3343)
  update mockito-core from 2.10.0 -> 2.11.0 (#3338)
  Remove underscore in Localized messages (#3336)
  Localisation: French: new entries translated (#3337)
  Refactoring: Lazy init of all editor tabs (#3333)
  • Loading branch information
Siedlerchr committed Oct 25, 2017
2 parents 5e1117a + c928e20 commit 8dabe6d
Show file tree
Hide file tree
Showing 27 changed files with 259 additions and 315 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We improved the way metadata is updated in remote databases. [#3235](https://github.com/JabRef/jabref/issues/3235)
- We improved font rendering of the Entry Editor for Linux based systems [#3295](https://github.com/JabRef/jabref/issues/3295)
- We fixed an issue where JabRef would freeze when trying to replace the original entry after a merge with new information from identifiers like DOI/ISBN etc. [3294](https://github.com/JabRef/jabref/issues/3294)

- We fixed an issue where JabRef would not show the translated content at some points, although there existed a translation
### Removed


Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ dependencies {
compile group: 'com.microsoft.azure', name: 'applicationinsights-logging-log4j2', version: '1.0.9'

testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.10.0'
testCompile 'org.mockito:mockito-core:2.11.0'
testCompile 'com.github.tomakehurst:wiremock:2.8.0'
testCompile 'org.assertj:assertj-swing-junit:3.8.0'
testCompile 'org.reflections:reflections:0.9.11'
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/cli/ArgumentProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ private void regenerateBibtexKeys(List<ParserResult> loaded) {
database, entry, Globals.prefs.getBibtexKeyPatternPreferences());
}
} else {
LOGGER.info(Localization.lang("No meta data present in BIB_file. Cannot regenerate BibTeX keys"));
LOGGER.info(Localization.lang("No meta data present in BIB file. Cannot regenerate BibTeX keys"));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/EntryTypeDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ protected void done() {
} else if (searchID.trim().isEmpty()) {
JOptionPane.showMessageDialog(frame, Localization.lang("The given search ID was empty."), Localization.lang("Empty search ID"), JOptionPane.WARNING_MESSAGE);
} else if (!fetcherException) {
JOptionPane.showMessageDialog(frame, Localization.lang("Fetcher_'%0'_did_not_find_an_entry_for_id_'%1'.", fetcher.getName(), searchID) + "\n" + fetcherExceptionMessage, Localization.lang("No files found."), JOptionPane.WARNING_MESSAGE);
JOptionPane.showMessageDialog(frame, Localization.lang("Fetcher '%0' did not find an entry for id '%1'.", fetcher.getName(), searchID) + "\n" + fetcherExceptionMessage, Localization.lang("No files found."), JOptionPane.WARNING_MESSAGE);
} else {
JOptionPane.showMessageDialog(frame,
Localization.lang("Error while fetching from %0", fetcher.getName()) + "." + "\n" + fetcherExceptionMessage,
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/desktop/JabRefDesktop.java
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public static void openBrowserShowPopup(String url) {
LOGGER.error("Could not open browser", exception);
String couldNotOpenBrowser = Localization.lang("Could not open browser.");
String openManually = Localization.lang("Please open %0 manually.", url);
String copiedToClipboard = Localization.lang("The_link_has_been_copied_to_the_clipboard.");
String copiedToClipboard = Localization.lang("The link has been copied to the clipboard.");
JabRefGUI.getMainFrame().output(couldNotOpenBrowser);
JOptionPane.showMessageDialog(JabRefGUI.getMainFrame(), couldNotOpenBrowser + "\n" + openManually + "\n" +
copiedToClipboard, couldNotOpenBrowser, JOptionPane.ERROR_MESSAGE);
Expand Down
15 changes: 11 additions & 4 deletions src/main/java/org/jabref/gui/entryeditor/DeprecatedFieldsTab.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
package org.jabref.gui.entryeditor;

import java.util.List;

import javafx.scene.control.Tooltip;

import org.jabref.gui.BasePanel;
import org.jabref.gui.IconTheme;
import org.jabref.gui.JabRefFrame;
import org.jabref.gui.autocompleter.SuggestionProviders;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.EntryType;

public class DeprecatedFieldsTab extends FieldsEditorTab {
public DeprecatedFieldsTab(JabRefFrame frame, BasePanel basePanel, EntryType entryType, EntryEditor parent, BibEntry entry) {
super(frame, basePanel, entryType.getDeprecatedFields(), parent, false, false, entry);
public DeprecatedFieldsTab(BibDatabaseContext databaseContext, SuggestionProviders suggestionProviders) {
super(false, databaseContext, suggestionProviders);

setText(Localization.lang("Deprecated fields"));
setTooltip(new Tooltip(Localization.lang("Show deprecated BibTeX fields")));
setGraphic(IconTheme.JabRefIcon.OPTIONAL.getGraphicNode());
}

@Override
protected List<String> determineFieldsToShow(BibEntry entry, EntryType entryType) {
return entryType.getDeprecatedFields();
}
}
168 changes: 66 additions & 102 deletions src/main/java/org/jabref/gui/entryeditor/EntryEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -106,11 +107,6 @@ public class EntryEditor extends JPanel implements EntryContainer {

private static final Log LOGGER = LogFactory.getLog(EntryEditor.class);

/**
* The default index number of the other fields tab
*/
private static final int OTHER_FIELDS_DEFAULTPOSITION = 4;

/**
* A reference to the entry this object works on.
*/
Expand Down Expand Up @@ -152,14 +148,14 @@ public class EntryEditor extends JPanel implements EntryContainer {
private final RedoAction redoAction = new RedoAction();
private final List<SearchQueryHighlightListener> searchListeners = new ArrayList<>();
private final JFXPanel container;
private final List<EntryEditorTab> tabs;

/**
* Indicates that we are about to go to the next or previous entry
*/
private final BooleanProperty movingToDifferentEntry = new SimpleBooleanProperty();
private EntryType entryType;
private SourceTab sourceTab;
private final BorderLayout layout;
private TypeLabel typeLabel;

public EntryEditor(BasePanel panel) {
Expand All @@ -168,28 +164,34 @@ public EntryEditor(BasePanel panel) {

writeXmp = new WriteXMPEntryEditorAction(panel, this);

layout = new BorderLayout();
BorderLayout layout = new BorderLayout();
setLayout(layout);

container = OS.LINUX ? new CustomJFXPanel() : new JFXPanel();
// Create type-label
typeLabel = new TypeLabel("");
setupToolBar();
DefaultTaskExecutor.runInJavaFXThread(() ->
container.setScene(new Scene(tabbed))
);
DefaultTaskExecutor.runInJavaFXThread(() -> {
tabbed.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
tabbed.setStyle(
"-fx-font-size: " + Globals.prefs.getFontSizeFX() + "pt;" +
"-fx-open-tab-animation: NONE; -fx-close-tab-animation: NONE;");
container.setScene(new Scene(tabbed));
});
add(container, BorderLayout.CENTER);

DefaultTaskExecutor.runInJavaFXThread(() -> {
EasyBind.subscribe(tabbed.getSelectionModel().selectedItemProperty(), tab -> {
EntryEditorTab activeTab = (EntryEditorTab) tab;
if (activeTab != null) {
activeTab.notifyAboutFocus();
activeTab.notifyAboutFocus(entry);
}
});
});

setupKeyBindings();

tabs = createTabs();
}

public void setEntry(BibEntry entry) {
Expand All @@ -201,73 +203,29 @@ public void setEntry(BibEntry entry) {
displayedBibEntryType = entry.getType();

DefaultTaskExecutor.runInJavaFXThread(() -> {
addTabs(this.getVisibleTabName());

tabbed.setStyle("-fx-font-size: " + Globals.prefs.getFontSizeFX() + "pt;");
recalculateVisibleTabs();
if (Globals.prefs.getBoolean(JabRefPreferences.DEFAULT_SHOW_SOURCE)) {
tabbed.getSelectionModel().select(sourceTab);
}

// Notify current tab about new entry
EntryEditorTab selectedTab = (EntryEditorTab) tabbed.getSelectionModel().getSelectedItem();
selectedTab.notifyAboutFocus(entry);
});

TypedBibEntry typedEntry = new TypedBibEntry(entry, panel.getBibDatabaseContext().getMode());
typeLabel.setText(typedEntry.getTypeForDisplay());
}

@Subscribe
public synchronized void listen(FieldAddedOrRemovedEvent event) {
// other field deleted -> update other fields tab
if (OtherFieldsTab.isOtherField(entryType, event.getFieldName())) {
DefaultTaskExecutor.runInJavaFXThread(() -> rebuildOtherFieldsTab());
}
// Rebuild entry editor based on new information (e.g. hide/add tabs)
recalculateVisibleTabs();
}

@Subscribe
public synchronized void listen(EntryChangedEvent event) {
DefaultTaskExecutor.runInJavaFXThread(() -> sourceTab.updateSourcePane());
}

private void rebuildOtherFieldsTab() {
int index = -1;
boolean isOtherFieldsTabSelected = false;

// find tab index and selection status
for (Tab tab : tabbed.getTabs()) {
if (tab instanceof OtherFieldsTab) {
index = tabbed.getTabs().indexOf(tab);
isOtherFieldsTabSelected = tabbed.getSelectionModel().isSelected(index);
break;
}
}

// rebuild tab at index and with prior selection status
if (index != -1) {
readdOtherFieldsTab(index, isOtherFieldsTabSelected);
} else {
// maybe the tab wasn't there but needs to be now
addNewOtherFieldsTabIfNeeded();
}
}

private void readdOtherFieldsTab(int index, boolean isOtherFieldsTabSelected) {
tabbed.getTabs().remove(index);
OtherFieldsTab tab = new OtherFieldsTab(frame, panel, entryType, this, entry);
// if there are no other fields left, no need to readd the tab
if (!(tab.getFields().size() == 0)) {
tabbed.getTabs().add(index, tab);
}
// select the new tab if it was selected before
if (isOtherFieldsTabSelected) {
tabbed.getSelectionModel().select(tab);
}
}

private void addNewOtherFieldsTabIfNeeded() {
OtherFieldsTab tab = new OtherFieldsTab(frame, panel, entryType, this, entry);
if (tab.getFields().size() > 0) {
// add it at default index, but that is just a guess
tabbed.getTabs().add(OTHER_FIELDS_DEFAULTPOSITION, tab);
}
}

private void selectLastUsedTab(String lastTabName) {
tabbed.getTabs().stream().filter(tab -> lastTabName.equals(tab.getText())).findFirst().ifPresent(tab -> tabbed.getSelectionModel().select(tab));
DefaultTaskExecutor.runInJavaFXThread(() -> sourceTab.updateSourcePane(entry));
}

/**
Expand Down Expand Up @@ -335,53 +293,62 @@ public void close() {
closeAction.actionPerformed(null);
}

private void addTabs(String lastTabName) {
private void recalculateVisibleTabs() {
List<Tab> visibleTabs = tabs.stream().filter(tab -> tab.shouldShow(entry)).collect(Collectors.toList());

List<EntryEditorTab> tabs = new ArrayList<>();
// Start of ugly hack:
// We need to find out, which tabs will be shown and which not and remove and re-add the appropriate tabs
// to the editor. We don't want to simply remove all and re-add the complete list of visible tabs, because
// the tabs give an ugly animation the looks like all tabs are shifting in from the right.
// This hack is required since tabbed.getTabs().setAll(visibleTabs) changes the order of the tabs in the editor

// First, remove tabs that we do not want to show
List<EntryEditorTab> toBeRemoved = tabs.stream().filter(tab -> !tab.shouldShow(entry)).collect(Collectors.toList());
tabbed.getTabs().removeAll(toBeRemoved);

// Next add all the visible tabs (if not already present) at the right position
for (int i = 0; i < visibleTabs.size(); i++) {
Tab toBeAdded = visibleTabs.get(i);
Tab shown = null;
if (i < tabbed.getTabs().size()) {
shown = tabbed.getTabs().get(i);
}

if (!toBeAdded.equals(shown)) {
tabbed.getTabs().add(i, toBeAdded);
}
}
}

private List<EntryEditorTab> createTabs() {
List<EntryEditorTab> tabs = new LinkedList<>();

// Required fields
tabs.add(new RequiredFieldsTab(frame, panel, entryType, this, entry));
tabs.add(new RequiredFieldsTab(panel.getDatabaseContext(), panel.getSuggestionProviders()));

// Optional fields
tabs.add(new OptionalFieldsTab(frame, panel, entryType, this, entry));
tabs.add(new OptionalFields2Tab(frame, panel, entryType, this, entry));
tabs.add(new DeprecatedFieldsTab(frame, panel, entryType, this, entry));
tabs.add(new OptionalFieldsTab(panel.getDatabaseContext(), panel.getSuggestionProviders()));
tabs.add(new OptionalFields2Tab(panel.getDatabaseContext(), panel.getSuggestionProviders()));
tabs.add(new DeprecatedFieldsTab(panel.getDatabaseContext(), panel.getSuggestionProviders()));

// Other fields
tabs.add(new OtherFieldsTab(frame, panel, entryType, this, entry));
tabs.add(new OtherFieldsTab(panel.getDatabaseContext(), panel.getSuggestionProviders()));

// General fields from preferences
EntryEditorTabList tabList = Globals.prefs.getEntryEditorTabList();
for (int i = 0; i < tabList.getTabCount(); i++) {
FieldsEditorTab newFieldsEditorTab = new FieldsEditorTab(frame, panel, tabList.getTabFields(i), this, false,
false, entry);
newFieldsEditorTab.setText(tabList.getTabName(i));
tabs.add(newFieldsEditorTab);
tabs.add(new UserDefinedFieldsTab(tabList.getTabName(i), tabList.getTabFields(i), panel.getDatabaseContext(), panel.getSuggestionProviders()));
}

// Special tabs
tabs.add(new MathSciNetTab(entry));
tabs.add(new FileAnnotationTab(panel.getAnnotationCache(), entry));
tabs.add(new RelatedArticlesTab(entry));
tabs.add(new MathSciNetTab());
tabs.add(new FileAnnotationTab(panel.getAnnotationCache()));
tabs.add(new RelatedArticlesTab(Globals.prefs));

// Source tab
sourceTab = new SourceTab(panel, entry, movingToDifferentEntry);
sourceTab = new SourceTab(panel, movingToDifferentEntry);
tabs.add(sourceTab);

tabbed.getTabs().clear();
for (EntryEditorTab tab : tabs) {
if (tab.shouldShow()) {
tabbed.getTabs().add(tab);
}
}
tabbed.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);

if (Globals.prefs.getBoolean(JabRefPreferences.DEFAULT_SHOW_SOURCE)) {
tabbed.getSelectionModel().select(sourceTab);
} else {
selectLastUsedTab(lastTabName);
}

return tabs;
}

public String getDisplayedBibEntryType() {
Expand Down Expand Up @@ -539,11 +506,10 @@ public void setVisibleTab(String name) {

public void setFocusToField(String fieldName) {
for (Tab tab : tabbed.getTabs()) {
if ((tab instanceof FieldsEditorTab) && ((FieldsEditorTab) tab).getFields().contains(fieldName)) {
if ((tab instanceof FieldsEditorTab) && ((FieldsEditorTab) tab).determineFieldsToShow(entry, entryType).contains(fieldName)) {
FieldsEditorTab fieldsEditorTab = (FieldsEditorTab) tab;
tabbed.getSelectionModel().select(tab);
fieldsEditorTab.setActive(fieldName);
fieldsEditorTab.focus();
fieldsEditorTab.requestFocus(fieldName);
}
}
}
Expand Down Expand Up @@ -808,9 +774,7 @@ public void actionPerformed(ActionEvent event) {
// Should only be done if this editor is currently showing:
// don't select the current entry again (eg use BasePanel#highlightEntry} in case another entry was selected)
if (!movingAway && isShowing()) {
SwingUtilities.invokeLater(() -> {
panel.getMainTable().ensureVisible(entry);
});
SwingUtilities.invokeLater(() -> panel.getMainTable().ensureVisible(entry));
}
}

Expand Down
Loading

0 comments on commit 8dabe6d

Please sign in to comment.