Changeset 2689

Show
Ignore:
Timestamp:
28.12.2009 00:16:04 (8 months ago)
Author:
Gubaer
Message:

new: Changeset Cache Manager for querying, downloading, browsing, and managing changesets within JOSM. See also Changeset Manager and Changeset Query Dialog

Location:
trunk/src/org/openstreetmap/josm/gui
Files:
21 added
10 modified
1 moved

Legend:

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

    r2578 r2689  
    2020import org.openstreetmap.josm.data.osm.Relation; 
    2121import org.openstreetmap.josm.data.osm.Way; 
     22import org.openstreetmap.josm.data.osm.history.HistoryNameFormatter; 
     23import org.openstreetmap.josm.data.osm.history.HistoryNode; 
     24import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive; 
     25import org.openstreetmap.josm.data.osm.history.HistoryRelation; 
     26import org.openstreetmap.josm.data.osm.history.HistoryWay; 
    2227 
    2328/** 
     
    2530 * 
    2631 */ 
    27 public class DefaultNameFormatter implements NameFormatter { 
     32public class DefaultNameFormatter implements NameFormatter, HistoryNameFormatter { 
    2833 
    2934    static private DefaultNameFormatter instance; 
     
    238243        return sb.toString(); 
    239244    } 
     245 
     246 
     247    /** 
     248     * Decorates the name of primitive with its id, if the preference 
     249     * <tt>osm-primitives.showid</tt> is set. 
     250     *  
     251     * The id is append to the {@see StringBuilder} passed in in <code>name</code>. 
     252     * 
     253     * @param name  the name without the id 
     254     * @param primitive the primitive 
     255     */ 
     256    protected void decorateNameWithId(StringBuilder name, HistoryOsmPrimitive primitive) { 
     257        if (Main.pref.getBoolean("osm-primitives.showid")) { 
     258            name.append(tr(" [id: {0}]", primitive.getId())); 
     259        } 
     260    } 
     261 
     262 
     263    /** 
     264     * Formats a name for a history node 
     265     * 
     266     * @param node the node 
     267     * @return the name 
     268     */ 
     269    public String format(HistoryNode node) { 
     270        StringBuilder sb = new StringBuilder(); 
     271        String name; 
     272        if (Main.pref.getBoolean("osm-primitives.localize-name", true)) { 
     273            name = node.getLocalName(); 
     274        } else { 
     275            name = node.getName(); 
     276        } 
     277        if (name == null) { 
     278            sb.append(node.getId()); 
     279        } else { 
     280            sb.append(name); 
     281        } 
     282        sb.append(" (") 
     283        .append(node.getCoords().latToString(CoordinateFormat.getDefaultFormat())) 
     284        .append(", ") 
     285        .append(node.getCoords().lonToString(CoordinateFormat.getDefaultFormat())) 
     286        .append(")"); 
     287        decorateNameWithId(sb, node); 
     288        return sb.toString(); 
     289    } 
     290 
     291    /** 
     292     * Formats a name for a way 
     293     * 
     294     * @param way the way 
     295     * @return the name 
     296     */ 
     297    public String format(HistoryWay way) { 
     298        StringBuilder sb = new StringBuilder(); 
     299        String name; 
     300        if (Main.pref.getBoolean("osm-primitives.localize-name", true)) { 
     301            name = way.getLocalName(); 
     302        } else { 
     303            name = way.getName(); 
     304        } 
     305        if (name != null) { 
     306            sb.append(name); 
     307        } 
     308        if (sb.length() == 0 && way.get("ref") != null) { 
     309            sb.append(way.get("ref")); 
     310        } 
     311        if (sb.length() == 0) { 
     312            sb.append( 
     313                    (way.get("highway") != null) ? tr("highway") : 
     314                        (way.get("railway") != null) ? tr("railway") : 
     315                            (way.get("waterway") != null) ? tr("waterway") : 
     316                                (way.get("landuse") != null) ? tr("landuse") : "" 
     317            ); 
     318        } 
     319 
     320        int nodesNo = way.isClosed() ? way.getNumNodes() -1 : way.getNumNodes(); 
     321        String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo); 
     322        sb.append((sb.length() > 0) ? " ("+nodes+")" : nodes); 
     323        decorateNameWithId(sb, way); 
     324        return sb.toString(); 
     325    } 
     326 
     327 
     328    /** 
     329     * Formats a name for a {@see HistoryRelation}) 
     330     * 
     331     * @param relation the relation 
     332     * @return the name 
     333     */ 
     334    public String format(HistoryRelation relation) { 
     335        StringBuilder sb = new StringBuilder(); 
     336        if (relation.get("type") != null) { 
     337            sb.append(relation.get("type")); 
     338        } else { 
     339            sb.append(tr("relation")); 
     340        } 
     341        sb.append(" ("); 
     342        String nameTag = null; 
     343        Set<String> namingTags = new HashSet<String>(getNamingtagsForRelations()); 
     344        for (String n : relation.getTags().keySet()) { 
     345            // #3328: "note " and " note" are name tags too 
     346            if (namingTags.contains(n.trim())) { 
     347                if (Main.pref.getBoolean("osm-primitives.localize-name", true)) { 
     348                    nameTag = relation.getLocalName(); 
     349                } else { 
     350                    nameTag = relation.getName(); 
     351                } 
     352                if (nameTag == null) { 
     353                    nameTag = relation.get(n); 
     354                } 
     355            } 
     356            if (nameTag != null) { 
     357                break; 
     358            } 
     359        } 
     360        if (nameTag == null) { 
     361            sb.append(Long.toString(relation.getId())).append(", "); 
     362        } else { 
     363            sb.append("\"").append(nameTag).append("\", "); 
     364        } 
     365 
     366        int mbno = relation.getNumMembers(); 
     367        sb.append(trn("{0} member", "{0} members", mbno, mbno)).append(")"); 
     368 
     369        decorateNameWithId(sb, relation); 
     370        return sb.toString(); 
     371    } 
     372 
     373    /** 
     374     * Builds a default tooltip text for an HistoryOsmPrimitive <code>primitive</code>. 
     375     *  
     376     * @param primitive the primitmive 
     377     * @return the tooltip text 
     378     */ 
     379    public String buildDefaultToolTip(HistoryOsmPrimitive primitive) { 
     380        StringBuilder sb = new StringBuilder(); 
     381        sb.append("<html>"); 
     382        sb.append("<strong>id</strong>=") 
     383        .append(primitive.getId()) 
     384        .append("<br>"); 
     385        ArrayList<String> keyList = new ArrayList<String>(primitive.getTags().keySet()); 
     386        Collections.sort(keyList); 
     387        for (int i = 0; i < keyList.size(); i++) { 
     388            if (i > 0) { 
     389                sb.append("<br>"); 
     390            } 
     391            String key = keyList.get(i); 
     392            sb.append("<strong>") 
     393            .append(key) 
     394            .append("</strong>") 
     395            .append("="); 
     396            String value = primitive.get(key); 
     397            while(value.length() != 0) { 
     398                sb.append(value.substring(0,Math.min(50, value.length()))); 
     399                if (value.length() > 50) { 
     400                    sb.append("<br>"); 
     401                    value = value.substring(50); 
     402                } else { 
     403                    value = ""; 
     404                } 
     405            } 
     406        } 
     407        sb.append("</html>"); 
     408        return sb.toString(); 
     409    } 
    240410} 
  • trunk/src/org/openstreetmap/josm/gui/MainMenu.java

    r2682 r2689  
    2121import org.openstreetmap.josm.actions.AlignInLineAction; 
    2222import org.openstreetmap.josm.actions.AutoScaleAction; 
     23import org.openstreetmap.josm.actions.ChangesetManagerToggleAction; 
    2324import org.openstreetmap.josm.actions.CloseChangesetAction; 
    2425import org.openstreetmap.josm.actions.CombineWayAction; 
     
    251252        add(viewMenu, new ZoomOutAction()); 
    252253        viewMenu.addSeparator(); 
    253         for (String mode : AutoScaleAction.modes) { 
     254        for (String mode : AutoScaleAction.MODES) { 
    254255            JosmAction autoScaleAction = new AutoScaleAction(mode); 
    255256            add(viewMenu, autoScaleAction); 
    256257        } 
     258 
     259        // -- changeset manager toggle action 
     260        ChangesetManagerToggleAction changesetManagerToggleAction = new ChangesetManagerToggleAction(); 
     261        final JCheckBoxMenuItem mi = new JCheckBoxMenuItem(changesetManagerToggleAction); 
     262        viewMenu.addSeparator(); 
     263        viewMenu.add(mi); 
     264        mi.setAccelerator(changesetManagerToggleAction.getShortcut().getKeyStroke()); 
     265        changesetManagerToggleAction.addButtonModel(mi.getModel()); 
    257266 
    258267        // -- fullscreen toggle action 
  • trunk/src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java

    r2512 r2689  
    33 
    44import java.awt.Component; 
    5 import java.util.ArrayList; 
    6 import java.util.Collections; 
    75 
    86import javax.swing.DefaultListCellRenderer; 
     
    1513 
    1614import org.openstreetmap.josm.data.osm.OsmPrimitive; 
    17 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
     15import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive; 
    1816import org.openstreetmap.josm.tools.ImageProvider; 
    1917 
     
    2725 */ 
    2826public class OsmPrimitivRenderer implements ListCellRenderer, TableCellRenderer { 
     27    private DefaultNameFormatter formatter = new DefaultNameFormatter(); 
     28 
    2929    /** 
    3030     * Default list cell renderer - delegate for ListCellRenderer operation 
     
    5050    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
    5151        Component def = defaultTableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
    52         return renderer(def, (OsmPrimitive) value); 
     52        if (value instanceof OsmPrimitive) 
     53            return renderer(def, (OsmPrimitive) value); 
     54        else if (value instanceof HistoryOsmPrimitive) 
     55            return renderer(def, (HistoryOsmPrimitive) value); 
     56        else 
     57            return def; 
    5358    } 
    5459 
     
    6368        if (def != null && value != null && def instanceof JLabel) { 
    6469            ((JLabel)def).setText(value.getDisplayName(DefaultNameFormatter.getInstance())); 
    65             ((JLabel)def).setIcon(ImageProvider.get(OsmPrimitiveType.from(value))); 
    66             ((JLabel)def).setToolTipText(buildToolTipText(value)); 
     70            ((JLabel)def).setIcon(ImageProvider.get(value.getType())); 
     71            ((JLabel)def).setToolTipText(formatter.buildDefaultToolTip(value)); 
    6772        } 
    6873        return def; 
     
    7075 
    7176    /** 
    72      * build the tool tip text for an {@see OsmPrimitive}. It consist of the formatted 
    73      * key/value pairs for this primitive. 
    74      * 
    75      * @param primitive 
    76      * @return the tool tip text 
     77     * Internal method that stuffs information into the rendering component 
     78     * provided that it's a kind of JLabel. 
     79     * @param def the rendering component 
     80     * @param value the HistoryOsmPrimtive to render 
     81     * @return the modified rendering component 
    7782     */ 
    78     public String buildToolTipText(OsmPrimitive primitive) { 
    79         StringBuilder sb = new StringBuilder(); 
    80  
    81         sb.append("<html>"); 
    82         // show the id 
    83         // 
    84         sb.append("<strong>id</strong>=") 
    85         .append(primitive.getId()) 
    86         .append("<br>"); 
    87  
    88         // show the key/value-pairs, sorted by key 
    89         // 
    90         ArrayList<String> keyList = new ArrayList<String>(primitive.keySet()); 
    91         Collections.sort(keyList); 
    92         for (int i = 0; i < keyList.size(); i++) { 
    93             if (i > 0) { 
    94                 sb.append("<br>"); 
    95             } 
    96             String key = keyList.get(i); 
    97             sb.append("<strong>") 
    98             .append(key) 
    99             .append("</strong>") 
    100             .append("="); 
    101             // make sure long values are split into several rows. Otherwise 
    102             // the tool tip window can become to wide 
    103             // 
    104             String value = primitive.get(key); 
    105             while(value.length() != 0) { 
    106                 sb.append(value.substring(0,Math.min(50, value.length()))); 
    107                 if (value.length() > 50) { 
    108                     sb.append("<br>"); 
    109                     value = value.substring(50); 
    110                 } else { 
    111                     value = ""; 
    112                 } 
    113             } 
     83    private Component renderer(Component def, HistoryOsmPrimitive value) { 
     84        if (def != null && value != null && def instanceof JLabel) { 
     85            ((JLabel)def).setText(value.getDisplayName(DefaultNameFormatter.getInstance())); 
     86            ((JLabel)def).setIcon(ImageProvider.get(value.getType())); 
     87            ((JLabel)def).setToolTipText(formatter.buildDefaultToolTip(value)); 
    11488        } 
    115         sb.append("</html>"); 
    116         return sb.toString(); 
     89        return def; 
    11790    } 
    11891} 
  • trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java

    r2613 r2689  
    22package org.openstreetmap.josm.gui; 
    33 
     4import java.awt.Component; 
    45import java.awt.EventQueue; 
    56import java.io.IOException; 
     
    1213import org.openstreetmap.josm.gui.progress.ProgressMonitor.CancelListener; 
    1314import org.openstreetmap.josm.io.OsmTransferException; 
     15import org.openstreetmap.josm.tools.CheckParameterUtil; 
    1416import org.xml.sax.SAXException; 
    1517 
     
    4648    public PleaseWaitRunnable(String title, boolean ignoreException) { 
    4749        this(title, new PleaseWaitProgressMonitor(title), ignoreException); 
     50    } 
     51 
     52    /** 
     53     * Create the runnable object with a given message for the user 
     54     * 
     55     * @param parent the parent component for the please wait dialog. Must not be null. 
     56     * @param title message for the user 
     57     * @param ignoreException If true, exception will be propagated to calling code. If false then 
     58     * exception will be thrown directly in EDT. When this runnable is executed using executor framework 
     59     * then use false unless you read result of task (because exception will get lost if you don't) 
     60     * @throws IllegalArgumentException thrown if parent is null 
     61     */ 
     62    public PleaseWaitRunnable(Component parent, String title, boolean ignoreException) throws IllegalArgumentException{ 
     63        CheckParameterUtil.ensureParameterNotNull(parent, "parent"); 
     64        this.title = title; 
     65        this.progressMonitor = new PleaseWaitProgressMonitor(parent, title); 
     66        this.ignoreException = ignoreException; 
    4867    } 
    4968 
  • trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java

    r2655 r2689  
    66import java.awt.BorderLayout; 
    77import java.awt.FlowLayout; 
     8import java.awt.Frame; 
    89import java.awt.event.ActionEvent; 
    910import java.awt.event.ItemEvent; 
     
    1112import java.awt.event.MouseAdapter; 
    1213import java.awt.event.MouseEvent; 
     14import java.util.Collection; 
    1315import java.util.HashSet; 
    1416import java.util.List; 
    1517import java.util.Set; 
     18import java.util.concurrent.ExecutionException; 
     19import java.util.concurrent.Future; 
    1620 
    1721import javax.swing.AbstractAction; 
     
    3741import org.openstreetmap.josm.gui.MapFrame; 
    3842import org.openstreetmap.josm.gui.MapView; 
     43import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetCacheManager; 
     44import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetHeaderDownloadTask; 
    3945import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetInSelectionListModel; 
    4046import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetListCellRenderer; 
    4147import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetListModel; 
    4248import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetsInActiveDataLayerListModel; 
    43 import org.openstreetmap.josm.gui.dialogs.changeset.DownloadChangesetsTask; 
    4449import org.openstreetmap.josm.gui.help.HelpUtil; 
    4550import org.openstreetmap.josm.gui.io.CloseChangesetTask; 
     51import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher; 
     52import org.openstreetmap.josm.tools.BugReportExceptionHandler; 
    4653import org.openstreetmap.josm.tools.ImageProvider; 
    4754import org.openstreetmap.josm.tools.OpenBrowser; 
     
    7582    private ShowChangesetInfoAction showChangsetInfoAction; 
    7683    private CloseOpenChangesetsAction closeChangesetAction; 
     84    private LaunchChangesetManagerAction launchChangesetManagerAction; 
    7785 
    7886 
     
    93101        lstInActiveDataLayer.setCellRenderer(new ChangesetListCellRenderer()); 
    94102 
    95         ChangesetCache.getInstance().addChangesetCacheListener(inSelectionModel); 
    96         MapView.addLayerChangeListener(inSelectionModel); 
    97         DataSet.selListeners.add(inSelectionModel); 
    98  
    99         ChangesetCache.getInstance().addChangesetCacheListener(inActiveDataLayerModel); 
    100  
    101103        DblClickHandler dblClickHandler = new DblClickHandler(); 
    102104        lstInSelection.addMouseListener(dblClickHandler); 
    103105        lstInActiveDataLayer.addMouseListener(dblClickHandler); 
    104106 
    105         PopupMenuLauncher popupMenuLauncher = new PopupMenuLauncher(); 
     107        ChangesetPopupMenuLauncher popupMenuLauncher = new ChangesetPopupMenuLauncher(); 
    106108        lstInSelection.addMouseListener(popupMenuLauncher); 
    107109        lstInActiveDataLayer.addMouseListener(popupMenuLauncher); 
    108110    } 
    109111 
     112    protected void registerAsListener() { 
     113        // let the model for changesets in the current selection listen to various 
     114        // events 
     115        ChangesetCache.getInstance().addChangesetCacheListener(inSelectionModel); 
     116        MapView.addEditLayerChangeListener(inSelectionModel); 
     117        DataSet.selListeners.add(inSelectionModel); 
     118 
     119 
     120        // let the model for changesets in the current layer listen to various 
     121        // events and bootstrap it's content 
     122        ChangesetCache.getInstance().addChangesetCacheListener(inActiveDataLayerModel); 
     123        MapView.addEditLayerChangeListener(inActiveDataLayerModel); 
     124        if (Main.main.getEditLayer() != null) { 
     125            Main.main.getEditLayer().data.addDataSetListener(inActiveDataLayerModel); 
     126            inActiveDataLayerModel.initFromDataSet(Main.main.getEditLayer().data); 
     127            inSelectionModel.initFromPrimitives(Main.main.getEditLayer().data.getSelected()); 
     128        } 
     129    } 
     130 
     131    protected void unregisterAsListener() { 
     132        // remove the list model for the current edit layer as listener 
     133        // 
     134        ChangesetCache.getInstance().removeChangesetCacheListener(inActiveDataLayerModel); 
     135        MapView.removeEditLayerChangeListener(inActiveDataLayerModel); 
     136        if (Main.main.getEditLayer() != null) { 
     137            Main.main.getEditLayer().data.removeDataSetListener(inActiveDataLayerModel); 
     138        } 
     139 
     140        // remove the list model for the changesets in the current selection as 
     141        // listener 
     142        // 
     143        MapView.removeEditLayerChangeListener(inSelectionModel); 
     144        DataSet.selListeners.remove(inSelectionModel); 
     145    } 
     146 
    110147    @Override 
    111148    public void tearDown() { 
    112         ChangesetCache.getInstance().removeChangesetCacheListener(inActiveDataLayerModel); 
    113         MapView.removeLayerChangeListener(inSelectionModel); 
    114         DataSet.selListeners.remove(inSelectionModel); 
     149        unregisterAsListener(); 
    115150    } 
    116151 
    117152    @Override 
    118153    public void showNotify() { 
     154        registerAsListener(); 
    119155        DatasetEventManager.getInstance().addDatasetListener(inActiveDataLayerModel, true); 
    120156    } 
     
    122158    @Override 
    123159    public void hideNotify() { 
     160        unregisterAsListener(); 
    124161        DatasetEventManager.getInstance().removeDatasetListener(inActiveDataLayerModel); 
    125162    } 
     
    179216        lstInActiveDataLayer.getSelectionModel().addListSelectionListener(showChangsetInfoAction); 
    180217        lstInSelection.getSelectionModel().addListSelectionListener(showChangsetInfoAction); 
     218 
     219        // -- launch changeset manager action 
     220        launchChangesetManagerAction = new LaunchChangesetManagerAction(); 
     221        tp.add(launchChangesetManagerAction); 
     222        cbInSelectionOnly.addItemListener(launchChangesetManagerAction); 
     223        lstInActiveDataLayer.getSelectionModel().addListSelectionListener(launchChangesetManagerAction); 
     224        lstInSelection.getSelectionModel().addListSelectionListener(launchChangesetManagerAction); 
    181225 
    182226        pnl.add(tp); 
     
    334378            if (sel.isEmpty()) 
    335379                return; 
    336             DownloadChangesetsTask task = new DownloadChangesetsTask(sel); 
     380            ChangesetHeaderDownloadTask task = new ChangesetHeaderDownloadTask(sel); 
    337381            Main.worker.submit(task); 
    338382        } 
     
    424468    } 
    425469 
    426     class PopupMenuLauncher extends MouseAdapter { 
    427         protected void showPopup(MouseEvent evt) { 
    428             if (!evt.isPopupTrigger()) 
    429                 return; 
     470    /** 
     471     * Show information about the currently selected changesets 
     472     *  
     473     */ 
     474    class LaunchChangesetManagerAction extends AbstractAction implements ListSelectionListener, ItemListener { 
     475        public LaunchChangesetManagerAction() { 
     476            putValue(NAME, tr("Details")); 
     477            putValue(SHORT_DESCRIPTION, tr("Opens the Changeset Manager window for the selected changesets")); 
     478            putValue(SMALL_ICON, ImageProvider.get("dialogs/changeset", "changesetmanager")); 
     479            updateEnabledState(); 
     480        } 
     481 
     482        protected void launchChangesetManager(Collection<Integer> toSelect) { 
     483            ChangesetCacheManager cm = ChangesetCacheManager.getInstance(); 
     484            if (cm.isVisible()) { 
     485                cm.setExtendedState(Frame.NORMAL); 
     486                cm.toFront(); 
     487                cm.requestFocus(); 
     488            } else { 
     489                cm.setVisible(true); 
     490                cm.toFront(); 
     491                cm.requestFocus(); 
     492            } 
     493            cm.setSelectedChangesetsById(toSelect); 
     494        } 
     495 
     496        public void actionPerformed(ActionEvent arg0) { 
     497            ChangesetListModel model = getCurrentChangesetListModel(); 
     498            Set<Integer> sel = model.getSelectedChangesetIds(); 
     499            if (sel.isEmpty()) 
     500                return; 
     501            final Set<Integer> toDownload = new HashSet<Integer>(); 
     502            ChangesetCache cc = ChangesetCache.getInstance(); 
     503            for (int id: sel) { 
     504                if (!cc.contains(id)) { 
     505                    toDownload.add(id); 
     506                } 
     507            } 
     508 
     509            final ChangesetHeaderDownloadTask task; 
     510            final Future<?> future; 
     511            if (toDownload.isEmpty()) { 
     512                task = null; 
     513                future = null; 
     514            } else { 
     515                task = new ChangesetHeaderDownloadTask(toDownload); 
     516                future = Main.worker.submit(task); 
     517            } 
     518 
     519            Runnable r = new Runnable() { 
     520                public void run() { 
     521                    // first, wait for the download task to finish, if a download 
     522                    // task was launched 
     523                    if (future != null) { 
     524                        try { 
     525                            future.get(); 
     526                        } catch(InterruptedException e) { 
     527                            e.printStackTrace(); 
     528                        } catch(ExecutionException e){ 
     529                            e.printStackTrace(); 
     530                            BugReportExceptionHandler.handleException(e.getCause()); 
     531                            return; 
     532                        } 
     533                    } 
     534                    if (task != null) { 
     535                        if (task.isCanceled()) 
     536                            // don't launch the changeset manager if the download task 
     537                            // was canceled 
     538                            return; 
     539                        if (task.isFailed()) { 
     540                            toDownload.clear(); 
     541                        } 
     542                    } 
     543                    // launch the task 
     544                    launchChangesetManager(toDownload); 
     545                } 
     546            }; 
     547            Main.worker.submit(r); 
     548        } 
     549 
     550        protected void updateEnabledState() { 
     551            setEnabled(getCurrentChangesetList().getSelectedIndices().length > 0); 
     552        } 
     553 
     554        public void itemStateChanged(ItemEvent arg0) { 
     555            updateEnabledState(); 
     556        } 
     557 
     558        public void valueChanged(ListSelectionEvent e) { 
     559            updateEnabledState(); 
     560        } 
     561    } 
     562 
     563 
     564    class ChangesetPopupMenuLauncher extends PopupMenuLauncher { 
     565        @Override 
     566        public void launch(MouseEvent evt) { 
    430567            JList lst = getCurrentChangesetList(); 
    431568            if (lst.getSelectedIndices().length == 0) { 
     
    438575            popup.show(lst, evt.getX(), evt.getY()); 
    439576 
    440         } 
    441         @Override 
    442         public void mouseClicked(MouseEvent evt) { 
    443             showPopup(evt); 
    444         } 
    445         @Override 
    446         public void mousePressed(MouseEvent evt) { 
    447             showPopup(evt); 
    448         } 
    449         @Override 
    450         public void mouseReleased(MouseEvent evt) { 
    451             showPopup(evt); 
    452577        } 
    453578    } 
  • trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetHeaderDownloadTask.java

    r2613 r2689  
    44import static org.openstreetmap.josm.tools.I18n.tr; 
    55 
     6import java.awt.Component; 
    67import java.io.IOException; 
     8import java.lang.reflect.InvocationTargetException; 
    79import java.util.Collection; 
     10import java.util.Collections; 
    811import java.util.HashSet; 
    9 import java.util.List; 
    1012import java.util.Set; 
    1113 
    1214import javax.swing.SwingUtilities; 
    1315 
     16import org.openstreetmap.josm.Main; 
    1417import org.openstreetmap.josm.data.osm.Changeset; 
    1518import org.openstreetmap.josm.data.osm.ChangesetCache; 
     
    1821import org.openstreetmap.josm.io.OsmServerChangesetReader; 
    1922import org.openstreetmap.josm.io.OsmTransferException; 
     23import org.openstreetmap.josm.tools.BugReportExceptionHandler; 
     24import org.openstreetmap.josm.tools.CheckParameterUtil; 
     25import org.openstreetmap.josm.tools.ExceptionUtil; 
    2026import org.xml.sax.SAXException; 
    2127 
    22 public class DownloadChangesetsTask extends PleaseWaitRunnable{ 
     28/** 
     29 * This is an asynchronous task for downloading a collection of changests from the OSM 
     30 * server. 
     31 *  
     32 * The  task only downloads the changeset properties without the changeset content. It 
     33 * updates the global {@see ChangesetCache}. 
     34 *  
     35 */ 
     36public class ChangesetHeaderDownloadTask extends PleaseWaitRunnable implements ChangesetDownloadTask{ 
     37 
     38    /** 
     39     * Builds a download task from for a collection of changesets. 
     40     *  
     41     * Ignores null values and changesets with {@see Changeset#isNew()} == true. 
     42     *  
     43     * @param changesets the collection of changesets. Assumes an empty collection if null. 
     44     * @return the download task 
     45     */ 
     46    static public ChangesetHeaderDownloadTask buildTaskForChangesets(Collection<Changeset> changesets) { 
     47        return buildTaskForChangesets(Main.parent, changesets); 
     48    } 
     49 
     50    /** 
     51     * Builds a download task from for a collection of changesets. 
     52     *  
     53     * Ignores null values and changesets with {@see Changeset#isNew()} == true. 
     54     *  
     55     * @param parent the parent component relative to which the {@see PleaseWaitDialog} is displayed. 
     56     * Must not be null. 
     57     * @param changesets the collection of changesets. Assumes an empty collection if null. 
     58     * @return the download task 
     59     * @throws IllegalArgumentException thrown if parent is null 
     60     */ 
     61    static public ChangesetHeaderDownloadTask buildTaskForChangesets(Component parent, Collection<Changeset> changesets) { 
     62        CheckParameterUtil.ensureParameterNotNull(parent, "parent"); 
     63        if (changesets == null) { 
     64            changesets = Collections.emptyList(); 
     65        } 
     66 
     67        HashSet<Integer> ids = new HashSet<Integer>(); 
     68        for (Changeset cs: changesets) { 
     69            if (cs == null || cs.isNew()) { 
     70                continue; 
     71            } 
     72            ids.add(cs.getId()); 
     73        } 
     74        if (parent == null) 
     75            return new ChangesetHeaderDownloadTask(ids); 
     76        else 
     77            return new ChangesetHeaderDownloadTask(parent, ids); 
     78 
     79    } 
     80 
    2381 
    2482    private Set<Integer> idsToDownload; 
    2583    private OsmServerChangesetReader reader; 
    26     private boolean cancelled; 
     84    private boolean canceled; 
    2785    private Exception lastException; 
    28     private List<Changeset> downloadedChangesets; 
    29  
    30     public DownloadChangesetsTask(Collection<Integer> ids) { 
    31         super(tr("Download changesets")); 
     86    private Set<Changeset> downloadedChangesets; 
     87 
     88    protected void init(Collection<Integer> ids) { 
     89        if (ids == null) { 
     90            ids = Collections.emptyList(); 
     91        } 
    3292        idsToDownload = new HashSet<Integer>(); 
    3393        if (ids == null ||  ids.isEmpty()) 
     
    41101    } 
    42102 
     103    /** 
     104     * Creates the download task for a collection of changeset ids. Uses a {@see PleaseWaitDialog} 
     105     * whose parent is {@see Main#parent}. 
     106     *  
     107     * Null ids or or ids <= 0 in the id collection are ignored. 
     108     *  
     109     * @param ids the collection of ids. Empty collection assumed if null. 
     110     */ 
     111    public ChangesetHeaderDownloadTask(Collection<Integer> ids) { 
     112        // parent for dialog is Main.parent 
     113        super(tr("Download changesets"), false /* don't ignore exceptions */); 
     114        init(ids); 
     115    } 
     116 
     117    /** 
     118     * Creates the download task for a collection of changeset ids. Uses a {@see PleaseWaitDialog} 
     119     * whose parent is the parent window of <code>dialogParent</code>. 
     120     *  
     121     * Null ids or or ids <= 0 in the id collection are ignored. 
     122     *  
     123     * @param dialogParent the parent reference component for the {@see PleaseWaitDialog}. Must not be null. 
     124     * @param ids the collection of ids. Empty collection assumed if null. 
     125     * @throws IllegalArgumentException thrown if dialogParent is null 
     126     */ 
     127    public ChangesetHeaderDownloadTask(Component dialogParent, Collection<Integer> ids) throws IllegalArgumentException{ 
     128        super(dialogParent,tr("Download changesets"), false /* don't ignore exceptions */); 
     129        init(ids); 
     130    } 
     131 
    43132    @Override 
    44133    protected void cancel() { 
    45         cancelled = true; 
     134        canceled = true; 
    46135        synchronized (this) { 
    47136            if (reader != null) { 
     
    53142    @Override 
    54143    protected void finish() { 
    55         if (cancelled) 
     144        if (canceled) 
    56145            return; 
    57146        if (lastException != null) { 
     
    67156            r.run(); 
    68157        } else { 
    69             SwingUtilities.invokeLater(r); 
     158            try { 
     159                SwingUtilities.invokeAndWait(r); 
     160            } catch(InterruptedException e) { 
     161                e.printStackTrace(); 
     162            } catch(InvocationTargetException e) { 
     163                Throwable t = e.getTargetException(); 
     164                if (t instanceof RuntimeException) { 
     165                    BugReportExceptionHandler.handleException(t); 
     166                } else if (t instanceof Exception){ 
     167                    ExceptionUtil.explainException(e); 
     168                } else { 
     169                    BugReportExceptionHandler.handleException(t); 
     170                } 
     171            } 
    70172        } 
    71173    } 
     
    77179                reader = new OsmServerChangesetReader(); 
    78180            } 
    79             downloadedChangesets = reader.readChangesets(idsToDownload, getProgressMonitor().createSubTaskMonitor(0, false)); 
    80         } catch(Exception e) { 
    81             if (cancelled) 
     181            downloadedChangesets = new HashSet<Changeset>(); 
     182            downloadedChangesets.addAll(reader.readChangesets(idsToDownload, getProgressMonitor().createSubTaskMonitor(0, false))); 
     183        } catch(OsmTransferException e) { 
     184            if (canceled) 
    82185                // ignore exception if cancelled 
    83186                return; 
    84             if (e instanceof RuntimeException) 
    85                 throw (RuntimeException)e; 
     187            // remember other exceptions 
    86188            lastException = e; 
    87189        } 
    88190    } 
     191 
     192    /* ------------------------------------------------------------------------------- */ 
     193    /* interface ChangesetDownloadTask                                                 */ 
     194    /* ------------------------------------------------------------------------------- */ 
     195    public Set<Changeset> getDownloadedChangesets() { 
     196        return downloadedChangesets; 
     197    } 
     198 
     199    public boolean isCanceled() { 
     200        return canceled; 
     201    } 
     202 
     203    public boolean isFailed() { 
     204        return lastException != null; 
     205    } 
    89206} 
  • trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetInSelectionListModel.java

    r2626 r2689  
    88import org.openstreetmap.josm.data.SelectionChangedListener; 
    99import org.openstreetmap.josm.data.osm.OsmPrimitive; 
    10 import org.openstreetmap.josm.gui.MapView; 
    11 import org.openstreetmap.josm.gui.layer.Layer; 
     10import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener; 
    1211import org.openstreetmap.josm.gui.layer.OsmDataLayer; 
    1312 
    14 public class ChangesetInSelectionListModel extends ChangesetListModel implements SelectionChangedListener, MapView.LayerChangeListener{ 
     13public class ChangesetInSelectionListModel extends ChangesetListModel implements SelectionChangedListener, EditLayerChangeListener{ 
    1514 
    1615    public ChangesetInSelectionListModel(DefaultListSelectionModel selectionModel) { 
     
    2423    } 
    2524 
     25 
    2626    /* ---------------------------------------------------------------------------- */ 
    2727    /* Interface LayerChangeListener                                                */ 
    2828    /* ---------------------------------------------------------------------------- */ 
    29     public void activeLayerChange(Layer oldLayer, Layer newLayer) { 
    30         if (newLayer == null || ! (newLayer instanceof OsmDataLayer)) { 
     29    public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) { 
     30        if (newLayer == null) { 
    3131            setChangesets(null); 
    3232        } else { 
    33             initFromPrimitives(((OsmDataLayer) newLayer).data.getSelected()); 
     33            initFromPrimitives((newLayer).data.getSelected()); 
    3434        } 
    3535    } 
    36     public void layerAdded(Layer newLayer) {} 
    37     public void layerRemoved(Layer oldLayer) {} 
    3836} 
  • trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetsInActiveDataLayerListModel.java

    r2655 r2689  
    1616import org.openstreetmap.josm.data.osm.event.TagsChangedEvent; 
    1717import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent; 
     18import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener; 
     19import org.openstreetmap.josm.gui.layer.OsmDataLayer; 
    1820 
    19 public class ChangesetsInActiveDataLayerListModel extends ChangesetListModel implements DataSetListener  { 
     21/** 
     22 * This is the list model for the list of changeset in the current edit layer. 
     23 *  
     24 */ 
     25public class ChangesetsInActiveDataLayerListModel extends ChangesetListModel implements DataSetListener, EditLayerChangeListener { 
    2026 
    2127    public ChangesetsInActiveDataLayerListModel(DefaultListSelectionModel selectionModel) { 
     
    2329    } 
    2430 
     31    /* ------------------------------------------------------------------------------ */ 
     32    /* interface DataSetListener                                                      */ 
     33    /* ------------------------------------------------------------------------------ */ 
    2534    public void dataChanged(DataChangedEvent event) { 
    26         initFromPrimitives(event.getPrimitives()); 
     35        initFromDataSet(event.getDataset()); 
    2736    } 
    28  
    29     public void nodeMoved(NodeMovedEvent event) {/* ignored */} 
    3037 
    3138    public void primtivesAdded(PrimitivesAddedEvent event) { 
     
    4148    } 
    4249 
    43     public void relationMembersChanged(RelationMembersChangedEvent event) {/* ignored */} 
    44  
    45     public void tagsChanged(TagsChangedEvent event) {/* ignored */} 
    46  
    4750    public void otherDatasetChange(AbstractDatasetChangedEvent event) { 
    4851        if (event instanceof ChangesetIdChangedEvent) { 
     
    5356    } 
    5457 
     58    public void nodeMoved(NodeMovedEvent event) {/* ignored */} 
     59 
     60    public void relationMembersChanged(RelationMembersChangedEvent event) {/* ignored */} 
     61 
     62    public void tagsChanged(TagsChangedEvent event) {/* ignored */} 
     63 
    5564    public void wayNodesChanged(WayNodesChangedEvent event) {/* ignored */} 
    5665 
     66    /* ------------------------------------------------------------------------------ */ 
     67    /* interface EditLayerListener                                                    */ 
     68    /* ------------------------------------------------------------------------------ */ 
     69    public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) { 
     70        // just init the model content. Don't register as DataSetListener. The mode 
     71        // is already registered to receive DataChangedEvents from the current 
     72        // edit layer 
     73        if (newLayer != null) { 
     74            initFromDataSet(newLayer.data); 
     75        } else { 
     76            initFromDataSet(null); 
     77        } 
     78    } 
    5779} 
  • trunk/src/org/openstreetmap/josm/gui/download/SlippyMapChooser.java

    r2524 r2689  
    77import java.awt.BorderLayout; 
    88import java.awt.Color; 
    9 import java.awt.Component; 
    109import java.awt.Dimension; 
    1110import java.awt.Graphics; 
     
    225224                        Math.min(l2.getLat(), l1.getLat()), 
    226225                        Math.min(l1.getLon(), l2.getLon()) 
    227                         ), 
     226                ), 
    228227                new LatLon( 
    229228                        Math.max(l2.getLat(), l1.getLat()), 
    230229                        Math.max(l1.getLon(), l2.getLon())) 
    231                 ); 
     230        ); 
    232231        iGui.boundingBoxChanged(b, this); 
    233232        repaint(); 
  • trunk/src/org/openstreetmap/josm/gui/history/HistoryLoadTask.java

    r2512 r2689  
    55import static org.openstreetmap.josm.tools.I18n.tr; 
    66 
     7import java.awt.Component; 
    78import java.io.IOException; 
    89import java.util.Collection; 
     
    2122import org.openstreetmap.josm.io.OsmServerHistoryReader; 
    2223import org.openstreetmap.josm.io.OsmTransferException; 
     24import org.openstreetmap.josm.tools.CheckParameterUtil; 
    2325import org.xml.sax.SAXException; 
    2426 
     
    5153    public HistoryLoadTask() { 
    5254        super(tr("Load history"), true); 
     55        toLoad = new HashSet<PrimitiveId>(); 
     56    } 
     57 
     58    /** 
     59     * Creates a new task 
     60     *  
     61     * @param parent the component to be used as reference to find the parent for {@see PleaseWaitDialog}. 
     62     * Must not be null. 
     63     * @throws IllegalArgumentException thrown if parent is null 
     64     */ 
     65    public HistoryLoadTask(Component parent) { 
     66        super(parent, tr("Load history"), true); 
     67        CheckParameterUtil.ensureParameterNotNull(parent, "parent"); 
    5368        toLoad = new HashSet<PrimitiveId>(); 
    5469    } 
  • trunk/src/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTask.java

    r2613 r2689  
    9999                return; 
    100100            reader = new OsmServerChangesetReader(); 
    101             ChangesetQuery query = new ChangesetQuery().forUser(model.getUserId()).beingOpen(); 
     101            ChangesetQuery query = new ChangesetQuery().forUser((int)model.getUserId()).beingOpen(true); 
    102102            changesets = reader.queryChangesets( 
    103103                    query,