Coverage Report - net.sf.jabref.external.PushToApplicationButton
 
Classes in this File Line Coverage Branch Coverage Complexity
PushToApplicationButton
97%
105/108
68%
11/16
1.583
PushToApplicationButton$1
16%
1/6
0%
0/2
1.583
PushToApplicationButton$2
100%
4/4
N/A
1.583
PushToApplicationButton$3
100%
3/3
N/A
1.583
PushToApplicationButton$4
33%
1/3
N/A
1.583
PushToApplicationButton$BooleanHolder
100%
3/3
N/A
1.583
PushToApplicationButton$MenuAction
100%
7/7
N/A
1.583
PushToApplicationButton$MenuButtonActionListener
80%
4/5
50%
1/2
1.583
PushToApplicationButton$PopupItemActionListener
100%
6/6
N/A
1.583
PushToApplicationButton$PushButtonMouseListener
7%
1/14
0%
0/8
1.583
PushToApplicationButton$PushToApplicationComparator
0%
0/2
N/A
1.583
 
 1  
 package net.sf.jabref.external;
 2  
 
 3  
 import com.jgoodies.forms.builder.ButtonBarBuilder;
 4  
 import net.sf.jabref.GUIGlobals;
 5  
 import net.sf.jabref.Globals;
 6  
 import net.sf.jabref.JabRefFrame;
 7  
 import net.sf.jabref.MnemonicAwareAction;
 8  
 import net.sf.jabref.plugin.PluginCore;
 9  
 import net.sf.jabref.plugin.core.JabRefPlugin;
 10  
 import net.sf.jabref.plugin.core.generated._JabRefPlugin;
 11  
 
 12  
 import javax.swing.*;
 13  
 import java.awt.*;
 14  
 import java.awt.event.ActionEvent;
 15  
 import java.awt.event.ActionListener;
 16  
 import java.awt.event.MouseAdapter;
 17  
 import java.awt.event.MouseEvent;
 18  
 import java.net.URL;
 19  
 import java.util.ArrayList;
 20  
 import java.util.Comparator;
 21  
 import java.util.HashMap;
 22  
 import java.util.List;
 23  
 
 24  
 /**
 25  
  * Customized UI component for pushing to external applications. Has a selection popup
 26  
  * menu to change the selected external application.
 27  
  * This class implements the ActionListener interface. When actionPerformed() is
 28  
  * invoked, the currently selected PushToApplication is activated. The actionPerformed()
 29  
  * method can be called with a null argument.
 30  
  */
 31  568974
 public class PushToApplicationButton implements ActionListener {
 32  
 
 33  
     public static List<PushToApplication> applications;
 34  
 
 35  
     private JabRefFrame frame;
 36  
     private List<PushToApplication> pushActions;
 37  
     private JPanel comp;
 38  
     private JButton pushButton, menuButton;
 39  140886441
     private int selected = 0;
 40  140886441
     private JPopupMenu popup = null;
 41  140886441
     private HashMap<PushToApplication, PushToApplicationAction> actions = new HashMap<PushToApplication, PushToApplicationAction>();
 42  140886441
     private final Dimension buttonDim = new Dimension(23, 23);
 43  140886441
     private static final URL ARROW_ICON = GUIGlobals.class.getResource("/images/secondary_sorted_reverse.png");
 44  140886441
     private MenuAction mAction = new MenuAction();
 45  140886441
     private JPopupMenu optPopup = new JPopupMenu();
 46  140886441
     private JMenuItem settings = new JMenuItem(Globals.lang("Settings"));
 47  
 
 48  
     /**
 49  
      * Set up the current available choices:
 50  
      */
 51  
     static {
 52  
 
 53  140886441
         applications = new ArrayList<PushToApplication>();
 54  
 
 55  140886441
         JabRefPlugin jabrefPlugin = JabRefPlugin.getInstance(PluginCore.getManager());
 56  140886441
         List<_JabRefPlugin.PushToApplicationExtension> plugins = jabrefPlugin.getPushToApplicationExtensions();
 57  140886441
         for (_JabRefPlugin.PushToApplicationExtension extension : plugins) {
 58  0
             applications.add(extension.getPushToApp());
 59  
         }
 60  
 
 61  140886441
         applications.add(new PushToLyx());
 62  140886441
         applications.add(new PushToEmacs());
 63  140886441
         applications.add(new PushToWinEdt());
 64  140886441
         applications.add(new PushToLatexEditor());
 65  140886441
         applications.add(new PushToVim());
 66  
 
 67  
         // Finally, sort the entries:
 68  
         //Collections.sort(applications, new PushToApplicationComparator());
 69  140886441
     }
 70  
 
 71  
 
 72  140886441
     public PushToApplicationButton(JabRefFrame frame, List<PushToApplication> pushActions) {
 73  140886441
         this.frame = frame;
 74  140886441
         this.pushActions = pushActions;
 75  140886441
         init();
 76  140886441
     }
 77  
 
 78  
     private void init() {
 79  140886441
         comp = new JPanel();
 80  140886441
         comp.setLayout(new BorderLayout());
 81  
 
 82  140886441
         menuButton = new JButton(new ImageIcon(ARROW_ICON));
 83  140886441
         menuButton.setMargin(new Insets(0,0,0,0));
 84  140886441
         menuButton.setPreferredSize(new Dimension(menuButton.getIcon().getIconWidth(),
 85  
                 menuButton.getIcon().getIconHeight()));
 86  140886441
         menuButton.addActionListener(new MenuButtonActionListener());
 87  140886441
         menuButton.setToolTipText(Globals.lang("Select external application"));
 88  140886441
         pushButton = new JButton();
 89  140886441
         if (Globals.prefs.hasKey("pushToApplication")) {
 90  132709607
             String appSelected = Globals.prefs.get("pushToApplication");
 91  132709607
             for (int i=0; i<pushActions.size(); i++) {
 92  132709607
                 PushToApplication toApp = pushActions.get(i);
 93  132709607
                 if (toApp.getName().equals(appSelected)) {
 94  132709607
                     selected = i;
 95  132709607
                     break;
 96  
                 }
 97  
             }
 98  
         }
 99  
 
 100  140886441
         setSelected(selected);
 101  140886441
         pushButton.addActionListener(this);
 102  140886441
         pushButton.addMouseListener(new PushButtonMouseListener());
 103  
 
 104  140886441
         comp.add(pushButton, BorderLayout.CENTER);
 105  140886441
         comp.add(menuButton, BorderLayout.EAST);
 106  140886441
         comp.setBorder(BorderFactory.createLineBorder(Color.gray));
 107  140886441
         comp.setMaximumSize(comp.getPreferredSize());
 108  
 
 109  140886441
         optPopup.add(settings);
 110  140886441
         settings.addActionListener(new ActionListener() {
 111  
             public void actionPerformed(ActionEvent event) {
 112  0
                 PushToApplication toApp = pushActions.get(selected);
 113  0
                 JPanel options = toApp.getSettingsPanel();
 114  0
                 if (options != null) {
 115  0
                     showSettingsDialog(frame, toApp, options);
 116  
                 }
 117  
 
 118  0
             }
 119  
         });
 120  
 
 121  140886441
         buildPopupMenu();
 122  140886441
     }
 123  
 
 124  
     /**
 125  
      * Create a selection menu for the available "Push" options.
 126  
      */
 127  
     private void buildPopupMenu() {
 128  140886441
         popup = new JPopupMenu();
 129  140886441
         int j=0;
 130  140886441
         for (PushToApplication application : pushActions){
 131  704432205
             JMenuItem item = new JMenuItem(application.getApplicationName(),
 132  
                     application.getIcon());
 133  704432205
             item.setToolTipText(application.getTooltip());
 134  704432205
             item.addActionListener(new PopupItemActionListener(j));
 135  704432205
             popup.add(item);
 136  704432205
             j++;
 137  704432205
         }
 138  140886441
     }
 139  
 
 140  
     /**
 141  
      * Update the PushButton to default to the given application.
 142  
      * @param i The List index of the application to default to.
 143  
      */
 144  
     private void setSelected(int i) {
 145  140887556
         this.selected = i;
 146  140887556
         PushToApplication toApp = pushActions.get(i);
 147  140887556
         pushButton.setIcon(toApp.getIcon());
 148  140887556
         pushButton.setToolTipText(toApp.getTooltip());
 149  140887556
         pushButton.setPreferredSize(buttonDim);
 150  
 
 151  140887556
         Globals.prefs.put("pushToApplication", toApp.getName());
 152  140887556
         mAction.setTitle(toApp.getApplicationName());
 153  140887556
     }
 154  
 
 155  
     /**
 156  
      * Get the toolbar component for the push button.
 157  
      * @return The component.
 158  
      */
 159  
     public Component getComponent() {
 160  140886441
        return comp;
 161  
     }
 162  
 
 163  
     public Action getMenuAction() {
 164  140886441
         return mAction;
 165  
     }
 166  
 
 167  
     public void actionPerformed(ActionEvent e) {
 168  28773
         PushToApplication toApp = pushActions.get(selected);
 169  
 
 170  
         // Lazy initialization of the push action:
 171  28773
         PushToApplicationAction action = actions.get(toApp);
 172  28773
         if (action == null) {
 173  28773
             action = new PushToApplicationAction(frame, toApp);
 174  28773
             actions.put(toApp, action);
 175  
         }
 176  28773
         action.actionPerformed(new ActionEvent(toApp, 0, "push"));
 177  28773
     }
 178  
 
 179  
     static class BooleanHolder {
 180  485749
         public BooleanHolder(boolean value) {
 181  485749
             this.value = value;
 182  485749
         }
 183  
         public boolean value;
 184  
     }
 185  
 
 186  
     public static void showSettingsDialog(Object parent, PushToApplication toApp, JPanel options) {
 187  
         
 188  485749
         final BooleanHolder okPressed = new BooleanHolder(false);
 189  
         JDialog dg;
 190  485749
         if (parent instanceof JDialog)
 191  0
             dg = new JDialog((JDialog)parent, Globals.lang("Settings"), true);
 192  
         else
 193  485749
             dg = new JDialog((JFrame)parent, Globals.lang("Settings"), true);
 194  485749
         final JDialog diag = dg;
 195  485749
         options.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
 196  485749
         diag.getContentPane().add(options, BorderLayout.CENTER);
 197  485749
         ButtonBarBuilder bb = new ButtonBarBuilder();
 198  485749
         JButton ok = new JButton(Globals.lang("Ok"));
 199  485749
         JButton cancel = new JButton(Globals.lang("Cancel"));
 200  485749
         bb.addGlue();
 201  485749
         bb.addGridded(ok);
 202  485749
         bb.addGridded(cancel);
 203  485749
         bb.addGlue();
 204  485749
         bb.getPanel().setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
 205  485749
         diag.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH);
 206  485749
         ok.addActionListener(new ActionListener() {
 207  
             public void actionPerformed(ActionEvent event) {
 208  230807
                 okPressed.value = true;
 209  230807
                 diag.dispose();
 210  230807
             }
 211  
         });
 212  485749
         cancel.addActionListener(new ActionListener() {
 213  
             public void actionPerformed(ActionEvent event) {
 214  47113
                 diag.dispose();
 215  47113
             }
 216  
         });
 217  
         // Key bindings:
 218  485749
         ActionMap am = bb.getPanel().getActionMap();
 219  485749
         InputMap im = bb.getPanel().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
 220  485749
         im.put(Globals.prefs.getKey("Close dialog"), "close");
 221  485749
         am.put("close", new AbstractAction() {
 222  
             public void actionPerformed(ActionEvent e) {
 223  0
                 diag.dispose();
 224  0
             }
 225  
         });
 226  485749
         diag.pack();
 227  485749
         if (parent instanceof JDialog)
 228  0
             diag.setLocationRelativeTo((JDialog)parent);
 229  
         else
 230  485749
             diag.setLocationRelativeTo((JFrame)parent);
 231  
         // Show the dialog:
 232  485749
         diag.setVisible(true);
 233  
         // If the user pressed Ok, ask the PushToApplication implementation
 234  
         // to store its settings:
 235  275724
         if (okPressed.value) {
 236  229773
             toApp.storeSettings();
 237  
         }
 238  275724
     }
 239  
 
 240  
     class PopupItemActionListener implements ActionListener {
 241  
         private int index;
 242  704432205
         public PopupItemActionListener(int index) {
 243  704432205
             this.index = index;
 244  704432205
         }
 245  
 
 246  
         public void actionPerformed(ActionEvent e) {
 247  
             // Change the selection:
 248  1115
             setSelected(index);
 249  
             // Invoke the selected operation (is that expected behaviour?):
 250  
             //PushToApplicationButton.this.actionPerformed(null);
 251  
             // It makes sense to transfer focus to the push button after the
 252  
             // menu closes:
 253  1115
             pushButton.requestFocus();
 254  1115
         }
 255  
     }
 256  
 
 257  
 
 258  140886441
     class MenuButtonActionListener implements ActionListener {
 259  
 
 260  
         public void actionPerformed(ActionEvent e) {
 261  
             // Lazy initialization of the popup menu:
 262  141686
             if (popup == null)
 263  0
                 buildPopupMenu();
 264  141686
             popup.show(comp, 0, menuButton.getHeight());
 265  141686
         }
 266  
     }
 267  
 
 268  
     class MenuAction extends MnemonicAwareAction {
 269  
 
 270  140886441
         public MenuAction() {
 271  140886441
             putValue(ACCELERATOR_KEY, Globals.prefs.getKey("Push to application"));
 272  140886441
         }
 273  
 
 274  
         public void setTitle(String appName) {
 275  140887556
             putValue(NAME, Globals.lang("Push entries to external application (%0)",
 276  
                     appName));
 277  140887556
         }
 278  
 
 279  
         public void actionPerformed(ActionEvent e) {
 280  28773
             PushToApplicationButton.this.actionPerformed(null);
 281  28773
         }
 282  
     }
 283  
 
 284  140886441
     class PushButtonMouseListener extends MouseAdapter {
 285  
         public void mousePressed(MouseEvent event) {
 286  0
             if (event.isPopupTrigger())
 287  0
                 processPopupTrigger(event);
 288  0
         }
 289  
 
 290  
         public void mouseClicked(MouseEvent event) {
 291  0
             if (event.isPopupTrigger())
 292  0
                 processPopupTrigger(event);
 293  0
         }
 294  
 
 295  
         public void mouseReleased(MouseEvent event) {
 296  0
             if (event.isPopupTrigger())
 297  0
                 processPopupTrigger(event);
 298  0
         }
 299  
 
 300  
         private void processPopupTrigger(MouseEvent e) {
 301  
             // We only want to show the popup if a settings panel exists for the selected
 302  
             // item:
 303  0
             PushToApplication toApp = pushActions.get(selected);
 304  0
             if (toApp.getSettingsPanel() != null)
 305  0
                 optPopup.show(pushButton, e.getX(), e.getY());
 306  
 
 307  0
         }
 308  
     }
 309  
 
 310  
     /**
 311  
      * Comparator for sorting the selection according to name.
 312  
      */
 313  0
     static class PushToApplicationComparator implements Comparator<PushToApplication> {
 314  
 
 315  
         public int compare(PushToApplication one, PushToApplication two) {
 316  0
             return one.getName().compareTo(two.getName());
 317  
         }
 318  
     }
 319  
 }