Ticket #3663: relation_download_members.patch

File relation_download_members.patch, 15.9 KB (added by bastiK, 15 years ago)
  • src/org/openstreetmap/josm/actions/UpdateDataAction.java

     
    1818    public UpdateDataAction() {
    1919        super(tr("Update data"),
    2020                "updatedata",
    21                 tr("Updates the objects in the current data layer from the server."),
     21                tr("Updates the objects in the active data layer from the server."),
    2222                Shortcut.registerShortcut("file:updatedata",
    2323                        tr("Update data"),
    2424                        KeyEvent.VK_U,
  • src/org/openstreetmap/josm/actions/UploadAction.java

     
    116116    }
    117117
    118118    public UploadAction() {
    119         super(tr("Upload data"), "upload", tr("Upload all changes in the current data layer to the OSM server"),
     119        super(tr("Upload data"), "upload", tr("Upload all changes in the active data layer to the OSM server"),
    120120                Shortcut.registerShortcut("file:upload", tr("File: {0}", tr("Upload data")), KeyEvent.VK_U, Shortcut.GROUPS_ALT1+Shortcut.GROUP_HOTKEY), true);
    121121    }
    122122
  • src/org/openstreetmap/josm/gui/dialogs/DialogsPanel.java

     
    270270         */
    271271        if (numPanels == 1 && panels.get(N-1).getComponents().length == 0)
    272272        {
     273            parent.setDividerSize(0);
    273274            this.setVisible(false);
    274275        } else {
    275276            if (this.getWidth() != 0) { // only if josm started with hidden panel
    276277                this.setPreferredSize(new Dimension(this.getWidth(), 0));
    277278            }
    278279            this.setVisible(true);
     280            parent.setDividerSize(5);
    279281            parent.resetToPreferredSizes();
    280282        }
    281283    }
  • src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java

     
    44
    55import java.awt.BorderLayout;
    66import java.awt.GridLayout;
     7import java.awt.Point;
    78import java.awt.event.ActionEvent;
     9import java.awt.event.ActionListener;
    810import java.awt.event.KeyEvent;
    911import java.awt.event.MouseAdapter;
    1012import java.awt.event.MouseEvent;
    1113import java.util.ArrayList;
     14import java.util.Arrays;
    1215import java.util.Collection;
    1316import java.util.Collections;
    1417import java.util.Comparator;
    1518import java.util.HashSet;
     19import java.util.List;
    1620import java.util.logging.Logger;
    1721
    1822import javax.swing.AbstractAction;
    1923import javax.swing.AbstractListModel;
    2024import javax.swing.JList;
     25import javax.swing.JMenuItem;
    2126import javax.swing.JPanel;
     27import javax.swing.JPopupMenu;
    2228import javax.swing.JScrollPane;
    2329import javax.swing.ListSelectionModel;
    2430import javax.swing.SwingUtilities;
     
    3541import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
    3642import org.openstreetmap.josm.gui.SideButton;
    3743import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
     44import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor;
    3845import org.openstreetmap.josm.gui.layer.DataChangeListener;
    3946import org.openstreetmap.josm.gui.layer.Layer;
    4047import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     
    167174            model.setRelations(null);
    168175            return;
    169176        }
    170         Relation selected = getSelected();
     177        Relation[] selected = getAllSelected();
    171178
    172179        model.setRelations(getDisplayedRelationsInSortOrder(Main.main.getCurrentDataSet()));
    173180        if(model.getSize() > 0) {
     
    175182        } else {
    176183            setTitle(tr("Relations"));
    177184        }
    178         selectRelation(selected);
     185        selectRelations(selected);
    179186    }
    180187
    181188    public void activeLayerChange(Layer a, Layer b) {
     
    237244    }
    238245
    239246    /**
     247     * @return All selected relations in the list, possibly empty List
     248     */
     249    private Relation[] getAllSelected() {
     250        return (Relation[]) Arrays.asList(displaylist.getSelectedValues()).toArray(new Relation[0]);
     251    }
     252
     253    /**
    240254     * Selects the relation <code>relation</code> in the list of relations.
    241255     *
    242256     * @param relation  the relation
    243257     */
    244258    public void selectRelation(Relation relation) {
    245         if (relation == null){
    246             displaylist.clearSelection();
    247             return;
     259        selectRelations(new Relation[] {relation});
     260    }
     261
     262    /**
     263     * Selects the relations <code>relations</code> in the list of relations.
     264     *
     265     * @param relations  the relations (may be empty)
     266     */
     267    public void selectRelations(Relation[] relations) {
     268        List<Integer> sel = new ArrayList<Integer>();
     269        for (Relation r : relations) {
     270            if (r == null) continue;
     271            int idx = model.getIndexOfRelation(r);
     272            if (idx != -1) {
     273                sel.add(idx);
     274            }
    248275        }
    249         int idx = model.getIndexOfRelation(relation);
    250         if (idx == -1) {
     276        if (sel.isEmpty()) {
    251277            displaylist.clearSelection();
     278            return;
    252279        } else {
    253             displaylist.setSelectedIndex(idx);
    254             displaylist.scrollRectToVisible(displaylist.getCellBounds(idx,idx));
     280            int fst = Collections.min(sel);
     281            displaylist.scrollRectToVisible(displaylist.getCellBounds(fst, fst));
     282        }
     283
     284        int[] aSel = new int[sel.size()];       //FIXME: how to cast Integer[] -> int[] ?
     285        for (int i=0; i<sel.size(); ++i) {
     286            aSel[i] = sel.get(i);
    255287        }
     288
     289        displaylist.setSelectedIndices(aSel);
    256290    }
    257291
    258292    class DoubleClickAdapter extends MouseAdapter {
     
    273307                }
    274308            }
    275309        }
     310        private void openPopup(MouseEvent e) {
     311            Point p = e.getPoint();
     312            int index = displaylist.locationToIndex(p);
     313            if (index < 0) return;
     314            if (!displaylist.getCellBounds(index, index).contains(e.getPoint()))
     315                return;
     316            Object obj = model.getElementAt(index);
     317            if (! displaylist.isSelectedIndex(index)) {
     318                displaylist.setSelectedIndex(index);
     319            }
     320            JPopupMenu menu = new JPopupMenu();
     321            JMenuItem down = new JMenuItem(tr("Download members"), ImageProvider.get("dialogs", "downloadincomplete"));
     322
     323            final Object[] os = displaylist.getSelectedValues();
     324            final List<Relation> rs = new ArrayList<Relation>();
     325            for (Object o : os) {
     326                Relation r = (Relation) o;
     327                if (r != null && !r.isNew()) {
     328                    rs.add(r);
     329                }
     330            }
     331            down.setEnabled(!rs.isEmpty());
     332            down.addActionListener(new ActionListener () {
     333                public void actionPerformed(ActionEvent e) {
     334                    Main.worker.submit(new GenericRelationEditor.DownloadTask(
     335                                                    (Relation[]) rs.toArray(new Relation[0]),
     336                                                    Main.map.mapView.getEditLayer(), null));
     337                }
     338            });
     339            JMenuItem select = new JMenuItem(tr("Select members"), ImageProvider.get("selectall"));
     340            select.addActionListener(new ActionListener () {
     341                public void actionPerformed(ActionEvent e) {
     342                    Object[] rs = displaylist.getSelectedValues();
     343                    HashSet<OsmPrimitive> ms = new HashSet<OsmPrimitive>();
     344                    for (Object r : rs) {
     345                        for (RelationMember m : ((Relation) r).getMembers()) {
     346                            ms.add(m.getMember());
     347                        }
     348                    }
     349                    final OsmDataLayer l = Main.map.mapView.getEditLayer();
     350                    l.data.setSelected(ms);
     351                    DataSet.fireSelectionChanged(l.data.getSelected());
     352                }
     353            });
     354            menu.add(down);
     355            menu.add(select);
     356
     357            menu.show(RelationListDialog.this, p.x, p.y-3);
     358        }
     359        @Override public void mousePressed(MouseEvent e) {
     360            if (e.isPopupTrigger()) {
     361                openPopup(e);
     362            }
     363        }
     364        @Override public void mouseReleased(MouseEvent e) {
     365            if (e.isPopupTrigger()) {
     366                openPopup(e);
     367            }
     368        }
    276369    }
    277370
    278     /**
     371   /**
    279372     * The edit action
    280373     *
    281374     */
  • src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java

     
    196196            listSelectionModel.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    197197        }
    198198        return listSelectionModel;
    199     }
    200 
    201     public void updateMemberReferences(DataSet ds) {
    202         for (int i=0; i< members.size();i++) {
    203             RelationMember member = members.get(i);
    204             if (member.getMember().isNew()) {
    205                 continue;
    206             }
    207             OsmPrimitive primitive = ds.getPrimitiveById(member.getMember().getId(), OsmPrimitiveType.from(member.getMember()));
    208             if (primitive != null) {
    209                 RelationMember newMember = new RelationMember(member.getRole(), primitive);
    210                 members.remove(i);
    211                 members.add(i, newMember);
    212             }
    213         }
    214         fireTableDataChanged();
    215     }
    216 
     199    }
    217200
    218201    public void removeMembersReferringTo(List<? extends OsmPrimitive> primitives) {
    219202        if (primitives == null)
  • src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

                 return;
     
    11951195        public void actionPerformed(ActionEvent e) {
    11961196            if (!isEnabled())
    11971197                return;
    1198             Main.worker.submit(new DownloadTask(GenericRelationEditor.this));
     1198            Main.worker.submit(new DownloadTask(new Relation[] {getRelation()}, getLayer(), memberTableModel, GenericRelationEditor.this));
    11991199        }
    12001200
    12011201        protected void updateEnabledState() {
     
    13611361     * The asynchronous task for downloading relation members.
    13621362     *
    13631363     */
    1364     class DownloadTask extends PleaseWaitRunnable {
     1364    public static class DownloadTask extends PleaseWaitRunnable {
    13651365        private boolean cancelled;
    13661366        private int conflictsCount;
    13671367        private Exception lastException;
     1368        private Relation[] relations;
     1369        private OsmDataLayer curLayer;
     1370        private MemberTableModel memberTableModel;
    13681371
    1369         public DownloadTask(Dialog parent) {
     1372        public DownloadTask(Relation[] relations, OsmDataLayer curLayer, MemberTableModel memberTableModel, Dialog parent) {
    13701373            super(tr("Download relation members"), new PleaseWaitProgressMonitor(parent), false /*
    13711374             * don't
    13721375             * ignore
    13731376             * exception
    13741377             */);
     1378             this.relations = relations;
     1379             this.curLayer = curLayer;
     1380             this.memberTableModel = memberTableModel;
     1381        }
     1382        public DownloadTask(Relation[] relations, OsmDataLayer curLayer, MemberTableModel memberTableModel) {
     1383            super(tr("Download relation members"), new PleaseWaitProgressMonitor(), false /*
     1384             * don't
     1385             * ignore
     1386             * exception
     1387             */);
     1388             this.relations = relations;
     1389             this.curLayer = curLayer;       
     1390             this.memberTableModel = memberTableModel;
    13751391        }
    13761392
    13771393        @Override
     
    13821398
    13831399        @Override
    13841400        protected void finish() {
     1401            Main.map.repaint();
    13851402            if (cancelled)
    13861403                return;
    1387             memberTableModel.updateMemberReferences(getLayer().data);
     1404            if (memberTableModel != null) {
     1405                memberTableModel.fireTableDataChanged();
     1406            }
    13881407            if (lastException != null) {
    13891408                ExceptionDialogUtil.explainException(lastException);
    13901409            }
     
    14021421        @Override
    14031422        protected void realRun() throws SAXException, IOException, OsmTransferException {
    14041423            try {
    1405                 progressMonitor.indeterminateSubTask("");
    1406                 OsmServerObjectReader reader = new OsmServerObjectReader(getRelation().getId(), OsmPrimitiveType.RELATION,
    1407                         true);
    1408                 DataSet dataSet = reader.parseOsm(progressMonitor
    1409                         .createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    1410                 if (dataSet != null) {
    1411                     final MergeVisitor visitor = new MergeVisitor(getLayer().data, dataSet);
    1412                     visitor.merge();
    1413 
    1414                     // copy the merged layer's data source info
    1415                     for (DataSource src : dataSet.dataSources) {
    1416                         getLayer().data.dataSources.add(src);
     1424                boolean changed = false;
     1425                for (Relation relation : relations) {
     1426                    progressMonitor.indeterminateSubTask("");
     1427                    OsmServerObjectReader reader = new OsmServerObjectReader(relation.getId(), OsmPrimitiveType.RELATION,
     1428                            true);
     1429                    DataSet dataSet = reader.parseOsm(progressMonitor
     1430                            .createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
     1431                    if (dataSet != null) {
     1432                        changed = true;
     1433                        final MergeVisitor visitor = new MergeVisitor(curLayer.data, dataSet);
     1434                        visitor.merge();
     1435
     1436                        // copy the merged layer's data source info
     1437                        for (DataSource src : dataSet.dataSources) {
     1438                            curLayer.data.dataSources.add(src);
     1439                        }
     1440                        if (!visitor.getConflicts().isEmpty()) {
     1441                            curLayer.getConflicts().add(visitor.getConflicts());
     1442                            conflictsCount = visitor.getConflicts().size();
     1443                        }
    14171444                    }
    1418                     // FIXME: this is necessary because there are dialogs listening
    1419                     // for DataChangeEvents which manipulate Swing components on this
    1420                     // thread.
    1421                     //
     1445                }
     1446                // FIXME: this is necessary because there are dialogs listening
     1447                // for DataChangeEvents which manipulate Swing components on this
     1448                // thread.
     1449                //
     1450                if (changed) {
    14221451                    SwingUtilities.invokeLater(new Runnable() {
    14231452                        public void run() {
    1424                             getLayer().fireDataChange();
     1453                            curLayer.fireDataChange();
    14251454                        }
    14261455                    });
    1427                     if (!visitor.getConflicts().isEmpty()) {
    1428                         getLayer().getConflicts().add(visitor.getConflicts());
    1429                         conflictsCount = visitor.getConflicts().size();
    1430                     }
    14311456                }
    14321457            } catch (Exception e) {
    14331458                if (cancelled) {