source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/PluginPreference.java@ 343

Last change on this file since 343 was 343, checked in by gebner, 17 years ago

Merge 0.5.

File size: 11.4 KB
Line 
1//License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.preferences;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.Dimension;
8import java.awt.GridBagLayout;
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.io.File;
12import java.io.FileReader;
13import java.util.Arrays;
14import java.util.Collection;
15import java.util.Collections;
16import java.util.Comparator;
17import java.util.HashMap;
18import java.util.HashSet;
19import java.util.LinkedList;
20import java.util.Map;
21import java.util.Set;
22import java.util.SortedMap;
23import java.util.TreeMap;
24import java.util.Map.Entry;
25
26import javax.swing.AbstractAction;
27import javax.swing.BorderFactory;
28import javax.swing.Box;
29import javax.swing.DefaultListModel;
30import javax.swing.JButton;
31import javax.swing.JCheckBox;
32import javax.swing.JLabel;
33import javax.swing.JList;
34import javax.swing.JOptionPane;
35import javax.swing.JPanel;
36import javax.swing.JScrollPane;
37
38import org.openstreetmap.josm.Main;
39import org.openstreetmap.josm.plugins.PluginDownloader;
40import org.openstreetmap.josm.plugins.PluginException;
41import org.openstreetmap.josm.plugins.PluginInformation;
42import org.openstreetmap.josm.plugins.PluginProxy;
43import org.openstreetmap.josm.tools.GBC;
44import org.openstreetmap.josm.tools.XmlObjectParser.Uniform;
45
46public class PluginPreference implements PreferenceSetting {
47
48 /**
49 * Only the plugin name, it's jar location and the description.
50 * In other words, this is the minimal requirement the plugin preference page
51 * needs to show the plugin as available
52 *
53 * @author imi
54 */
55 public static class PluginDescription {
56 public String name;
57 public String description;
58 public String resource;
59 public String version;
60 public PluginDescription(String name, String description, String resource, String version) {
61 this.name = name;
62 this.description = description;
63 this.resource = resource;
64 this.version = version;
65 }
66 public PluginDescription() {
67 }
68 }
69
70 private Map<PluginDescription, Boolean> pluginMap;
71 private Box pluginPanel = Box.createVerticalBox();
72 private JPanel plugin;
73 private PreferenceDialog gui;
74
75 public void addGui(final PreferenceDialog gui) {
76 this.gui = gui;
77 plugin = gui.createPreferenceTab("plugin", tr("Plugins"), tr("Configure available plugins."));
78 JScrollPane pluginPane = new JScrollPane(pluginPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
79 pluginPane.setBorder(null);
80 plugin.add(pluginPane, GBC.eol().fill(GBC.BOTH));
81 plugin.add(GBC.glue(0,10), GBC.eol());
82 JButton morePlugins = new JButton(tr("Check for plugins"));
83 morePlugins.addActionListener(new ActionListener(){
84 public void actionPerformed(ActionEvent e) {
85 int count = PluginDownloader.downloadDescription();
86 if (count > 0)
87 JOptionPane.showMessageDialog(Main.parent,
88 trn("Downloaded plugin information from {0} site",
89 "Downloaded plugin information from {0} sites", count, count));
90 else
91 JOptionPane.showMessageDialog(Main.parent, tr("No plugin information found."));
92 refreshPluginPanel(gui);
93 }
94 });
95 plugin.add(morePlugins, GBC.std().insets(0,0,10,0));
96
97 JButton update = new JButton(tr("Update current"));
98 update.addActionListener(new ActionListener(){
99 public void actionPerformed(ActionEvent e) {
100 update();
101 }
102
103 });
104 plugin.add(update, GBC.std().insets(0,0,10,0));
105
106 JButton configureSites = new JButton(tr("Configure Plugin Sites"));
107 configureSites.addActionListener(new ActionListener(){
108 public void actionPerformed(ActionEvent e) {
109 configureSites();
110 }
111
112 });
113 plugin.add(configureSites, GBC.std());
114
115 refreshPluginPanel(gui);
116 }
117
118 private void configureSites() {
119 JPanel p = new JPanel(new GridBagLayout());
120 p.add(new JLabel(tr("Add either site-josm.xml or Wiki Pages.")), GBC.eol());
121 final DefaultListModel model = new DefaultListModel();
122 for (String s : PluginDownloader.getSites())
123 model.addElement(s);
124 final JList list = new JList(model);
125 p.add(new JScrollPane(list), GBC.std().fill());
126 JPanel buttons = new JPanel(new GridBagLayout());
127 buttons.add(new JButton(new AbstractAction(tr("Add")){
128 public void actionPerformed(ActionEvent e) {
129 String s = JOptionPane.showInputDialog(gui, tr("Add either site-josm.xml or Wiki Pages."));
130 if (s != null)
131 model.addElement(s);
132 }
133 }), GBC.eol().fill(GBC.HORIZONTAL));
134 buttons.add(new JButton(new AbstractAction(tr("Edit")){
135 public void actionPerformed(ActionEvent e) {
136 if (list.getSelectedValue() == null) {
137 JOptionPane.showMessageDialog(gui, tr("Please select an entry."));
138 return;
139 }
140 String s = JOptionPane.showInputDialog(gui, tr("Add either site-josm.xml or Wiki Pages."), list.getSelectedValue());
141 model.setElementAt(s, list.getSelectedIndex());
142 }
143 }), GBC.eol().fill(GBC.HORIZONTAL));
144 buttons.add(new JButton(new AbstractAction(tr("Delete")){
145 public void actionPerformed(ActionEvent event) {
146 if (list.getSelectedValue() == null) {
147 JOptionPane.showMessageDialog(gui, tr("Please select an entry."));
148 return;
149 }
150 model.removeElement(list.getSelectedValue());
151 }
152 }), GBC.eol().fill(GBC.HORIZONTAL));
153 p.add(buttons, GBC.eol());
154 int answer = JOptionPane.showConfirmDialog(gui, p, tr("Configure Plugin Sites"), JOptionPane.OK_CANCEL_OPTION);
155 if (answer != JOptionPane.OK_OPTION)
156 return;
157 StringBuilder b = new StringBuilder();
158 for (int i = 0; i < model.getSize(); ++i) {
159 b.append(model.getElementAt(i));
160 if (i < model.getSize()-1)
161 b.append(" ");
162 }
163 Main.pref.put("pluginmanager.sites", b.toString());
164 }
165
166 private void update() {
167 Set<PluginDescription> toUpdate = new HashSet<PluginDescription>();
168 StringBuilder toUpdateStr = new StringBuilder();
169 for (PluginProxy proxy : Main.plugins) {
170 PluginDescription description = findDescription(proxy.info.name);
171 if (description != null && (description.version == null || description.version.equals("")) ? (proxy.info.version != null && proxy.info.version.equals("")) : !description.version.equals(proxy.info.version)) {
172 toUpdate.add(description);
173 toUpdateStr.append(description.name+"\n");
174 }
175 }
176 if (toUpdate.isEmpty()) {
177 JOptionPane.showMessageDialog(Main.parent, tr("All installed plugins are up to date."));
178 return;
179 }
180 int answer = JOptionPane.showConfirmDialog(Main.parent, tr("Update the following plugins:\n\n{0}", toUpdateStr.toString()), tr("Update"), JOptionPane.OK_CANCEL_OPTION);
181 if (answer != JOptionPane.OK_OPTION)
182 return;
183 PluginDownloader.update(toUpdate);
184 }
185
186 private PluginDescription findDescription(String name) {
187 for (PluginDescription d : pluginMap.keySet())
188 if (d.name.equals(name))
189 return d;
190 return null;
191 }
192
193 private void refreshPluginPanel(final PreferenceDialog gui) {
194 Collection<PluginDescription> availablePlugins = getAvailablePlugins();
195 pluginMap = new HashMap<PluginDescription, Boolean>();
196 pluginPanel.removeAll();
197
198 // the following could probably be done more elegantly?
199 Collection<String> enabledPlugins = null;
200 String enabledProp = Main.pref.get("plugins");
201 if ((enabledProp == null) || ("".equals(enabledProp))) {
202 enabledPlugins = Collections.EMPTY_SET;
203 }
204 else
205 {
206 enabledPlugins = Arrays.asList(enabledProp.split(","));
207 }
208
209 for (final PluginDescription plugin : availablePlugins) {
210 boolean enabled = enabledPlugins.contains(plugin.name);
211 final JCheckBox pluginCheck = new JCheckBox(plugin.name+(plugin.version != null && !plugin.version.equals("") ? " Version: "+plugin.version : ""), enabled);
212 pluginPanel.add(pluginCheck);
213
214 pluginCheck.setToolTipText(plugin.resource != null ? plugin.resource : tr("Plugin bundled with JOSM"));
215 JLabel label = new JLabel("<html><i>"+(plugin.description==null?tr("no description available"):plugin.description)+"</i></html>");
216 label.setBorder(BorderFactory.createEmptyBorder(0,20,0,0));
217 label.setMaximumSize(new Dimension(450,1000));
218 pluginPanel.add(label);
219 pluginPanel.add(Box.createVerticalStrut(5));
220
221 pluginMap.put(plugin, enabled);
222 pluginCheck.addActionListener(new ActionListener(){
223 public void actionPerformed(ActionEvent e) {
224 pluginMap.put(plugin, pluginCheck.isSelected());
225 }
226 });
227 }
228 plugin.updateUI();
229 }
230
231 private Collection<PluginDescription> getAvailablePlugins() {
232 SortedMap<String, PluginDescription> availablePlugins = new TreeMap<String, PluginDescription>(new Comparator<String>(){
233 public int compare(String o1, String o2) {
234 return o1.compareToIgnoreCase(o2);
235 }
236 });
237 for (String location : PluginInformation.getPluginLocations()) {
238 File[] pluginFiles = new File(location).listFiles();
239 if (pluginFiles != null) {
240 Arrays.sort(pluginFiles);
241 for (File f : pluginFiles) {
242 if (!f.isFile())
243 continue;
244 if (f.getName().endsWith(".jar")) {
245 try {
246 PluginInformation info = new PluginInformation(f);
247 if (!availablePlugins.containsKey(info.name))
248 availablePlugins.put(info.name, new PluginDescription(info.name, info.description, PluginInformation.getURLString(f.getPath()), info.version));
249 } catch (PluginException x) {
250 }
251 } else if (f.getName().matches("^[0-9]+-site.*\\.xml$")) {
252 try {
253 Uniform<PluginDescription> parser = new Uniform<PluginDescription>(new FileReader(f), "plugin", PluginDescription.class);
254 for (PluginDescription pd : parser)
255 if (!availablePlugins.containsKey(pd.name))
256 availablePlugins.put(pd.name, pd);
257 } catch (Exception e) {
258 e.printStackTrace();
259 JOptionPane.showMessageDialog(Main.parent, tr("Error reading plugin information file: {0}", f.getName()));
260 }
261 }
262 }
263 }
264 }
265 for (PluginProxy proxy : Main.plugins)
266 if (!availablePlugins.containsKey(proxy.info.name))
267 availablePlugins.put(proxy.info.name, new PluginDescription(
268 proxy.info.name,
269 proxy.info.description,
270 proxy.info.file == null ? null : PluginInformation.getURLString(proxy.info.file.getPath()),
271 proxy.info.version));
272 return availablePlugins.values();
273 }
274
275 public void ok() {
276 Collection<PluginDescription> toDownload = new LinkedList<PluginDescription>();
277 String msg = "";
278 for (Entry<PluginDescription, Boolean> entry : pluginMap.entrySet()) {
279 if (entry.getValue() && PluginInformation.findPlugin(entry.getKey().name) == null) {
280 toDownload.add(entry.getKey());
281 msg += entry.getKey().name+"\n";
282 }
283 }
284 if (!toDownload.isEmpty()) {
285 int answer = JOptionPane.showConfirmDialog(Main.parent,
286 tr("Download the following plugins?\n\n{0}", msg),
287 tr("Download missing plugins"),
288 JOptionPane.YES_NO_OPTION);
289 if (answer != JOptionPane.OK_OPTION)
290 for (PluginDescription pd : toDownload)
291 pluginMap.put(pd, false);
292 else
293 for (PluginDescription pd : toDownload)
294 if (!PluginDownloader.downloadPlugin(pd))
295 pluginMap.put(pd, false);
296
297 }
298
299 String plugins = "";
300 for (Entry<PluginDescription, Boolean> entry : pluginMap.entrySet())
301 if (entry.getValue())
302 plugins += entry.getKey().name + ",";
303 if (plugins.endsWith(","))
304 plugins = plugins.substring(0, plugins.length()-1);
305
306 String oldPlugins = Main.pref.get("plugins");
307 if (!plugins.equals(oldPlugins)) {
308 Main.pref.put("plugins", plugins);
309 gui.requiresRestart = true;
310 }
311 }
312}
Note: See TracBrowser for help on using the repository browser.