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