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