001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.io; 003 004import java.beans.PropertyChangeListener; 005import java.beans.PropertyChangeSupport; 006import java.io.File; 007import java.util.ArrayList; 008import java.util.Collections; 009import java.util.Comparator; 010import java.util.List; 011 012import javax.swing.table.DefaultTableModel; 013 014import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer; 015import org.openstreetmap.josm.gui.layer.OsmDataLayer; 016 017public class SaveLayersModel extends DefaultTableModel { 018 public static final String MODE_PROP = SaveLayerInfo.class.getName() + ".mode"; 019 020 public enum Mode { 021 EDITING_DATA, 022 UPLOADING_AND_SAVING 023 } 024 025 private transient List<SaveLayerInfo> layerInfo; 026 private Mode mode; 027 private PropertyChangeSupport support; 028 029 // keep in sync with how the columns are ordered in SaveLayersTableColumnModel#build 030 private static final int columnFilename = 0; 031 private static final int columnActions = 2; 032 033 /** 034 * Constructs a new {@code SaveLayersModel}. 035 */ 036 public SaveLayersModel() { 037 mode = Mode.EDITING_DATA; 038 support = new PropertyChangeSupport(this); 039 } 040 041 public void addPropertyChangeListener(PropertyChangeListener l) { 042 support.addPropertyChangeListener(l); 043 } 044 045 public void removePropertyChangeListener(PropertyChangeListener l) { 046 support.removePropertyChangeListener(l); 047 } 048 049 protected void fireModeChanged(Mode oldValue, Mode newValue) { 050 support.firePropertyChange(MODE_PROP, oldValue, newValue); 051 } 052 053 public void setMode(Mode newValue) { 054 Mode oldValue = this.mode; 055 this.mode = newValue; 056 fireModeChanged(oldValue, newValue); 057 } 058 059 public Mode getMode() { 060 return mode; 061 } 062 063 /** 064 * Populates the model with given modifiable layers. 065 * @param layers The layers to use to populate this model 066 * @since 7358 067 */ 068 public void populate(List<? extends AbstractModifiableLayer> layers) { 069 layerInfo = new ArrayList<>(); 070 if (layers == null) return; 071 for (AbstractModifiableLayer layer: layers) { 072 layerInfo.add(new SaveLayerInfo(layer)); 073 } 074 Collections.sort( 075 layerInfo, 076 new Comparator<SaveLayerInfo>() { 077 @Override 078 public int compare(SaveLayerInfo o1, SaveLayerInfo o2) { 079 return o1.compareTo(o2); 080 } 081 } 082 ); 083 fireTableDataChanged(); 084 } 085 086 @Override 087 public int getRowCount() { 088 if (layerInfo == null) return 0; 089 return layerInfo.size(); 090 } 091 092 @Override 093 public Object getValueAt(int row, int column) { 094 if (layerInfo == null) return null; 095 return layerInfo.get(row); 096 } 097 098 @Override 099 public boolean isCellEditable(int row, int column) { 100 return column == columnFilename || column == columnActions; 101 } 102 103 @Override 104 public void setValueAt(Object value, int row, int column) { 105 switch(column) { 106 case columnFilename: 107 this.layerInfo.get(row).setFile((File) value); 108 this.layerInfo.get(row).setDoSaveToFile(true); 109 break; 110 case columnActions: 111 boolean[] values = (boolean[]) value; 112 this.layerInfo.get(row).setDoUploadToServer(values[0]); 113 this.layerInfo.get(row).setDoSaveToFile(values[1]); 114 break; 115 } 116 fireTableDataChanged(); 117 } 118 119 public List<SaveLayerInfo> getSafeLayerInfo() { 120 return this.layerInfo; 121 } 122 123 public List<SaveLayerInfo> getLayersWithoutFilesAndSaveRequest() { 124 List<SaveLayerInfo> ret = new ArrayList<>(); 125 for (SaveLayerInfo info: layerInfo) { 126 if (info.isDoSaveToFile() && info.getFile() == null) { 127 ret.add(info); 128 } 129 } 130 return ret; 131 } 132 133 public List<SaveLayerInfo> getLayersWithIllegalFilesAndSaveRequest() { 134 List<SaveLayerInfo> ret = new ArrayList<>(); 135 for (SaveLayerInfo info: layerInfo) { 136 if (info.isDoSaveToFile() && info.getFile() != null && info.getFile().exists() && !info.getFile().canWrite()) { 137 ret.add(info); 138 } 139 } 140 return ret; 141 } 142 143 public List<SaveLayerInfo> getLayersWithConflictsAndUploadRequest() { 144 List<SaveLayerInfo> ret = new ArrayList<>(); 145 for (SaveLayerInfo info: layerInfo) { 146 AbstractModifiableLayer l = info.getLayer(); 147 if (info.isDoUploadToServer() && l instanceof OsmDataLayer && !((OsmDataLayer) l).getConflicts().isEmpty()) { 148 ret.add(info); 149 } 150 } 151 return ret; 152 } 153 154 public List<SaveLayerInfo> getLayersToUpload() { 155 List<SaveLayerInfo> ret = new ArrayList<>(); 156 for (SaveLayerInfo info: layerInfo) { 157 if (info.isDoUploadToServer()) { 158 ret.add(info); 159 } 160 } 161 return ret; 162 } 163 164 public List<SaveLayerInfo> getLayersToSave() { 165 List<SaveLayerInfo> ret = new ArrayList<>(); 166 for (SaveLayerInfo info: layerInfo) { 167 if (info.isDoSaveToFile()) { 168 ret.add(info); 169 } 170 } 171 return ret; 172 } 173 174 public void setUploadState(AbstractModifiableLayer layer, UploadOrSaveState state) { 175 SaveLayerInfo info = getSaveLayerInfo(layer); 176 if (info != null) { 177 info.setUploadState(state); 178 } 179 fireTableDataChanged(); 180 } 181 182 public void setSaveState(AbstractModifiableLayer layer, UploadOrSaveState state) { 183 SaveLayerInfo info = getSaveLayerInfo(layer); 184 if (info != null) { 185 info.setSaveState(state); 186 } 187 fireTableDataChanged(); 188 } 189 190 public SaveLayerInfo getSaveLayerInfo(AbstractModifiableLayer layer) { 191 for (SaveLayerInfo info: this.layerInfo) { 192 if (info.getLayer() == layer) 193 return info; 194 } 195 return null; 196 } 197 198 public void resetSaveAndUploadState() { 199 for (SaveLayerInfo info: layerInfo) { 200 info.setSaveState(null); 201 info.setUploadState(null); 202 } 203 } 204 205 public boolean hasUnsavedData() { 206 for (SaveLayerInfo info: layerInfo) { 207 if (info.isDoUploadToServer() && !UploadOrSaveState.OK.equals(info.getUploadState())) 208 return true; 209 if (info.isDoSaveToFile() && !UploadOrSaveState.OK.equals(info.getSaveState())) 210 return true; 211 } 212 return false; 213 } 214 215 public int getNumCancel() { 216 int ret = 0; 217 for (SaveLayerInfo info: layerInfo) { 218 if (UploadOrSaveState.CANCELED.equals(info.getSaveState()) 219 || UploadOrSaveState.CANCELED.equals(info.getUploadState())) { 220 ret++; 221 } 222 } 223 return ret; 224 } 225 226 public int getNumFailed() { 227 int ret = 0; 228 for (SaveLayerInfo info: layerInfo) { 229 if (UploadOrSaveState.FAILED.equals(info.getSaveState()) 230 || UploadOrSaveState.FAILED.equals(info.getUploadState())) { 231 ret++; 232 } 233 } 234 return ret; 235 } 236}