Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Split push to applications in logic and gui #4110

Merged
merged 3 commits into from
Jun 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/main/java/org/jabref/gui/preftabs/ExternalTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import org.jabref.gui.JabRefFrame;
import org.jabref.gui.externalfiletype.ExternalFileTypeEditor;
import org.jabref.gui.push.PushToApplication;
import org.jabref.gui.push.PushToApplicationSettings;
import org.jabref.gui.push.PushToApplicationSettingsDialog;
import org.jabref.gui.push.PushToApplications;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.util.OS;
import org.jabref.preferences.JabRefPreferences;
Expand Down Expand Up @@ -196,10 +198,11 @@ public ExternalTab(JabRefFrame frame, PreferencesDialog prefsDiag, JabRefPrefere

}

private void addSettingsButton(final PushToApplication pt, JPanel p) {
JButton button = new JButton(Localization.lang("Settings for %0", pt.getApplicationName()), pt.getIcon().getIcon());
button.addActionListener(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, pt, pt.getSettingsPanel()));
p.add(button);
private void addSettingsButton(final PushToApplication application, JPanel panel) {
PushToApplicationSettings settings = PushToApplications.getSettings(application);
JButton button = new JButton(Localization.lang("Settings for %0", application.getApplicationName()), application.getIcon().getIcon());
button.addActionListener(e -> PushToApplicationSettingsDialog.showSettingsDialog(null, settings));
panel.add(button);
}

@Override
Expand Down
48 changes: 2 additions & 46 deletions src/main/java/org/jabref/gui/push/AbstractPushToApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ public abstract class AbstractPushToApplication implements PushToApplication {
protected boolean couldNotCall; // Set to true in case the command could not be executed, e.g., if the file is not found
protected boolean couldNotConnect; // Set to true in case the tunnel to the program (if one is used) does not operate
protected boolean notDefined; // Set to true if the corresponding path is not defined in the preferences
protected JPanel settings;
protected final JTextField path = new JTextField(30);

protected String commandPath;
protected String commandPathPreferenceKey;
protected FormBuilder builder;

protected DialogService dialogService;

public AbstractPushToApplication(DialogService dialogService) {
Expand Down Expand Up @@ -144,55 +143,12 @@ protected String getCommandName() {
return null;
}

@Override
public JPanel getSettingsPanel() {
initParameters();
commandPath = Globals.prefs.get(commandPathPreferenceKey);
if (settings == null) {
initSettingsPanel();
}
path.setText(commandPath);
return settings;
}

/**
* Function to initialize parameters. Currently it is expected that commandPathPreferenceKey is set to the path of
* the application.
*/
protected abstract void initParameters();

/**
* Create a FormBuilder, fill it with a textbox for the path and store the JPanel in settings
*/
protected void initSettingsPanel() {
builder = FormBuilder.create();
builder.layout(new FormLayout("left:pref, 4dlu, fill:pref:grow, 4dlu, fill:pref", "p"));
StringBuilder label = new StringBuilder(Localization.lang("Path to %0", getApplicationName()));
// In case the application name and the actual command is not the same, add the command in brackets
if (getCommandName() == null) {
label.append(':');
} else {
label.append(" (").append(getCommandName()).append("):");
}
builder.add(label.toString()).xy(1, 1);
builder.add(path).xy(3, 1);
JButton browse = new JButton(Localization.lang("Browse"));

FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
.withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build();

browse.addActionListener(
e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration))
.ifPresent(f -> path.setText(f.toAbsolutePath().toString())));
builder.add(browse).xy(5, 1);
settings = builder.build();
}

@Override
public void storeSettings() {
Globals.prefs.put(commandPathPreferenceKey, path.getText());
}

