001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.io;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005import static org.openstreetmap.josm.tools.I18n.trn;
006
007import java.awt.GridBagConstraints;
008import java.awt.GridBagLayout;
009import java.util.ArrayList;
010import java.util.List;
011
012import javax.swing.AbstractListModel;
013import javax.swing.JLabel;
014import javax.swing.JList;
015import javax.swing.JPanel;
016import javax.swing.JScrollPane;
017
018import org.openstreetmap.josm.data.osm.OsmPrimitive;
019import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
020
021/**
022 * This panel displays a summary of the objects to upload. It is displayed in
023 * the upper part of the {@link UploadDialog}.
024 *
025 */
026public class UploadedObjectsSummaryPanel extends JPanel {
027    public static final String NUM_OBJECTS_TO_UPLOAD_PROP = UploadedObjectsSummaryPanel.class.getName() + ".numObjectsToUpload";
028
029    /** the list with the added primitives */
030    private PrimitiveList lstAdd;
031    private JLabel lblAdd;
032    private JScrollPane spAdd;
033    /** the list with the updated primitives */
034    private PrimitiveList lstUpdate;
035    private JLabel lblUpdate;
036    private JScrollPane spUpdate;
037    /** the list with the deleted primitives */
038    private PrimitiveList lstDelete;
039    private JLabel lblDelete;
040    private JScrollPane spDelete;
041
042    protected void build() {
043        setLayout(new GridBagLayout());
044        OsmPrimitivRenderer renderer = new OsmPrimitivRenderer();
045        // initialize the three lists for uploaded primitives, but don't add
046        // them to the dialog yet,  see setUploadedPrimitives()
047        //
048        lstAdd = new PrimitiveList();
049        lstAdd.setCellRenderer(renderer);
050        lstAdd.setVisibleRowCount(Math.min(lstAdd.getModel().getSize(), 10));
051        spAdd = new JScrollPane(lstAdd);
052        lblAdd = new JLabel(tr("Objects to add:"));
053
054        lstUpdate = new PrimitiveList();
055        lstUpdate.setCellRenderer(renderer);
056        lstUpdate.setVisibleRowCount(Math.min(lstUpdate.getModel().getSize(), 10));
057        spUpdate = new JScrollPane(lstUpdate);
058        lblUpdate = new JLabel(tr("Objects to modify:"));
059
060        lstDelete = new PrimitiveList();
061        lstDelete.setCellRenderer(renderer);
062        lstDelete.setVisibleRowCount(Math.min(lstDelete.getModel().getSize(), 10));
063        spDelete = new JScrollPane(lstDelete);
064        lblDelete = new JLabel(tr("Objects to delete:"));
065    }
066
067    /**
068     * Sets the collections of primitives which will be uploaded
069     *
070     * @param add  the collection of primitives to add
071     * @param update the collection of primitives to update
072     * @param delete the collection of primitives to delete
073     */
074    public void setUploadedPrimitives(List<OsmPrimitive> add, List<OsmPrimitive> update, List<OsmPrimitive> delete) {
075        lstAdd.getPrimitiveListModel().setPrimitives(add);
076        lstUpdate.getPrimitiveListModel().setPrimitives(update);
077        lstDelete.getPrimitiveListModel().setPrimitives(delete);
078
079        GridBagConstraints gcLabel = new GridBagConstraints();
080        gcLabel.fill = GridBagConstraints.HORIZONTAL;
081        gcLabel.weightx = 1.0;
082        gcLabel.weighty = 0.0;
083        gcLabel.anchor = GridBagConstraints.FIRST_LINE_START;
084
085        GridBagConstraints gcList = new GridBagConstraints();
086        gcList.fill = GridBagConstraints.BOTH;
087        gcList.weightx = 1.0;
088        gcList.weighty = 1.0;
089        gcList.anchor = GridBagConstraints.CENTER;
090        removeAll();
091        int y = -1;
092        if (!add.isEmpty()) {
093            y++;
094            gcLabel.gridy = y;
095            lblAdd.setText(trn("{0} object to add:", "{0} objects to add:", add.size(),add.size()));
096            add(lblAdd, gcLabel);
097            y++;
098            gcList.gridy = y;
099            add(spAdd, gcList);
100        }
101        if (!update.isEmpty()) {
102            y++;
103            gcLabel.gridy = y;
104            lblUpdate.setText(trn("{0} object to modify:", "{0} objects to modify:", update.size(),update.size()));
105            add(lblUpdate, gcLabel);
106            y++;
107            gcList.gridy = y;
108            add(spUpdate, gcList);
109        }
110        if (!delete.isEmpty()) {
111            y++;
112            gcLabel.gridy = y;
113            lblDelete.setText(trn("{0} object to delete:", "{0} objects to delete:", delete.size(),delete.size()));
114            add(lblDelete, gcLabel);
115            y++;
116            gcList.gridy = y;
117            add(spDelete, gcList);
118        }
119
120        firePropertyChange(NUM_OBJECTS_TO_UPLOAD_PROP,0, getNumObjectsToUpload());
121    }
122
123    public UploadedObjectsSummaryPanel() {
124        build();
125    }
126
127    /**
128     * Replies the number of objects to upload
129     *
130     * @return the number of objects to upload
131     */
132    public int  getNumObjectsToUpload() {
133        return lstAdd.getModel().getSize()
134        + lstUpdate.getModel().getSize()
135        + lstDelete.getModel().getSize();
136    }
137
138    /**
139     * A simple list of OSM primitives.
140     *
141     */
142    static class PrimitiveList extends JList<OsmPrimitive> {
143        public PrimitiveList() {
144            super(new PrimitiveListModel());
145        }
146
147        public PrimitiveListModel getPrimitiveListModel() {
148            return (PrimitiveListModel)getModel();
149        }
150    }
151
152    /**
153     * A list model for a list of OSM primitives.
154     *
155     */
156    static class PrimitiveListModel extends AbstractListModel<OsmPrimitive> {
157        private List<OsmPrimitive> primitives;
158
159        public PrimitiveListModel() {
160            primitives = new ArrayList<>();
161        }
162
163        public PrimitiveListModel(List<OsmPrimitive> primitives) {
164            setPrimitives(primitives);
165        }
166
167        public void setPrimitives(List<OsmPrimitive> primitives) {
168            if (primitives == null) {
169                this.primitives = new ArrayList<>();
170            } else {
171                this.primitives = primitives;
172            }
173            fireContentsChanged(this,0,getSize());
174        }
175
176        @Override
177        public OsmPrimitive getElementAt(int index) {
178            if (primitives == null) return null;
179            return primitives.get(index);
180        }
181
182        @Override
183        public int getSize() {
184            if (primitives == null) return 0;
185            return primitives.size();
186        }
187    }
188}