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 public enum Mode { 020 EDITING_DATA, 021 UPLOADING_AND_SAVING 022 } 023 024 private List<SaveLayerInfo> layerInfo; 025 private Mode mode; 026 private 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 Collections.sort( 074 layerInfo, 075 new Comparator<SaveLayerInfo>() { 076 @Override 077 public int compare(SaveLayerInfo o1, SaveLayerInfo o2) { 078 return o1.compareTo(o2); 079 } 080 } 081 ); 082 fireTableDataChanged(); 083 } 084 085 @Override 086 public int getRowCount() { 087 if (layerInfo == null) return 0; 088 return layerInfo.size(); 089 } 090 091 @Override 092 public Object getValueAt(int row, int column) { 093 if (layerInfo == null) return null; 094 return layerInfo.get(row); 095 } 096 097 @Override 098 public boolean isCellEditable(int row, int column) { 099 return column == columnFilename || column == columnActions; 100 } 101 102 @Override 103 public void setValueAt(Object value, int row, int column) { 104 switch(column) { 105 case columnFilename: 106 this.layerInfo.get(row).setFile((File)value); 107 this.layerInfo.get(row).setDoSaveToFile(true); 108 break; 109 case columnActions: 110 boolean[] values = (boolean[]) value; 111 this.layerInfo.get(row).setDoUploadToServer(values[0]); 112 this.layerInfo.get(row).setDoSaveToFile(values[1]); 113 break; 114 } 115 fireTableDataChanged(); 116 } 117 118 public List<SaveLayerInfo> getSafeLayerInfo() { 119 return this.layerInfo; 120 } 121 122 public List<SaveLayerInfo> getLayersWithoutFilesAndSaveRequest() { 123 List<SaveLayerInfo> ret = new ArrayList<>(); 124 for (SaveLayerInfo info: layerInfo) { 125 if (info.isDoSaveToFile() && info.getFile() == null) { 126 ret.add(info); 127 } 128 } 129 return ret; 130 } 131 132 public List<SaveLayerInfo> getLayersWithIllegalFilesAndSaveRequest() { 133 List<SaveLayerInfo> ret =new ArrayList<>(); 134 for (SaveLayerInfo info: layerInfo) { 135 if (info.isDoSaveToFile() && info.getFile() != null && info.getFile().exists() && !info.getFile().canWrite()) { 136 ret.add(info); 137 } 138 } 139 return ret; 140 } 141 142 public List<SaveLayerInfo> getLayersWithConflictsAndUploadRequest() { 143 List<SaveLayerInfo> ret = new ArrayList<>(); 144 for (SaveLayerInfo info: layerInfo) { 145 AbstractModifiableLayer l = info.getLayer(); 146 if (info.isDoUploadToServer() && l instanceof OsmDataLayer && !((OsmDataLayer)l).getConflicts().isEmpty()) { 147 ret.add(info); 148 } 149 } 150 return ret; 151 } 152 153 public List<SaveLayerInfo> getLayersToUpload() { 154 List<SaveLayerInfo> ret = new ArrayList<>(); 155 for (SaveLayerInfo info: layerInfo) { 156 if (info.isDoUploadToServer()) { 157 ret.add(info); 158 } 159 } 160 return ret; 161 } 162 163 public List<SaveLayerInfo> getLayersToSave() { 164 List<SaveLayerInfo> ret = new ArrayList<>(); 165 for (SaveLayerInfo info: layerInfo) { 166 if (info.isDoSaveToFile()) { 167 ret.add(info); 168 } 169 } 170 return ret; 171 } 172 173 public void setUploadState(AbstractModifiableLayer layer, UploadOrSaveState state) { 174 SaveLayerInfo info = getSaveLayerInfo(layer); 175 if (info != null) { 176 info.setUploadState(state); 177 } 178 fireTableDataChanged(); 179 } 180 181 public void setSaveState(AbstractModifiableLayer layer, UploadOrSaveState state) { 182 SaveLayerInfo info = getSaveLayerInfo(layer); 183 if (info != null) { 184 info.setSaveState(state); 185 } 186 fireTableDataChanged(); 187 } 188 189 public SaveLayerInfo getSaveLayerInfo(AbstractModifiableLayer layer) { 190 for (SaveLayerInfo info: this.layerInfo) { 191 if (info.getLayer() == layer) 192 return info; 193 } 194 return null; 195 } 196 197 public void resetSaveAndUploadState() { 198 for (SaveLayerInfo info: layerInfo) { 199 info.setSaveState(null); 200 info.setUploadState(null); 201 } 202 } 203 204 public boolean hasUnsavedData() { 205 for (SaveLayerInfo info: layerInfo) { 206 if (info.isDoUploadToServer() && ! UploadOrSaveState.OK.equals(info.getUploadState())) 207 return true; 208 if (info.isDoSaveToFile() && ! UploadOrSaveState.OK.equals(info.getSaveState())) 209 return true; 210 } 211 return false; 212 } 213 214 public int getNumCancel() { 215 int ret = 0; 216 for (SaveLayerInfo info: layerInfo) { 217 if (UploadOrSaveState.CANCELED.equals(info.getSaveState()) 218 || UploadOrSaveState.CANCELED.equals(info.getUploadState())) { 219 ret++; 220 } 221 } 222 return ret; 223 } 224 225 public int getNumFailed() { 226 int ret = 0; 227 for (SaveLayerInfo info: layerInfo) { 228 if (UploadOrSaveState.FAILED.equals(info.getSaveState()) 229 || UploadOrSaveState.FAILED.equals(info.getUploadState())) { 230 ret++; 231 } 232 } 233 return ret; 234 } 235}