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