Ignore:
Timestamp:
2009-01-23T22:22:10+01:00 (15 years ago)
Author:
stoecker
Message:

reworked plugin handling a lot, more to come

Location:
trunk/src/org/openstreetmap/josm/gui
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/MainApplication.java

    r1286 r1326  
    66import static org.openstreetmap.josm.tools.I18n.i18n;
    77import static org.openstreetmap.josm.tools.I18n.tr;
    8 
    98
    109import java.awt.EventQueue;
     
    2423
    2524import javax.swing.JFrame;
    26 import javax.swing.JOptionPane;
    2725
    2826import org.openstreetmap.josm.Main;
    29 import org.openstreetmap.josm.plugins.PluginDownloader;
     27import org.openstreetmap.josm.plugins.PluginHandler;
    3028import org.openstreetmap.josm.tools.BugReportExceptionHandler;
    3129import org.openstreetmap.josm.tools.ImageProvider;
     
    6765     */
    6866    public static void main(final String[] argArray) {
    69         /////////////////////////////////////////////////////////////////////////
    70         //                        TO ALL TRANSLATORS
    71         /////////////////////////////////////////////////////////////////////////
    72         // Do not translate the early strings below until the locale is set up.
    73         // (By the eager loaded plugins)
    74         //
    75         // These strings cannot be translated. That's life. Really. Sorry.
    76         //
    77         //                                                                 Imi.
    78         /////////////////////////////////////////////////////////////////////////
     67        /* try initial language settings, may be changed later again */
     68        try { i18n = I18nFactory.getI18n(MainApplication.class); }
     69        catch (MissingResourceException ex) { Locale.setDefault(Locale.ENGLISH);}
    7970
    8071        Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
     
    10192        }
    10293
     94        Main.pref.init(args.containsKey("reset-preferences"));
     95
     96        String localeName = null; // The locale to use
     97
     98        //Check if passed as parameter
     99        if(args.containsKey("language"))
     100            localeName = (String)(args.get("language").toArray()[0]);
     101
     102        if (localeName == null)
     103            localeName = Main.pref.get("language", null);
     104
     105        if (localeName != null) {
     106            Locale l;
     107            Locale d = Locale.getDefault();
     108            if(localeName.equals("he")) localeName = "iw_IL";
     109            int i = localeName.indexOf('_');
     110            if (i > 0) {
     111                l = new Locale(localeName.substring(0, i), localeName.substring(i + 1));
     112            } else {
     113                l = new Locale(localeName);
     114            }
     115            try {
     116                Locale.setDefault(l);
     117                i18n = I18nFactory.getI18n(MainApplication.class);
     118            } catch (MissingResourceException ex) {
     119                if(!l.getLanguage().equals("en"))
     120                {
     121                    System.out.println(tr("Unable to find translation for the locale {0}. Reverting to {1}.",
     122                    l.getDisplayName(), d.getDisplayName()));
     123                    Locale.setDefault(d);
     124                }
     125            }
     126        }
     127
    103128        if (argList.contains("--help") || argList.contains("-?") || argList.contains("-h")) {
    104129            // TODO: put in a platformHook for system that have no console by default
     
    122147                    "\tjava -jar josm.jar london.osm --selection=http://www.ostertag.name/osm/OSM_errors_node-duplicate.xml\n"+
    123148                    "\tjava -jar josm.jar 43.2,11.1,43.4,11.4\n\n"+
    124 
    125149                    tr("Parameters are read in the order they are specified, so make sure you load\n"+
    126150                    "some data before --selection")+"\n\n"+
     
    129153        }
    130154
    131         // get the preferences.
    132         final File prefDir = new File(Main.pref.getPreferencesDir());
    133         if (prefDir.exists()) {
    134             if(!prefDir.isDirectory()) {
    135                 JOptionPane.showMessageDialog(null, tr("Cannot open preferences directory: {0}",Main.pref.getPreferencesDir()));
    136                 return;
    137             }
    138         }
    139         else
    140             prefDir.mkdirs();
    141 
    142         if (!new File(Main.pref.getPreferencesDir()+"preferences").exists()) {
    143             Main.pref.resetToDefault();
    144         }
    145 
    146         try {
    147             if (args.containsKey("reset-preferences")) {
    148                 Main.pref.resetToDefault();
    149             } else {
    150                 Main.pref.load();
    151             }
    152         } catch (final IOException e1) {
    153             e1.printStackTrace();
    154             String backup = Main.pref.getPreferencesDir() + "preferences.bak";
    155             JOptionPane.showMessageDialog(null, tr("Preferences file had errors. Making backup of old one to {0}.", backup));
    156             new File(Main.pref.getPreferencesDir() + "preferences").renameTo(new File(backup));
    157             Main.pref.save();
    158         }
    159 
    160         String localeName = null; //The locale to use
    161 
    162         //Check if passed as parameter
    163         if(args.containsKey("language"))
    164             localeName = (String)(args.get("language").toArray()[0]);
    165 
    166         if (localeName == null) {
    167             localeName = Main.pref.get("language", null);
    168         }
    169 
    170         if (localeName != null) {
    171             if(localeName.equals("he")) localeName = "iw_IL";
    172             Locale l;
    173             int i = localeName.indexOf('_');
    174             if (i > 0) {
    175                 l = new Locale(localeName.substring(0, i), localeName.substring(i + 1));
    176             } else {
    177                 l = new Locale(localeName);
    178             }
    179             Locale.setDefault(l);
    180         }
    181         try {
    182             i18n = I18nFactory.getI18n(MainApplication.class);
    183         } catch (MissingResourceException ex) {
    184             if(!Locale.getDefault().getLanguage().equals("en"))
    185             {
    186                 System.out.println("Unable to find translation for the locale: "
    187                 + Locale.getDefault().getDisplayName() + " reverting to English.");
    188                 Locale.setDefault(Locale.ENGLISH);
    189             }
    190         }
    191 
    192155        SplashScreen splash = new SplashScreen(Main.pref.getBoolean("draw.splashscreen", true));
    193156
    194157        splash.setStatus(tr("Activating updated plugins"));
    195         if (!PluginDownloader.moveUpdatedPlugins()) {
    196             JOptionPane.showMessageDialog(null,
    197                     tr("Activating the updated plugins failed. Check if JOSM has the permission to overwrite the existing ones."),
    198                     tr("Plugins"), JOptionPane.ERROR_MESSAGE);
    199         }
     158        PluginHandler.earlyCleanup();
    200159
    201         // load the early plugins
    202160        splash.setStatus(tr("Loading early plugins"));
    203         Main.loadPlugins(true);
     161        PluginHandler.loadPlugins(true);
    204162
    205163        splash.setStatus(tr("Setting defaults"));
     
    210168        final Main main = new MainApplication(mainFrame, splash);
    211169        splash.setStatus(tr("Loading plugins"));
    212         Main.loadPlugins(false);
     170        PluginHandler.loadPlugins(false);
    213171        toolbar.refreshToolbarControl();
    214172
  • trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java

    r1307 r1326  
    3030import org.openstreetmap.josm.data.Bounds;
    3131import org.openstreetmap.josm.gui.MapView;
    32 import org.openstreetmap.josm.plugins.PluginProxy;
     32import org.openstreetmap.josm.plugins.PluginHandler;
    3333import org.openstreetmap.josm.tools.GBC;
    3434import org.openstreetmap.josm.tools.OsmUrlToBounds;
     
    107107
    108108        // add selections from plugins
    109         for (PluginProxy p : Main.plugins) {
    110             p.addDownloadSelection(downloadSelections);
    111         }
     109        PluginHandler.addDownloadSelection(downloadSelections);
    112110
    113111        // now everybody may add their tab to the tabbed pane
  • trunk/src/org/openstreetmap/josm/gui/preferences/PluginPreference.java

    r1212 r1326  
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    5 import static org.openstreetmap.josm.tools.I18n.trn;
    65
    76import java.awt.Dimension;
    8 import java.awt.GridBagConstraints;
    97import java.awt.GridBagLayout;
    10 import java.awt.Insets;
    118import java.awt.Rectangle;
    129import java.awt.event.ActionEvent;
    1310import java.awt.event.ActionListener;
    14 import java.io.File;
    15 import java.io.FileReader;
    16 import java.io.IOException;
    17 import java.util.Arrays;
    1811import java.util.Collection;
    19 import java.util.Collections;
    20 import java.util.Comparator;
    21 import java.util.HashMap;
    22 import java.util.HashSet;
    2312import java.util.LinkedList;
    24 import java.util.Map;
    25 import java.util.Set;
    26 import java.util.SortedMap;
    27 import java.util.TreeMap;
    28 import java.util.Map.Entry;
    2913
    3014import javax.swing.AbstractAction;
    31 import javax.swing.BorderFactory;
    3215import javax.swing.DefaultListModel;
    3316import javax.swing.JButton;
    34 import javax.swing.JCheckBox;
    35 import javax.swing.JEditorPane;
    3617import javax.swing.JLabel;
    3718import javax.swing.JList;
     
    4021import javax.swing.JScrollPane;
    4122import javax.swing.Scrollable;
    42 import javax.swing.UIManager;
    43 import javax.swing.event.HyperlinkEvent;
    44 import javax.swing.event.HyperlinkListener;
    45 import javax.swing.event.HyperlinkEvent.EventType;
    4623
    4724import org.openstreetmap.josm.Main;
    4825import org.openstreetmap.josm.plugins.PluginDownloader;
    49 import org.openstreetmap.josm.plugins.PluginException;
    50 import org.openstreetmap.josm.plugins.PluginInformation;
    51 import org.openstreetmap.josm.plugins.PluginProxy;
     26import org.openstreetmap.josm.plugins.PluginSelection;
    5227import org.openstreetmap.josm.tools.GBC;
    53 import org.openstreetmap.josm.tools.OpenBrowser;
    54 import org.openstreetmap.josm.tools.XmlObjectParser.Uniform;
    5528
    5629public class PluginPreference implements PreferenceSetting {
    5730
    58     /**
    59      * Only the plugin name, its jar location and the description.
    60      * In other words, this is the minimal requirement the plugin preference page
    61      * needs to show the plugin as available
    62      *
    63      * @author imi
    64      */
    65     public static class PluginDescription implements Comparable<Object> {
    66         // Note: All the following need to be public instance variables of
    67         // type String.  (Plugin description XMLs from the server are parsed
    68         // with tools.XmlObjectParser, which uses reflection to access them.)
    69         public String name;
    70         public String description;
    71         public String resource;
    72         public String version;
    73         public PluginDescription(String name, String description, String resource, String version) {
    74             this.name = name;
    75             this.description = description;
    76             this.resource = resource;
    77             this.version = version;
    78         }
    79         public PluginDescription() {
    80         }
    81         public int compareTo(Object n) {
    82             if(n instanceof PluginDescription)
    83                 return name.compareToIgnoreCase(((PluginDescription)n).name);
    84             return -1;
    85         }
    86     }
    87 
    88     private Map<String, Boolean> pluginMap;
    89     private Map<String, PluginDescription> availablePlugins;
    9031    private JPanel plugin;
    9132    private JPanel pluginPanel = new NoHorizontalScrollPanel(new GridBagLayout());
    9233    private PreferenceDialog gui;
    9334    private JScrollPane pluginPane;
     35    private PluginSelection selection = new PluginSelection();
    9436
    9537    public void addGui(final PreferenceDialog gui) {
     
    10345        morePlugins.addActionListener(new ActionListener(){
    10446            public void actionPerformed(ActionEvent e) {
    105                 int count = PluginDownloader.downloadDescription();
    106                 if (count > 0)
    107                     JOptionPane.showMessageDialog(Main.parent,
    108                         trn("Downloaded plugin information from {0} site",
    109                             "Downloaded plugin information from {0} sites", count, count));
    110                 else
    111                     JOptionPane.showMessageDialog(Main.parent, tr("No plugin information found."));
    112                 refreshPluginPanel(gui);
     47                selection.updateDescription(pluginPanel);
    11348            }
    11449        });
     
    11853        update.addActionListener(new ActionListener(){
    11954            public void actionPerformed(ActionEvent e) {
    120                 update();
    121                 refreshPluginPanel(gui);
     55                selection.update(pluginPanel);
    12256            }
    12357        });
     
    13266        plugin.add(configureSites, GBC.std());
    13367
    134         refreshPluginPanel(gui);
     68        selection.drawPanel(pluginPanel);
    13569    }
    13670
     
    174108        if (answer != JOptionPane.OK_OPTION)
    175109            return;
    176         StringBuilder b = new StringBuilder();
    177         for (int i = 0; i < model.getSize(); ++i) {
    178             b.append(model.getElementAt(i));
    179             if (i < model.getSize()-1)
    180                 b.append(" ");
    181         }
    182         Main.pref.put("pluginmanager.sites", b.toString());
    183     }
    184 
    185     private void update() {
    186         // refresh description
    187         int num = PluginDownloader.downloadDescription();
    188         Boolean done = false;
    189         refreshPluginPanel(gui);
    190 
    191         Set<PluginDescription> toUpdate = new HashSet<PluginDescription>();
    192         StringBuilder toUpdateStr = new StringBuilder();
    193         for (PluginProxy proxy : Main.plugins) {
    194             PluginDescription description = availablePlugins.get(proxy.info.name);
    195             if (description != null && (description.version == null || description.version.equals("")) ?
    196             (proxy.info.version != null && proxy.info.version.equals("")) : !description.version.equals(proxy.info.version)) {
    197                 toUpdate.add(description);
    198                 toUpdateStr.append(description.name+"\n");
    199             }
    200         }
    201         if (toUpdate.isEmpty()) {
    202             JOptionPane.showMessageDialog(Main.parent, tr("All installed plugins are up to date."));
    203             done = true;
    204         } else {
    205             int answer = JOptionPane.showConfirmDialog(Main.parent, tr("Update the following plugins:\n\n{0}",
    206             toUpdateStr.toString()), tr("Update"), JOptionPane.OK_CANCEL_OPTION);
    207             if (answer == JOptionPane.OK_OPTION) {
    208                 PluginDownloader.update(toUpdate);
    209                 done = true;
    210             }
    211         }
    212         if (done && num >= 1)
    213             Main.pref.put("pluginmanager.lastupdate", Long.toString(System.currentTimeMillis()));
    214     }
    215 
    216     private void refreshPluginPanel(final PreferenceDialog gui) {
    217         availablePlugins = getAvailablePlugins();
    218         Collection<String> enabledPlugins = Main.pref.getCollection("plugins", null);
    219 
    220         if (pluginMap == null)
    221             pluginMap = new HashMap<String, Boolean>();
    222         else
    223             // Keep the map in bounds; possibly slightly pointless.
    224             for (final String pname : pluginMap.keySet())
    225                 if (availablePlugins.get(pname) == null) pluginMap.remove(pname);
    226 
    227         pluginPanel.removeAll();
    228 
    229         GridBagConstraints gbc = new GridBagConstraints();
    230         gbc.gridx = 0;
    231         gbc.anchor = GridBagConstraints.NORTHWEST;
    232 
    233         int row = 0;
    234         for (final PluginDescription plugin : availablePlugins.values()) {
    235             boolean enabled = (enabledPlugins != null) && enabledPlugins.contains(plugin.name);
    236             if (pluginMap.get(plugin.name) == null)
    237                 pluginMap.put(plugin.name, enabled);
    238 
    239             String remoteversion = plugin.version;
    240             if ((remoteversion == null) || remoteversion.equals(""))
    241                 remoteversion = tr("unknown");
    242 
    243             String localversion;
    244             PluginInformation p = PluginInformation.findPlugin(plugin.name);
    245             if (p != null) {
    246                 if (p.version != null && !p.version.equals(""))
    247                     localversion = p.version;
    248                 else
    249                     localversion = tr("unknown");
    250                 localversion = " (" + localversion + ")";
    251             } else
    252                 localversion = "";
    253 
    254             final JCheckBox pluginCheck = new JCheckBox(
    255                     tr("{0}: Version {1}{2}", plugin.name, remoteversion, localversion),
    256                     pluginMap.get(plugin.name));
    257             gbc.gridy = row++;
    258             gbc.insets = new Insets(5,5,0,5);
    259             gbc.weighty = 0.1;
    260             gbc.fill = GridBagConstraints.NONE;
    261             pluginPanel.add(pluginCheck, gbc);
    262 
    263             pluginCheck.setToolTipText(plugin.resource != null ? ""+plugin.resource : tr("Plugin bundled with JOSM"));
    264 
    265             JEditorPane description = new JEditorPane();
    266             description.setContentType("text/html");
    267             description.setEditable(false);
    268             description.setText("<html><i>"+(plugin.description==null?tr("no description available"):plugin.description)+"</i></html>");
    269             description.setBorder(BorderFactory.createEmptyBorder(0,20,0,0));
    270             description.setBackground(UIManager.getColor("Panel.background"));
    271             description.addHyperlinkListener(new HyperlinkListener() {
    272                 public void hyperlinkUpdate(HyperlinkEvent e) {
    273                     if(e.getEventType() == EventType.ACTIVATED) {
    274                         OpenBrowser.displayUrl(e.getURL().toString());
    275                     }
    276                 }
    277             });
    278 
    279             gbc.gridy = row++;
    280             gbc.insets = new Insets(3,5,5,5);
    281             gbc.weighty = 0.9;
    282             gbc.weightx = 1.0;
    283             gbc.anchor = GridBagConstraints.WEST;
    284             gbc.fill = GridBagConstraints.HORIZONTAL;
    285             pluginPanel.add(description, gbc);
    286 
    287             pluginCheck.addActionListener(new ActionListener(){
    288                 public void actionPerformed(ActionEvent e) {
    289                     // if user enabled a plugin, it is not loaded but found somewhere on disk: offer to delete jar
    290                     if (pluginCheck.isSelected()) {
    291                         PluginInformation plinfo = PluginInformation.findPlugin(plugin.name);
    292                         if ((PluginInformation.getLoaded(plugin.name) == null) && (plinfo != null)) {
    293                             try {
    294                                 int answer = JOptionPane.showConfirmDialog(Main.parent,
    295                                     tr("Plugin archive already available. Do you want to download the current version by deleting existing archive?\n\n{0}",
    296                                     plinfo.file.getCanonicalPath()), tr("Plugin already exists"), JOptionPane.OK_CANCEL_OPTION);
    297                                 if (answer == JOptionPane.OK_OPTION) {
    298                                     if (!plinfo.file.delete()) {
    299                                         JOptionPane.showMessageDialog(Main.parent, tr("Error deleting plugin file: {0}", plinfo.file.getCanonicalPath()));
    300                                     }
    301                                 }
    302                             } catch (IOException e1) {
    303                                 e1.printStackTrace();
    304                                 JOptionPane.showMessageDialog(Main.parent, tr("Error deleting plugin file: {0}", e1.getMessage()));
    305                             }
    306                         }
    307                     }
    308                     pluginMap.put(plugin.name, pluginCheck.isSelected());
    309                 }
    310             });
    311         }
    312         plugin.updateUI();
    313     }
    314 
    315     private Map<String, PluginDescription> getAvailablePlugins() {
    316         SortedMap<String, PluginDescription> availablePlugins = new TreeMap<String, PluginDescription>(new Comparator<String>(){
    317             public int compare(String o1, String o2) {
    318                 return o1.compareToIgnoreCase(o2);
    319             }
    320         });
    321         for (String location : PluginInformation.getPluginLocations()) {
    322             File[] pluginFiles = new File(location).listFiles();
    323             if (pluginFiles != null) {
    324                 Arrays.sort(pluginFiles);
    325                 for (File f : pluginFiles) {
    326                     if (!f.isFile())
    327                         continue;
    328                     if (f.getName().endsWith(".jar")) {
    329                         try {
    330                             PluginInformation info = new PluginInformation(f);
    331                             if (!availablePlugins.containsKey(info.name))
    332                                 availablePlugins.put(info.name, new PluginDescription(
    333                                     info.name,
    334                                     info.description,
    335                                     PluginInformation.fileToURL(f).toString(),
    336                                     info.version));
    337                         } catch (PluginException x) {
    338                         }
    339                     } else if (f.getName().matches("^[0-9]+-site.*\\.xml$")) {
    340                         try {
    341                             Uniform<PluginDescription> parser = new Uniform<PluginDescription>(new FileReader(f), "plugin", PluginDescription.class);
    342                             for (PluginDescription pd : parser)
    343                                 if (!availablePlugins.containsKey(pd.name))
    344                                     availablePlugins.put(pd.name, pd);
    345                         } catch (Exception e) {
    346                             e.printStackTrace();
    347                             JOptionPane.showMessageDialog(Main.parent, tr("Error reading plugin information file: {0}", f.getName()));
    348                         }
    349                     }
    350                 }
    351             }
    352         }
    353         for (PluginProxy proxy : Main.plugins)
    354             if (!availablePlugins.containsKey(proxy.info.name))
    355                 availablePlugins.put(proxy.info.name, new PluginDescription(
    356                         proxy.info.name,
    357                         proxy.info.description,
    358                         proxy.info.file == null ? null :
    359                             PluginInformation.fileToURL(proxy.info.file).toString(),
    360                         proxy.info.version));
    361         return availablePlugins;
     110        Collection<String> sites = new LinkedList<String>();
     111        for (int i = 0; i < model.getSize(); ++i)
     112            sites.add((String)model.getElementAt(i));
     113        PluginDownloader.setSites(sites);
    362114    }
    363115
    364116    public boolean ok() {
    365         Collection<PluginDescription> toDownload = new LinkedList<PluginDescription>();
    366         String msg = "";
    367         for (Entry<String, Boolean> entry : pluginMap.entrySet()) {
    368             if (entry.getValue() && PluginInformation.findPlugin(entry.getKey()) == null) {
    369                 toDownload.add(availablePlugins.get(entry.getKey()));
    370                 msg += entry.getKey() + "\n";
    371             }
    372         }
    373         if (!toDownload.isEmpty()) {
    374             int answer = JOptionPane.showConfirmDialog(Main.parent,
    375                     tr("Download the following plugins?\n\n{0}", msg),
    376                     tr("Download missing plugins"),
    377                     JOptionPane.YES_NO_OPTION);
    378             if (answer != JOptionPane.OK_OPTION)
    379                 for (PluginDescription pd : toDownload)
    380                     pluginMap.put(pd.name, false);
    381             else
    382                 for (PluginDescription pd : toDownload)
    383                     if (!PluginDownloader.downloadPlugin(pd))
    384                         pluginMap.put(pd.name, false);
     117        return selection.finish();
     118    }
    385119
    386         }
    387         LinkedList<String> plugins = new LinkedList<String>();
    388         for (Map.Entry<String, Boolean> d : pluginMap.entrySet()) {
    389             if (d.getValue())
    390                 plugins.add(d.getKey());
    391         }
    392 
    393         Collections.sort(plugins);
    394         return Main.pref.putCollection("plugins", plugins);
    395     }
    396    
    397120    class NoHorizontalScrollPanel extends JPanel implements Scrollable {
    398121        public NoHorizontalScrollPanel(GridBagLayout gridBagLayout) {
  • trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceDialog.java

    r1180 r1326  
    2222
    2323import org.openstreetmap.josm.Main;
    24 import org.openstreetmap.josm.plugins.PluginProxy;
     24import org.openstreetmap.josm.plugins.PluginHandler;
     25import org.openstreetmap.josm.tools.BugReportExceptionHandler;
    2526import org.openstreetmap.josm.tools.GBC;
    2627import org.openstreetmap.josm.tools.I18n;
     
    112113            } catch (SecurityException e) {
    113114                it.remove();
     115            } catch (Throwable e) {
     116                /* allow to change most settings even if e.g. a plugin fails */
     117                BugReportExceptionHandler.handleException(e);
    114118            }
    115119        }
     
    133137        settings.add(new ShortcutPreference());
    134138
    135         for (PluginProxy plugin : Main.plugins) {
    136             PreferenceSetting p = plugin.getPreferenceSetting();
    137             if (p != null)
    138                 settings.add(p);
    139         }
     139        PluginHandler.getPreferenceSetting(settings);
    140140
    141141        // always the last: advanced tab
Note: See TracChangeset for help on using the changeset viewer.