View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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      //--- Constant(s) ---
54  
55      //--- Data field(s) ---
56      
57      private static Preferences prefs = Preferences.getInstance();
58      private FileProvider fp;    
59  
60      //--- Constructor(s) ---
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      //--- Method(s) ---
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 }