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

Last change on this file since 1860 was 1860, checked in by Gubaer, 15 years ago

partial fix for #3109: window order generally messed up?

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