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