package org.jabref.gui; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JPanel; import javax.swing.LayoutFocusTraversalPolicy; import javax.swing.text.JTextComponent; import org.jabref.Globals; import org.jabref.gui.actions.Actions; import org.jabref.gui.fieldeditors.FieldEditor; import org.jabref.gui.fieldeditors.TextArea; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.undo.UndoablePreambleChange; import org.jabref.gui.util.WindowLocation; import org.jabref.logic.l10n.Localization; import org.jabref.model.database.BibDatabase; import org.jabref.preferences.JabRefPreferences; class PreambleEditor extends JabRefDialog { // A reference to the entry this object works on. private final BibDatabase database; private final BasePanel panel; private final FieldEditor editor; private final UndoAction undoAction = new UndoAction(); private final StoreFieldAction storeFieldAction = new StoreFieldAction(); private final RedoAction redoAction = new RedoAction(); // The action concerned with closing the window. private final CloseAction closeAction = new CloseAction(); public PreambleEditor(JabRefFrame baseFrame, BasePanel panel, BibDatabase database) { super(baseFrame, PreambleEditor.class); this.panel = panel; this.database = database; addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { closeAction.actionPerformed(null); } @Override public void windowOpened(WindowEvent e) { editor.requestFocus(); } }); setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() { @Override protected boolean accept(Component c) { return super.accept(c) && (c instanceof FieldEditor); } }); JPanel pan = new JPanel(); GridBagLayout gbl = new GridBagLayout(); pan.setLayout(gbl); GridBagConstraints con = new GridBagConstraints(); con.fill = GridBagConstraints.BOTH; con.weighty = 1; con.insets = new Insets(10, 5, 10, 5); editor = new TextArea(Localization.lang("Preamble"), database.getPreamble().orElse("")); // TODO: Reenable this //setupJTextComponent((TextArea) editor); //gbl.setConstraints(editor.getLabel(), con); //pan.add(editor.getLabel()); con.weightx = 1; gbl.setConstraints(editor.getPane(), con); pan.add(editor.getPane()); Container conPane = getContentPane(); conPane.add(pan, BorderLayout.CENTER); setTitle(Localization.lang("Edit preamble")); WindowLocation pw = new WindowLocation(this, JabRefPreferences.PREAMBLE_POS_X, JabRefPreferences.PREAMBLE_POS_Y, JabRefPreferences.PREAMBLE_SIZE_X, JabRefPreferences.PREAMBLE_SIZE_Y); pw.displayWindowAtStoredLocation(); } private void setupJTextComponent(JTextComponent ta) { // Set up key bindings and focus listener for the FieldEditor. ta.getInputMap().put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE_DIALOG), "close"); ta.getActionMap().put("close", closeAction); ta.getInputMap().put(Globals.getKeyPrefs().getKey(KeyBinding.PREAMBLE_EDITOR_STORE_CHANGES), "store"); ta.getActionMap().put("store", storeFieldAction); ta.getInputMap().put(Globals.getKeyPrefs().getKey(KeyBinding.UNDO), "undo"); ta.getActionMap().put(Actions.UNDO, undoAction); ta.getInputMap().put(Globals.getKeyPrefs().getKey(KeyBinding.REDO), "redo"); ta.getActionMap().put(Actions.REDO, redoAction); ta.addFocusListener(new FieldListener()); } public void updatePreamble() { editor.setText(database.getPreamble().orElse("")); } public FieldEditor getFieldEditor() { return editor; } public void storeCurrentEdit() { storeFieldAction.actionPerformed(null); } private class FieldListener extends FocusAdapter { /* * Focus listener that fires the storeFieldAction when a TextArea * loses focus. */ @Override public void focusLost(FocusEvent e) { if (!e.isTemporary()) { storeFieldAction.actionPerformed(new ActionEvent(e.getSource(), 0, "")); } } } class StoreFieldAction extends AbstractAction { public StoreFieldAction() { super("Store field value"); putValue(Action.SHORT_DESCRIPTION, "Store field value"); } @Override public void actionPerformed(ActionEvent e) { String toSet = editor.getText(); // We check if the field has changed, since we don't want to mark the // base as changed unless we have a real change. if (!database.getPreamble().orElse("").equals(toSet)) { panel.getUndoManager().addEdit( new UndoablePreambleChange(database, panel, database.getPreamble().orElse(null), toSet)); database.setPreamble(toSet); //if ((toSet == null) || toSet.isEmpty()) { // editor.setLabelColor(GUIGlobals.NULL_FIELD_COLOR); //} else { // editor.setLabelColor(GUIGlobals.ENTRY_EDITOR_LABEL_COLOR); //} editor.setValidBackgroundColor(); if (editor.hasFocus()) { editor.setActiveBackgroundColor(); } panel.markBaseChanged(); } } } class UndoAction extends AbstractAction { public UndoAction() { super("Undo", IconTheme.JabRefIcon.UNDO.getIcon()); putValue(Action.SHORT_DESCRIPTION, "Undo"); } @Override public void actionPerformed(ActionEvent e) { panel.runCommand(Actions.UNDO); } } class RedoAction extends AbstractAction { public RedoAction() { super("Redo", IconTheme.JabRefIcon.REDO.getIcon()); putValue(Action.SHORT_DESCRIPTION, "Redo"); } @Override public void actionPerformed(ActionEvent e) { panel.runCommand(Actions.REDO); } } class CloseAction extends AbstractAction { public CloseAction() { super(Localization.lang("Close window")); } @Override public void actionPerformed(ActionEvent e) { storeFieldAction.actionPerformed(null); panel.preambleEditorClosing(); dispose(); } } }