protected String getCiteCommand() {
return Globals.prefs.get(JabRefPreferences.CITE_COMMAND);
}
Expand Down
17 changes: 0 additions & 17 deletions src/main/java/org/jabref/gui/push/PushToApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,6 @@ public interface PushToApplication {

JabRefIcon getIcon();

/**
* This method asks the implementing class to return a JPanel populated with the imlementation's options panel, if
* necessary. If the JPanel is shown to the user, and the user indicates that settings should be stored, the
* implementation's storeSettings() method will be called. This method must make sure all widgets in the panel are
* in the correct selection states.
*
* @return a JPanel containing options, or null if options are not needed.
*/
JPanel getSettingsPanel();

/**
* This method is called to indicate that the settings panel returned from the getSettingsPanel() method has been
* shown to the user and that the user has indicated that the settings should be stored. This method must store the
* state of the widgets in the settings panel to Globals.prefs.
*/
void storeSettings();

/**
* The actual operation. This method will not be called on the event dispatch thread, so it should not do GUI
* operations without utilizing invokeLater().
Expand Down
149 changes: 0 additions & 149 deletions src/main/java/org/jabref/gui/push/PushToApplicationButton.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,70 +36,16 @@
*/
public class PushToApplicationButton extends SimpleCommand implements ActionListener {

private static final Icon ARROW_ICON = IconTheme.JabRefIcons.DOWN.getSmallIcon();
private final JabRefFrame frame;
private final List<PushToApplication> pushActions;
private JPanel comp;
private JButton pushButton;
private PushToApplication toApp;
private JPopupMenu popup;
private final Map<PushToApplication, PushToApplicationAction> actions = new HashMap<>();
private final Dimension buttonDim = new Dimension(23, 23);
private final JPopupMenu optPopup = new JPopupMenu();
private final JMenuItem settings = new JMenuItem(Localization.lang("Settings"));


public PushToApplicationButton(JabRefFrame frame, List<PushToApplication> pushActions) {
this.frame = frame;
this.pushActions = pushActions;
init();
}

private void init() {
comp = new JPanel();
comp.setLayout(new BorderLayout());

JButton menuButton = new JButton(PushToApplicationButton.ARROW_ICON);
menuButton.setMargin(new Insets(0, 0, 0, 0));
menuButton.setPreferredSize(
new Dimension(menuButton.getIcon().getIconWidth(), menuButton.getIcon().getIconHeight()));
menuButton.addActionListener(e -> {
if (popup == null) {
buildPopupMenu();
}
popup.show(comp, 0, menuButton.getHeight());
});

menuButton.setToolTipText(Localization.lang("Select external application"));

pushButton = new JButton();
if (OS.OS_X) {
menuButton.putClientProperty("JButton.buttonType", "toolbar");
pushButton.putClientProperty("JButton.buttonType", "toolbar");
}

// Set the last used external application
toApp = getLastUsedApplication();

setSelected();
pushButton.addActionListener(this);
pushButton.addMouseListener(new PushButtonMouseListener());
pushButton.setOpaque(false);
menuButton.setOpaque(false);
comp.setOpaque(false);
comp.add(pushButton, BorderLayout.CENTER);
comp.add(menuButton, BorderLayout.EAST);
comp.setMaximumSize(comp.getPreferredSize());

optPopup.add(settings);
settings.addActionListener(event -> {
JPanel options = toApp.getSettingsPanel();
if (options != null) {
PushToApplicationSettingsDialog.showSettingsDialog(null, toApp, options);
}
});

buildPopupMenu();
}

private PushToApplication getLastUsedApplication() {
Expand All @@ -114,47 +60,6 @@ private PushToApplication getLastUsedApplication() {
return pushActions.get(0);
}

/**
* Create a selection menu for the available "Push" options.
*/
private void buildPopupMenu() {
popup = new JPopupMenu();
for (PushToApplication application : pushActions) {
JMenuItem item = new JMenuItem(application.getApplicationName(), application.getIcon().getIcon());
item.setToolTipText(application.getTooltip());
item.addActionListener(new PopupItemActionListener(application));
popup.add(item);
}
}

/**
* Update the PushButton to default to the given application.
*
* @param newApplication the application to default to
*/
private void setSelected(PushToApplication newApplication) {
toApp = newApplication;
setSelected();
}

private void setSelected() {
pushButton.setIcon(toApp.getIcon().getIcon());
pushButton.setToolTipText(toApp.getTooltip());
pushButton.setPreferredSize(buttonDim);

// Store the last used application
Globals.prefs.put(JabRefPreferences.PUSH_TO_APPLICATION, toApp.getApplicationName());
}

/**
* Get the toolbar component for the push button.
*
* @return The component.
*/
public Component getComponent() {
return comp;
}

public org.jabref.gui.actions.Action getMenuAction() {
PushToApplication application = getLastUsedApplication();

Expand Down Expand Up @@ -196,58 +101,4 @@ public void execute() {
}
action.actionPerformed(new ActionEvent(toApp, 0, "push"));
}

class PopupItemActionListener implements ActionListener {

private final PushToApplication application;


public PopupItemActionListener(PushToApplication application) {
this.application = application;
}

@Override
public void actionPerformed(ActionEvent e) {
// Change the selection:
setSelected(application);
// Invoke the selected operation (is that expected behaviour?):
//PushToApplicationButton.this.actionPerformed(null);
// It makes sense to transfer focus to the push button after the
// menu closes:
pushButton.requestFocus();
}
}

class PushButtonMouseListener extends MouseAdapter {

@Override
public void mousePressed(MouseEvent event) {
if (event.isPopupTrigger()) {
processPopupTrigger(event);
}
}

@Override
public void mouseClicked(MouseEvent event) {
if (event.isPopupTrigger()) {
processPopupTrigger(event);
}
}

@Override
public void mouseReleased(MouseEvent event) {
if (event.isPopupTrigger()) {
processPopupTrigger(event);
}
}

private void processPopupTrigger(MouseEvent e) {
// We only want to show the popup if a settings panel exists for the selected
// item:
if (toApp.getSettingsPanel() != null) {
optPopup.show(pushButton, e.getX(), e.getY());
}

}
}
}
77 changes: 77 additions & 0 deletions src/main/java/org/jabref/gui/push/PushToApplicationSettings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.jabref.gui.push;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.jabref.Globals;
import org.jabref.gui.DialogService;
import org.jabref.gui.util.DefaultTaskExecutor;
import org.jabref.gui.util.FileDialogConfiguration;
import org.jabref.logic.l10n.Localization;
import org.jabref.preferences.JabRefPreferences;

import com.jgoodies.forms.builder.FormBuilder;
import com.jgoodies.forms.layout.FormLayout;

public class PushToApplicationSettings {
protected final JTextField path = new JTextField(30);
protected JPanel settings;
protected FormBuilder builder;
protected AbstractPushToApplication application;
private DialogService dialogService;

/**
* This method asks the implementing class to return a JPanel populated with the imlementation's options panel, if
* necessary. If the JPanel is shown to the user, and the user indicates that settings should be stored, the
* implementation's storeSettings() method will be called. This method must make sure all widgets in the panel are
* in the correct selection states.
*
* @return a JPanel containing options, or null if options are not needed.
*/
public JPanel getSettingsPanel() {
application.initParameters();
String commandPath = Globals.prefs.get(application.commandPathPreferenceKey);
if (settings == null) {
initSettingsPanel();
}
path.setText(commandPath);
return settings;
}

/**
* Create a FormBuilder, fill it with a textbox for the path and store the JPanel in settings
*/
protected void initSettingsPanel() {
builder = FormBuilder.create();
builder.layout(new FormLayout("left:pref, 4dlu, fill:pref:grow, 4dlu, fill:pref", "p"));
StringBuilder label = new StringBuilder(Localization.lang("Path to %0", application.getApplicationName()));
// In case the application name and the actual command is not the same, add the command in brackets
if (application.getCommandName() == null) {
label.append(':');
} else {
label.append(" (").append(application.getCommandName()).append("):");
}
builder.add(label.toString()).xy(1, 1);
builder.add(path).xy(3, 1);
JButton browse = new JButton(Localization.lang("Browse"));

FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder()
.withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)).build();

browse.addActionListener(
e -> DefaultTaskExecutor.runInJavaFXThread(() -> dialogService.showFileOpenDialog(fileDialogConfiguration))
.ifPresent(f -> path.setText(f.toAbsolutePath().toString())));
builder.add(browse).xy(5, 1);
settings = builder.build();
}

/**
* This method is called to indicate that the settings panel returned from the getSettingsPanel() method has been
* shown to the user and that the user has indicated that the settings should be stored. This method must store the
* state of the widgets in the settings panel to Globals.prefs.
*/
public void storeSettings() {
Globals.prefs.put(application.commandPathPreferenceKey, path.getText());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
import com.jgoodies.forms.builder.ButtonBarBuilder;

public class PushToApplicationSettingsDialog {
public static void showSettingsDialog(JFrame parent, PushToApplication toApp, JPanel options) {
public static void showSettingsDialog(JFrame parent, PushToApplicationSettings toApp) {
final JDialog diag = new JDialog(parent, Localization.lang("Settings"), true);
JPanel options = toApp.getSettingsPanel();
options.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
diag.getContentPane().add(options, BorderLayout.CENTER);
ButtonBarBuilder bb = new ButtonBarBuilder();
Expand Down
Loading