1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.gui.menu;
21
22 import java.awt.Component;
23 import java.awt.event.ActionEvent;
24 import java.beans.PropertyChangeEvent;
25 import java.beans.PropertyChangeListener;
26 import java.io.File;
27 import java.io.IOException;
28 import java.util.Arrays;
29 import java.util.Iterator;
30 import java.util.LinkedList;
31
32 import javax.swing.AbstractAction;
33 import javax.swing.Action;
34 import javax.swing.JMenu;
35 import javax.swing.JOptionPane;
36
37 import org.xnap.XNap;
38 import org.xnap.gui.Dialogs;
39 import org.xnap.gui.FileProvider;
40 import org.xnap.gui.util.IconHelper;
41 import org.xnap.util.Preferences;
42 import org.xnap.util.launcher.LauncherManager;
43
44 /***
45 * This class provides a menu to open files provided by the
46 * {@link FileProvider}. It displays a history of recently used commands on
47 * files and offers an input dialog to enter new commands.
48 */
49 public class OpenFileWithMenu extends JMenu
50 implements PropertyChangeListener
51 {
52
53
54
55
56
57 private static Preferences prefs = Preferences.getInstance();
58 private FileProvider fp;
59
60
61
62 /***
63 * Constructs a new OpenFileWithMenu for a given
64 * <code>FileProvider</code>.
65 */
66 public OpenFileWithMenu(FileProvider fp)
67 {
68 super(XNap.tr("Open With"));
69
70 this.fp = fp;
71
72 setIcon(IconHelper.getMenuIcon("folder_new.png"));
73 setupMenu();
74
75 prefs.addPropertyChangeListener("openWithCommands", this);
76 }
77
78
79
80 private void openFiles(String command)
81 {
82 File[] files = fp.getFiles();
83
84 if (files == null || command == null) {
85 return;
86 }
87
88 try {
89 LauncherManager.exec(command, files);
90 }
91 catch (IOException e) {
92 Dialogs.error(null, "Could not execute " + command + "."
93 + e.getLocalizedMessage());
94 }
95 }
96
97 private void setupMenu()
98 {
99 removeAll();
100 add(new OthersAction());
101 addSeparator();
102
103 String[] commands = prefs.getOpenWithCommands();
104 for (int i = 0; i < commands.length; i++) {
105 add(new ItemAction(commands[i]));
106 }
107 }
108
109 /***
110 * Updates the menu if list of recently used commands changes.
111 */
112 public void propertyChange(PropertyChangeEvent e)
113 {
114 setupMenu();
115 }
116
117 private void insertCommand(String command)
118 {
119 LinkedList commands
120 = new LinkedList(Arrays.asList(prefs.getOpenWithCommands()));
121 for (Iterator i = commands.iterator(); i.hasNext();) {
122 if (command.equals((String) i.next())) {
123 i.remove();
124 break;
125 }
126 }
127
128 commands.addFirst(command);
129 while (commands.size() > prefs.getMaxOpenWithCommands()) {
130 commands.removeLast();
131 }
132
133 prefs.setOpenWithCommands((String[])commands.toArray(new String[0]));
134 }
135
136 /***
137 * Executes a single command in the the history menu.
138 */
139 private class ItemAction extends AbstractAction
140 {
141 String command;
142
143 public ItemAction(String command)
144 {
145 this.command = command;
146
147 putValue(Action.NAME, command);
148 }
149
150 public void actionPerformed(ActionEvent event)
151 {
152 openFiles(command);
153 insertCommand(command);
154 }
155 }
156
157 /***
158 * Opens the input dialog to accept new commands from the user.
159 */
160 private class OthersAction extends AbstractAction
161 {
162
163 public OthersAction()
164 {
165 this.putValue(Action.NAME, XNap.tr("Other") + "...");
166 }
167
168 public void actionPerformed(ActionEvent event)
169 {
170 String command = JOptionPane.showInputDialog
171 (fp instanceof Component ? (Component)fp : null,
172 XNap.tr("Enter command"),XNap.tr("Open With") + "...",
173 JOptionPane.QUESTION_MESSAGE);
174
175 openFiles(command);
176
177 if (command != null) {
178 insertCommand(command);
179 }
180 }
181 }
182
183 }