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