source: josm/trunk/src/org/openstreetmap/josm/gui/io/TagSettingsPanel.java @ 12719

Last change on this file since 12719 was 12719, checked in by Don-vip, 3 weeks ago

fix #15232 - Allow user to request feedback when uploading by adding the review_requested=yes changeset tag.
Inspired by:

  • Property svn:eol-style set to native
File size: 6.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import java.awt.BorderLayout;
5import java.util.Map;
6import java.util.Optional;
7
8import javax.swing.JPanel;
9import javax.swing.event.ChangeEvent;
10import javax.swing.event.ChangeListener;
11import javax.swing.event.TableModelEvent;
12import javax.swing.event.TableModelListener;
13
14import org.openstreetmap.josm.data.osm.Changeset;
15import org.openstreetmap.josm.gui.MainApplication;
16import org.openstreetmap.josm.gui.tagging.TagEditorPanel;
17import org.openstreetmap.josm.gui.tagging.TagModel;
18import org.openstreetmap.josm.tools.CheckParameterUtil;
19
20/**
21 * Tag settings panel of upload dialog.
22 * @since 2599
23 */
24public class TagSettingsPanel extends JPanel implements TableModelListener {
25
26    /** checkbox for selecting whether an atomic upload is to be used  */
27    private final TagEditorPanel pnlTagEditor = new TagEditorPanel(null, null, Changeset.MAX_CHANGESET_TAG_LENGTH);
28    /** the model for the changeset comment */
29    private final transient ChangesetCommentModel changesetCommentModel;
30    private final transient ChangesetCommentModel changesetSourceModel;
31    private final transient ChangesetReviewModel changesetReviewModel;
32
33    /**
34     * Creates a new panel
35     *
36     * @param changesetCommentModel the changeset comment model. Must not be null.
37     * @param changesetSourceModel the changeset source model. Must not be null.
38     * @param changesetReviewModel the model for the changeset review. Must not be null.
39     * @throws IllegalArgumentException if {@code changesetCommentModel} is null
40     * @since 12719 (signature)
41     */
42    public TagSettingsPanel(ChangesetCommentModel changesetCommentModel, ChangesetCommentModel changesetSourceModel,
43            ChangesetReviewModel changesetReviewModel) {
44        CheckParameterUtil.ensureParameterNotNull(changesetCommentModel, "changesetCommentModel");
45        CheckParameterUtil.ensureParameterNotNull(changesetSourceModel, "changesetSourceModel");
46        CheckParameterUtil.ensureParameterNotNull(changesetReviewModel, "changesetReviewModel");
47        this.changesetCommentModel = changesetCommentModel;
48        this.changesetSourceModel = changesetSourceModel;
49        this.changesetReviewModel = changesetReviewModel;
50        changesetCommentModel.addChangeListener(new ChangesetCommentChangeListener("comment"));
51        changesetSourceModel.addChangeListener(new ChangesetCommentChangeListener("source"));
52        changesetReviewModel.addChangeListener(new ChangesetReviewChangeListener());
53        build();
54        pnlTagEditor.getModel().addTableModelListener(this);
55    }
56
57    protected void build() {
58        setLayout(new BorderLayout());
59        add(pnlTagEditor, BorderLayout.CENTER);
60    }
61
62    protected void setProperty(String key, String value) {
63        String val = (value == null ? "" : value).trim();
64        String commentInTag = getTagEditorValue(key);
65        if (val.equals(commentInTag))
66            return;
67
68        if (val.isEmpty()) {
69            pnlTagEditor.getModel().delete(key);
70            return;
71        }
72        TagModel tag = pnlTagEditor.getModel().get(key);
73        if (tag == null) {
74            tag = new TagModel(key, val);
75            pnlTagEditor.getModel().add(tag);
76        } else {
77            pnlTagEditor.getModel().updateTagValue(tag, val);
78        }
79    }
80
81    protected String getTagEditorValue(String key) {
82        TagModel tag = pnlTagEditor.getModel().get(key);
83        return tag == null ? null : tag.getValue();
84    }
85
86    /**
87     * Initialize panel from the given tags.
88     * @param tags the tags used to initialize the panel
89     */
90    public void initFromTags(Map<String, String> tags) {
91        pnlTagEditor.getModel().initFromTags(tags);
92    }
93
94    /**
95     * Replies the map with the current tags in the tag editor model.
96     * @param keepEmpty {@code true} to keep empty tags
97     * @return the map with the current tags in the tag editor model.
98     */
99    public Map<String, String> getTags(boolean keepEmpty) {
100        forceCommentFieldReload();
101        return pnlTagEditor.getModel().getTags(keepEmpty);
102    }
103
104    /**
105     * Initializes the panel for user input
106     */
107    public void startUserInput() {
108        pnlTagEditor.initAutoCompletion(MainApplication.getLayerManager().getEditLayer());
109    }
110
111    /* -------------------------------------------------------------------------- */
112    /* Interface TableChangeListener                                              */
113    /* -------------------------------------------------------------------------- */
114    @Override
115    public void tableChanged(TableModelEvent e) {
116        changesetCommentModel.setComment(getTagEditorValue("comment"));
117        changesetSourceModel.setComment(getTagEditorValue("source"));
118        changesetReviewModel.setReviewRequested("yes".equals(getTagEditorValue("review_requested")));
119    }
120
121    /**
122     * Force update the fields if the user is currently changing them. See #5676
123     */
124    private void forceCommentFieldReload() {
125        setProperty("comment", changesetCommentModel.getComment());
126        setProperty("source", changesetSourceModel.getComment());
127        setProperty("review_requested", changesetReviewModel.isReviewRequested() ? "yes" : null);
128    }
129
130    /**
131     * Observes the changeset comment model and keeps the tag editor in sync
132     * with the current changeset comment
133     */
134    class ChangesetCommentChangeListener implements ChangeListener {
135
136        private final String key;
137
138        ChangesetCommentChangeListener(String key) {
139            this.key = key;
140        }
141
142        @Override
143        public void stateChanged(ChangeEvent e) {
144            if (e.getSource() instanceof ChangesetCommentModel) {
145                String newValue = ((ChangesetCommentModel) e.getSource()).getComment();
146                String oldValue = Optional.ofNullable(getTagEditorValue(key)).orElse("");
147                if (!oldValue.equals(newValue)) {
148                    setProperty(key, newValue);
149                }
150            }
151        }
152    }
153
154    /**
155     * Observes the changeset review model and keeps the tag editor in sync
156     * with the current changeset review request
157     */
158    class ChangesetReviewChangeListener implements ChangeListener {
159
160        private final String key = "review_requested";
161
162        @Override
163        public void stateChanged(ChangeEvent e) {
164            if (e.getSource() instanceof ChangesetReviewModel) {
165                boolean newState = ((ChangesetReviewModel) e.getSource()).isReviewRequested();
166                boolean oldState = "yes".equals(Optional.ofNullable(getTagEditorValue(key)).orElse(""));
167                if (oldState != newState) {
168                    setProperty(key, newState ? "yes" : null);
169                }
170            }
171        }
172    }
173}
Note: See TracBrowser for help on using the repository browser.