Skip to content

Commit

Permalink
Merge pull request #3427 from JabRef/javafxEditorToolbar
Browse files Browse the repository at this point in the history
Rework entry editor toolbar in JavaFX
  • Loading branch information
tobiasdiez committed Dec 28, 2017
2 parents 64c774b + 6a61a12 commit 1172ed4
Show file tree
Hide file tree
Showing 60 changed files with 826 additions and 1,449 deletions.
171 changes: 73 additions & 98 deletions src/main/java/org/jabref/gui/BasePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ public class BasePanel extends JPanel implements ClipboardOwner {
// To contain instantiated entry editors. This is to save time
// As most enums, this must not be null
private BasePanelMode mode = BasePanelMode.SHOWING_NOTHING;
private EntryEditor currentEditor;
private final EntryEditor entryEditor;
private final JFXPanel entryEditorContainer;
private MainTableSelectionListener selectionListener;
private JSplitPane splitPane;
private boolean saving;
Expand Down Expand Up @@ -245,11 +246,41 @@ public BasePanel(JabRefFrame frame, BibDatabaseContext bibDatabaseContext) {

this.getDatabase().registerListener(new UpdateTimestampListener(Globals.prefs));

entryEditor = new EntryEditor(this);
entryEditorContainer = setupEntryEditor(entryEditor);

this.preview = new PreviewPanel(this, getBibDatabaseContext());
DefaultTaskExecutor.runInJavaFXThread(() -> frame().getGlobalSearchBar().getSearchQueryHighlightObservable().addSearchListener(preview));
this.previewContainer = CustomJFXPanel.wrap(new Scene(preview));
}

private static JFXPanel setupEntryEditor(EntryEditor entryEditor) {
JFXPanel container = CustomJFXPanel.wrap(new Scene(entryEditor));
container.addKeyListener(new KeyAdapter() {

@Override
public void keyPressed(KeyEvent e) {

//We need to consume this event here to prevent the propgation of keybinding events back to the JFrame
Optional<KeyBinding> keyBinding = Globals.getKeyPrefs().mapToKeyBinding(e);
if (keyBinding.isPresent()) {
switch (keyBinding.get()) {
case CUT:
case COPY:
case PASTE:
case DELETE_ENTRY:
case SELECT_ALL:
e.consume();
break;
default:
//do nothing
}
}
}
});
return container;
}

public static void runWorker(AbstractWorker worker) throws Exception {
// This part uses Spin's features:
Runnable wrk = worker.getWorker();
Expand Down Expand Up @@ -775,7 +806,16 @@ private void cut() {
* "deleted". If true the action will be localized as "cut"
*/
private void delete(boolean cut) {
List<BibEntry> entries = mainTable.getSelectedEntries();
delete(cut, mainTable.getSelectedEntries());
}

/**
* Removes the selected entries from the database
*
* @param cut If false the user will get asked if he really wants to delete the entries, and it will be localized as
* "deleted". If true the action will be localized as "cut"
*/
private void delete(boolean cut, List<BibEntry> entries) {
if (entries.isEmpty()) {
return;
}
Expand Down Expand Up @@ -814,6 +854,10 @@ private void delete(boolean cut) {
mainTable.requestFocus();
}

public void delete(BibEntry entry) {
delete(false, Collections.singletonList(entry));
}

private void paste() {
Collection<BibEntry> bes = new ClipBoardManager().extractBibEntriesFromClipboard();

Expand Down Expand Up @@ -1076,7 +1120,7 @@ private boolean saveDatabase(File file, boolean selectedOnly, Charset enc,
if (ex.specificEntry()) {
// Error occurred during processing of the entry. Highlight it:
highlightEntry(ex.getEntry());
showEntry(ex.getEntry());
showAndEdit(ex.getEntry());
} else {
LOGGER.warn("Could not save", ex);
}
Expand Down Expand Up @@ -1182,9 +1226,7 @@ public BibEntry newEntry(EntryType type) {
// The database just changed.
markBaseChanged();

final EntryEditor entryEditor = getEntryEditor(be);
this.showEntryEditor(entryEditor);
entryEditor.requestFocus();
this.showAndEdit(be);

return be;
} catch (KeyCollisionException ex) {
Expand Down Expand Up @@ -1223,14 +1265,11 @@ public void insertEntry(final BibEntry bibEntry) {
}

public void editEntryByIdAndFocusField(final String entryId, final String fieldName) {
final Optional<BibEntry> entry = bibDatabaseContext.getDatabase().getEntryById(entryId);
entry.ifPresent(e -> {
mainTable.setSelected(mainTable.findEntry(e));
bibDatabaseContext.getDatabase().getEntryById(entryId).ifPresent(entry -> {
mainTable.setSelected(mainTable.findEntry(entry));
selectionListener.editSignalled();
final EntryEditor editor = getEntryEditor(e);
editor.setFocusToField(fieldName);
this.showEntryEditor(editor);
editor.requestFocus();
showAndEdit(entry);
entryEditor.setFocusToField(fieldName);
});
}

Expand Down Expand Up @@ -1273,7 +1312,7 @@ public void actionPerformed(ActionEvent e) {
break;
case SHOWING_EDITOR:
case WILL_SHOW_EDITOR:
entryEditorClosing(getCurrentEditor());
entryEditorClosing(getEntryEditor());
break;
default:
LOGGER.warn("unknown BasePanelMode: '" + mode + "', doing nothing");
Expand Down Expand Up @@ -1454,81 +1493,29 @@ public void adjustSplitter() {
}
}

private boolean isShowingEditor() {
return (splitPane.getBottomComponent() != null) && (splitPane.getBottomComponent() instanceof EntryEditor);
}

public void showEntry(final BibEntry bibEntry) {

if (getShowing() == bibEntry) {
if (splitPane.getBottomComponent() == null) {
// This is the special occasion when showing is set to an
// entry, but no entry editor is in fact shown. This happens
// after Preferences dialog is closed, and it means that we
// must make sure the same entry is shown again. We do this by
// setting showing to null, and recursively calling this method.
newEntryShowing(null);
showEntry(bibEntry);
}
return;
}

String visName = null;
if ((getShowing() != null) && isShowingEditor()) {
visName = ((EntryEditor) splitPane.getBottomComponent()).getVisibleTabName();
}

// We must instantiate a new editor.
EntryEditor entryEditor = getEntryEditor(bibEntry);
if (visName != null) {
entryEditor.setVisibleTab(visName);
}
showEntryEditor(entryEditor);

newEntryShowing(bibEntry);
}

/**
* Get an entry editor ready to edit the given entry.
*
* @param entry The entry to be edited.
* @return A suitable entry editor.
*/
public EntryEditor getEntryEditor(BibEntry entry) {
if (currentEditor != null) {
currentEditor.setEntry(entry);
return currentEditor;
} else {
EntryEditor editor = new EntryEditor(this);
editor.setEntry(entry);
return editor;
}
}

public EntryEditor getCurrentEditor() {
return currentEditor;
public EntryEditor getEntryEditor() {
return entryEditor;
}

/**
* Sets the given entry editor as the bottom component in the split pane. If an entry editor already was shown,
* Sets the entry editor as the bottom component in the split pane. If an entry editor already was shown,
* makes sure that the divider doesn't move. Updates the mode to SHOWING_EDITOR.
* Then shows the given entry.
*
* @param editor The entry editor to add.
* @param entry The entry to edit.
*/
public void showEntryEditor(EntryEditor editor) {
public void showAndEdit(BibEntry entry) {
if (mode == BasePanelMode.SHOWING_EDITOR) {
Globals.prefs.putInt(JabRefPreferences.ENTRY_EDITOR_HEIGHT,
splitPane.getHeight() - splitPane.getDividerLocation());
Globals.prefs.putInt(JabRefPreferences.ENTRY_EDITOR_HEIGHT, splitPane.getHeight() - splitPane.getDividerLocation());
}
mode = BasePanelMode.SHOWING_EDITOR;
if (currentEditor != null) {
currentEditor.setMovingToDifferentEntry();
}
currentEditor = editor;
splitPane.setBottomComponent(editor);
if (editor.getEntry() != getShowing()) {
newEntryShowing(editor.getEntry());
splitPane.setBottomComponent(entryEditorContainer);

if (entry != getShowing()) {
entryEditor.setEntry(entry);
newEntryShowing(entry);
}
entryEditor.requestFocus();
adjustSplitter();
}

Expand Down Expand Up @@ -1628,20 +1615,17 @@ public void entryEditorClosing(EntryEditor editor) {
* Closes the entry editor or preview panel if it is showing the given entry.
*/
public void ensureNotShowingBottomPanel(BibEntry entry) {
if (((mode == BasePanelMode.SHOWING_EDITOR) && (currentEditor.getEntry() == entry))
if (((mode == BasePanelMode.SHOWING_EDITOR) && (entryEditor.getEntry() == entry))
|| ((mode == BasePanelMode.SHOWING_PREVIEW) && (selectionListener.getPreview().getEntry() == entry))) {
hideBottomComponent();
}
}

public void updateEntryEditorIfShowing() {
if (mode == BasePanelMode.SHOWING_EDITOR) {
if (!currentEditor.getDisplayedBibEntryType().equals(currentEditor.getEntry().getType())) {
// The entry has changed type, so we must get a new editor.
newEntryShowing(null);
final EntryEditor newEditor = getEntryEditor(currentEditor.getEntry());
showEntryEditor(newEditor);
}
BibEntry currentEntry = entryEditor.getEntry();
showAndEdit(null);
showAndEdit(currentEntry);
}
}

Expand Down Expand Up @@ -1813,15 +1797,6 @@ public void lostOwnership(Clipboard clipboard, Transferable contents) {
// Nothing
}

private void setEntryEditorEnabled(boolean enabled) {
if ((getShowing() != null) && (splitPane.getBottomComponent() instanceof EntryEditor)) {
EntryEditor ed = (EntryEditor) splitPane.getBottomComponent();
if (ed.isEnabled() != enabled) {
ed.setEnabled(enabled);
}
}
}

/**
* Perform necessary cleanup when this BasePanel is closed.
*/
Expand Down Expand Up @@ -1890,7 +1865,7 @@ private BibEntry getShowing() {
*
* @param entry The entry that is now to be shown.
*/
public void newEntryShowing(BibEntry entry) {
private void newEntryShowing(BibEntry entry) {

// If this call is the result of a Back or Forward operation, we must take
// care not to make any history changes, since the necessary changes will
Expand Down Expand Up @@ -2085,8 +2060,8 @@ private class EntryRemovedListener {
@Subscribe
public void listen(EntryRemovedEvent entryRemovedEvent) {
// if the entry that is displayed in the current entry editor is removed, close the entry editor
if (isShowingEditor() && currentEditor.getEntry().equals(entryRemovedEvent.getBibEntry())) {
currentEditor.close();
if (mode == BasePanelMode.SHOWING_EDITOR && entryEditor.getEntry().equals(entryRemovedEvent.getBibEntry())) {
entryEditor.close();
}

BibEntry previewEntry = selectionListener.getPreview().getEntry();
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/org/jabref/gui/Main.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
*/
-fx-dark-background: #757575;

/*
* A strong white as background
*/
-fx-light-background: #ffffff;

/*
* A strong blue for backgrounds of active items (toggle button, selected list item)
*/
Expand Down Expand Up @@ -85,6 +90,8 @@
-fx-font-family: monospace;
}

.flatButtonNoSpaceBottom,
.flatButtonNoSpaceTop,
.flatButton {
-fx-shadow-highlight-color: transparent;
-fx-outer-border: transparent;
Expand All @@ -101,3 +108,11 @@
-fx-text-fill: white;
-fx-fill: white;
}

.flatButtonNoSpaceBottom {
-fx-padding: 0.5em 0.5em -0.1em 0.5em;
}

.flatButtonNoSpaceTop {
-fx-padding: -0.1em 0.5em 0.5em 0.5em;
}
27 changes: 27 additions & 0 deletions src/main/java/org/jabref/gui/actions/ChangeTypeAction.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package org.jabref.gui.actions;

import java.awt.event.ActionEvent;
import java.util.Collections;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.undo.UndoManager;

import javafx.scene.control.MenuItem;

import org.jabref.gui.BasePanel;
import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.undo.UndoableChangeType;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.EntryType;

public class ChangeTypeAction extends AbstractAction {
Expand All @@ -22,4 +31,22 @@ public ChangeTypeAction(EntryType type, BasePanel bp) {
public void actionPerformed(ActionEvent evt) {
panel.changeTypeOfSelectedEntries(type);
}

public static MenuItem as(EntryType type, BibEntry entry, UndoManager undoManager) {
return as(type, Collections.singletonList(entry), undoManager);
}

public static MenuItem as(EntryType type, List<BibEntry> entries, UndoManager undoManager) {
MenuItem menuItem = new MenuItem(type.getName());
menuItem.setOnAction(event -> {
NamedCompound compound = new NamedCompound(Localization.lang("Change entry type"));
for (BibEntry entry : entries) {
entry.setType(type)
.ifPresent(change -> compound.addEdit(new UndoableChangeType(change)));
}

undoManager.addEdit(compound);
});
return menuItem;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.jabref.logic.integrity.IntegrityCheck;
import org.jabref.logic.integrity.IntegrityMessage;
import org.jabref.logic.l10n.Localization;
import org.jabref.preferences.JabRefPreferences;

import com.jgoodies.forms.builder.FormBuilder;
import com.jgoodies.forms.layout.FormLayout;
Expand All @@ -53,8 +54,8 @@ public void actionPerformed(ActionEvent e) {
IntegrityCheck check = new IntegrityCheck(frame.getCurrentBasePanel().getBibDatabaseContext(),
Globals.prefs.getFileDirectoryPreferences(),
Globals.prefs.getBibtexKeyPatternPreferences(),
Globals.journalAbbreviationLoader
.getRepository(Globals.prefs.getJournalAbbreviationPreferences()));
Globals.journalAbbreviationLoader.getRepository(Globals.prefs.getJournalAbbreviationPreferences()),
Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY));

final JDialog integrityDialog = new JDialog(frame, true);
integrityDialog.setUndecorated(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.Collection;

import javax.swing.undo.UndoManager;

import javafx.scene.control.Tooltip;

import org.jabref.gui.IconTheme;
Expand All @@ -12,8 +14,8 @@
import org.jabref.model.entry.EntryType;

public class DeprecatedFieldsTab extends FieldsEditorTab {
public DeprecatedFieldsTab(BibDatabaseContext databaseContext, SuggestionProviders suggestionProviders) {
super(false, databaseContext, suggestionProviders);
public DeprecatedFieldsTab(BibDatabaseContext databaseContext, SuggestionProviders suggestionProviders, UndoManager undoManager) {
super(false, databaseContext, suggestionProviders, undoManager);

setText(Localization.lang("Deprecated fields"));
setTooltip(new Tooltip(Localization.lang("Show deprecated BibTeX fields")));
Expand Down
Loading

0 comments on commit 1172ed4

Please sign in to comment.