source: josm/trunk/src/org/openstreetmap/josm/plugins/PluginSelection.java@ 1672

Last change on this file since 1672 was 1672, checked in by stoecker, 15 years ago

fix #2726 - patch by Bananeweizen - minor UI design issue

File size: 15.1 KB
Line 
1//License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.plugins;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.GridBagConstraints;
8import java.awt.Insets;
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11
12import java.io.BufferedReader;
13import java.io.ByteArrayInputStream;
14import java.io.File;
15import java.io.FileInputStream;
16import java.io.InputStreamReader;
17import java.io.IOException;
18import java.util.Arrays;
19import java.util.Collection;
20import java.util.Collections;
21import java.util.Comparator;
22import java.util.HashMap;
23import java.util.HashSet;
24import java.util.LinkedList;
25import java.util.Map;
26import java.util.Set;
27import java.util.SortedMap;
28import java.util.TreeMap;
29import java.util.Map.Entry;
30
31import javax.swing.BorderFactory;
32import javax.swing.JCheckBox;
33import javax.swing.JEditorPane;
34import javax.swing.JOptionPane;
35import javax.swing.JPanel;
36import javax.swing.UIManager;
37import javax.swing.event.HyperlinkEvent;
38import javax.swing.event.HyperlinkListener;
39import javax.swing.event.HyperlinkEvent.EventType;
40
41import org.openstreetmap.josm.Main;
42import org.openstreetmap.josm.gui.ExtendedDialog;
43import org.openstreetmap.josm.tools.OpenBrowser;
44
45public class PluginSelection {
46
47 private Map<String, Boolean> pluginMap;
48 private Map<String, PluginInformation> availablePlugins;
49 private Map<String, PluginInformation> localPlugins;
50
51 public void updateDescription(JPanel pluginPanel) {
52 int count = PluginDownloader.downloadDescription();
53 if (count > 0)
54 JOptionPane.showMessageDialog(Main.parent,
55 trn("Downloaded plugin information from {0} site",
56 "Downloaded plugin information from {0} sites", count, count));
57 else
58 JOptionPane.showMessageDialog(Main.parent, tr("No plugin information found."));
59 drawPanel(pluginPanel);
60 }
61
62 public void update(JPanel pluginPanel) {
63 // refresh description
64 int num = PluginDownloader.downloadDescription();
65 Boolean done = false;
66 drawPanel(pluginPanel);
67
68 Set<PluginInformation> toUpdate = new HashSet<PluginInformation>();
69 StringBuilder toUpdateStr = new StringBuilder();
70 for (PluginProxy proxy : PluginHandler.pluginList) {
71 PluginInformation local = localPlugins.get(proxy.info.name);
72 PluginInformation description = availablePlugins.get(local.name);
73
74 if (description != null && (description.version == null || description.version.equals("")) ?
75 (local.version != null && local.version.equals("")) : !description.version.equals(local.version)) {
76 toUpdate.add(description);
77 toUpdateStr.append(description.name+"\n");
78 }
79 }
80 if (toUpdate.isEmpty()) {
81 JOptionPane.showMessageDialog(Main.parent, tr("All installed plugins are up to date."));
82 done = true;
83 } else {
84 int answer = new ExtendedDialog(Main.parent,
85 tr("Update"),
86 tr("Update the following plugins:\n\n{0}", toUpdateStr.toString()),
87 new String[] {tr("Update Plugins"), tr("Cancel")},
88 new String[] {"dialogs/refresh.png", "cancel.png"}).getValue();
89 if (answer == 1) {
90 PluginDownloader.update(toUpdate);
91 done = true;
92 }
93 }
94 if (done && num >= 1)
95 Main.pref.put("pluginmanager.lastupdate", Long.toString(System.currentTimeMillis()));
96 drawPanel(pluginPanel);
97 }
98
99 public Boolean finish() {
100 Collection<PluginInformation> toDownload = new LinkedList<PluginInformation>();
101 String msg = "";
102 for (Entry<String, Boolean> entry : pluginMap.entrySet()) {
103 if(entry.getValue())
104 {
105 String name = entry.getKey();
106 PluginInformation ap = availablePlugins.get(name);
107 PluginInformation pi = localPlugins.get(name);
108 if(pi == null || (pi.version == null && ap.version != null)
109 || (pi.version != null && !pi.version.equals(ap.version)))
110 {
111 toDownload.add(ap);
112 msg += name + "\n";
113 }
114 }
115 }
116 if (!toDownload.isEmpty()) {
117 int answer = new ExtendedDialog(Main.parent,
118 tr("Download missing plugins"),
119 tr("Download the following plugins?\n\n{0}", msg),
120 new String[] {tr("Download Plugins"), tr("Cancel")},
121 new String[] {"download.png", "cancel.png"}).getValue();
122 Collection<PluginInformation> error =
123 (answer != 1 ? toDownload : new PluginDownloader().download(toDownload));
124 for (PluginInformation pd : error)
125 pluginMap.put(pd.name, false);
126
127 }
128 LinkedList<String> plugins = new LinkedList<String>();
129 for (Map.Entry<String, Boolean> d : pluginMap.entrySet()) {
130 if (d.getValue())
131 plugins.add(d.getKey());
132 }
133
134 Collections.sort(plugins);
135 return Main.pref.putCollection("plugins", plugins);
136 }
137
138 /* return true when plugin list changed */
139 public void drawPanel(JPanel pluginPanel) {
140 availablePlugins = getAvailablePlugins();
141 Collection<String> enabledPlugins = Main.pref.getCollection("plugins", null);
142
143 if (pluginMap == null)
144 pluginMap = new HashMap<String, Boolean>();
145 else {
146 // Keep the map in bounds; possibly slightly pointless.
147 Set<String> pluginsToRemove = new HashSet<String>();
148 for (final String pname : pluginMap.keySet()) {
149 if (availablePlugins.get(pname) == null) pluginsToRemove.add(pname);
150 }
151
152 for (String pname : pluginsToRemove) {
153 pluginMap.remove(pname);
154 }
155 }
156
157 pluginPanel.removeAll();
158
159 GridBagConstraints gbc = new GridBagConstraints();
160 gbc.gridx = 0;
161 gbc.anchor = GridBagConstraints.NORTHWEST;
162
163 int row = 0;
164 for (final PluginInformation plugin : availablePlugins.values()) {
165 boolean enabled = (enabledPlugins != null) && enabledPlugins.contains(plugin.name);
166 if (pluginMap.get(plugin.name) == null)
167 pluginMap.put(plugin.name, enabled);
168
169 String remoteversion = plugin.version;
170 if ((remoteversion == null) || remoteversion.equals(""))
171 remoteversion = tr("unknown");
172
173 String localversion = "";
174 PluginInformation p = localPlugins.get(plugin.name);
175 if(p != null)
176 {
177 if (p.version != null && !p.version.equals(""))
178 localversion = p.version;
179 else
180 localversion = tr("unknown");
181 localversion = " (" + localversion + ")";
182 }
183
184 final JCheckBox pluginCheck = new JCheckBox(
185 tr("{0}: Version {1}{2}", plugin.name, remoteversion, localversion),
186 pluginMap.get(plugin.name));
187 gbc.gridy = row++;
188 gbc.insets = new Insets(5,5,0,5);
189 gbc.weighty = 0.1;
190 gbc.fill = GridBagConstraints.NONE;
191 pluginPanel.add(pluginCheck, gbc);
192
193 pluginCheck.setToolTipText(plugin.downloadlink != null ? ""+plugin.downloadlink : tr("Plugin bundled with JOSM"));
194
195 JEditorPane description = new JEditorPane();
196 description.setContentType("text/html");
197 description.setEditable(false);
198 description.setText("<html><body bgcolor=\"#" + Integer.toHexString( UIManager.getColor("Panel.background").getRGB() & 0x00ffffff ) +"\"><i>"+plugin.getLinkDescription()+"</i></body></html>");
199 description.setBorder(BorderFactory.createEmptyBorder());
200 description.setBackground(UIManager.getColor("Panel.background"));
201 description.addHyperlinkListener(new HyperlinkListener() {
202 public void hyperlinkUpdate(HyperlinkEvent e) {
203 if(e.getEventType() == EventType.ACTIVATED) {
204 OpenBrowser.displayUrl(e.getURL().toString());
205 }
206 }
207 });
208
209 gbc.gridy = row++;
210 gbc.insets = new Insets(3,25,5,5);
211 gbc.weighty = 0.9;
212 gbc.weightx = 1.0;
213 gbc.anchor = GridBagConstraints.WEST;
214 gbc.fill = GridBagConstraints.HORIZONTAL;
215 pluginPanel.add(description, gbc);
216
217 pluginCheck.addActionListener(new ActionListener(){
218 public void actionPerformed(ActionEvent e) {
219 pluginMap.put(plugin.name, pluginCheck.isSelected());
220 }
221 });
222 }
223 pluginPanel.updateUI();
224 }
225
226 /**
227 * Return information about a loaded plugin.
228 *
229 * Note that if you call this in your plugins bootstrap, you may get <code>null</code> if
230 * the plugin requested is not loaded yet.
231 *
232 * @return The PluginInformation to a specific plugin, but only if the plugin is loaded.
233 * If it is not loaded, <code>null</code> is returned.
234 */
235 private static PluginInformation getLoaded(String pluginName) {
236 for (PluginProxy p : PluginHandler.pluginList)
237 if (p.info.name.equals(pluginName))
238 return p.info;
239 return null;
240 }
241
242 private Map<String, PluginInformation> getAvailablePlugins() {
243 SortedMap<String, PluginInformation> availablePlugins = new TreeMap<String, PluginInformation>(new Comparator<String>(){
244 public int compare(String o1, String o2) {
245 return o1.compareToIgnoreCase(o2);
246 }
247 });
248 localPlugins = new TreeMap<String, PluginInformation>(new Comparator<String>(){
249 public int compare(String o1, String o2) {
250 return o1.compareToIgnoreCase(o2);
251 }
252 });
253 for (String location : PluginInformation.getPluginLocations()) {
254 File[] pluginFiles = new File(location).listFiles();
255 if (pluginFiles != null) {
256 Arrays.sort(pluginFiles);
257 for (File f : pluginFiles) {
258 if (!f.isFile())
259 continue;
260 String fname = f.getName();
261 if (fname.endsWith(".jar")) {
262 try {
263 PluginInformation info = new PluginInformation(f,fname.substring(0,fname.length()-4));
264 if (!availablePlugins.containsKey(info.name))
265 availablePlugins.put(info.name, info);
266 if (!localPlugins.containsKey(info.name))
267 localPlugins.put(info.name, info);
268 } catch (PluginException x) {
269 }
270 } else if (fname.endsWith(".jar.new")) {
271 try {
272 PluginInformation info = new PluginInformation(f,fname.substring(0,fname.length()-8));
273 availablePlugins.put(info.name, info);
274 localPlugins.put(info.name, info);
275 } catch (PluginException x) {
276 }
277 } else if (fname.matches("^[0-9]+-site.*\\.txt$")) {
278 int err = 0;
279 try {
280 BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(f), "utf-8"));
281 String name = null;
282 String url = null;
283 String manifest = null;
284 for (String line = r.readLine(); line != null; line = r.readLine())
285 {
286 if(line.startsWith("\t"))
287 {
288 line = line.substring(1);
289 if(line.length() > 70)
290 {
291 manifest += line.substring(0,70)+"\n";
292 line = " " + line.substring(70);
293 }
294 manifest += line+"\n";
295 }
296 else
297 {
298 if(name != null)
299 {
300 try
301 {
302 PluginInformation info = new PluginInformation(
303 new ByteArrayInputStream(manifest.getBytes("utf-8")),
304 name.substring(0,name.length()-4));
305 info.downloadlink = url;
306 if(!availablePlugins.containsKey(info.name))
307 availablePlugins.put(info.name, info);
308 }
309 catch (Exception e)
310 {
311 e.printStackTrace();
312 ++err;
313 }
314 }
315 String x[] = line.split(";");
316 name = x[0];
317 url = x[1];
318 manifest = null;
319 }
320 }
321 if(name != null)
322 {
323 PluginInformation info = new PluginInformation(
324 new ByteArrayInputStream(manifest.getBytes("utf-8")),
325 name.substring(0,name.length()-4));
326 info.downloadlink = url;
327 if(!availablePlugins.containsKey(info.name))
328 availablePlugins.put(info.name, info);
329 }
330 r.close();
331 } catch (Exception e) {
332 e.printStackTrace();
333 ++err;
334 }
335 if(err > 0)
336 {
337 JOptionPane.showMessageDialog(Main.parent, tr("Error reading plugin information file: {0}", f.getName()));
338 }
339 }
340 }
341 }
342 }
343 for (PluginProxy proxy : PluginHandler.pluginList)
344 {
345 if (!availablePlugins.containsKey(proxy.info.name))
346 availablePlugins.put(proxy.info.name, proxy.info);
347 if (!localPlugins.containsKey(proxy.info.name))
348 localPlugins.put(proxy.info.name, proxy.info);
349 }
350 return availablePlugins;
351 }
352}
Note: See TracBrowser for help on using the repository browser.