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