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

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