001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.io;
003
004import java.util.ArrayList;
005import java.util.List;
006
007import javax.swing.DefaultComboBoxModel;
008
009import org.openstreetmap.josm.data.osm.Changeset;
010import org.openstreetmap.josm.data.osm.ChangesetCache;
011import org.openstreetmap.josm.data.osm.ChangesetCacheEvent;
012import org.openstreetmap.josm.data.osm.ChangesetCacheListener;
013
014/**
015 * A combobox model for the list of open changesets. The model is populated with the list
016 * of open changesets kept in the {@link ChangesetCache}.
017 *
018 */
019public class OpenChangesetComboBoxModel extends DefaultComboBoxModel<Changeset> implements ChangesetCacheListener {
020    private final transient List<Changeset> changesets;
021    private transient Changeset selectedChangeset;
022
023    protected Changeset getChangesetById(long id) {
024        for (Changeset cs : changesets) {
025            if (cs.getId() == id) return cs;
026        }
027        return null;
028    }
029
030    /**
031     * Constructs a new {@code OpenChangesetComboBoxModel}.
032     */
033    public OpenChangesetComboBoxModel() {
034        this.changesets = new ArrayList<>();
035    }
036
037    /**
038     * Refreshes the content of the combobox model with the current list of open
039     * changesets from the {@link ChangesetCache}.
040     */
041    public void refresh() {
042        changesets.clear();
043        changesets.addAll(ChangesetCache.getInstance().getOpenChangesets());
044        fireContentsChanged(this, 0, getSize());
045        int idx = changesets.indexOf(selectedChangeset);
046        if (idx < 0) {
047            selectFirstChangeset();
048        } else {
049            setSelectedItem(changesets.get(idx));
050        }
051    }
052
053    /**
054     * Selects the first changeset in the current list of open changesets
055     */
056    public void selectFirstChangeset() {
057        if (changesets == null || changesets.isEmpty()) {
058            setSelectedItem(null);
059        } else {
060            setSelectedItem(changesets.get(0));
061        }
062    }
063
064    /* ------------------------------------------------------------------------------------ */
065    /* ChangesetCacheListener                                                               */
066    /* ------------------------------------------------------------------------------------ */
067    @Override
068    public void changesetCacheUpdated(ChangesetCacheEvent event) {
069        refresh();
070    }
071
072    /* ------------------------------------------------------------------------------------ */
073    /* ComboBoxModel                                                                        */
074    /* ------------------------------------------------------------------------------------ */
075    @Override
076    public Changeset getElementAt(int index) {
077        return changesets.get(index);
078    }
079
080    @Override
081    public int getIndexOf(Object anObject) {
082        return changesets.indexOf(anObject);
083    }
084
085    @Override
086    public int getSize() {
087        return changesets.size();
088    }
089
090    @Override
091    public Object getSelectedItem() {
092        return selectedChangeset;
093    }
094
095    @Override
096    public void setSelectedItem(Object anObject) {
097        if (anObject == null) {
098            this.selectedChangeset = null;
099            super.setSelectedItem(null);
100            return;
101        }
102        if (!(anObject instanceof Changeset)) return;
103        Changeset cs = (Changeset) anObject;
104        if (cs.getId() == 0 || !cs.isOpen()) return;
105        Changeset candidate = getChangesetById(cs.getId());
106        if (candidate == null) return;
107        this.selectedChangeset = candidate;
108        super.setSelectedItem(selectedChangeset);
109    }
110}