001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.io; 003 004import java.awt.BorderLayout; 005import java.util.Map; 006import java.util.Observable; 007import java.util.Observer; 008 009import javax.swing.JPanel; 010import javax.swing.event.TableModelEvent; 011import javax.swing.event.TableModelListener; 012 013import org.openstreetmap.josm.Main; 014import org.openstreetmap.josm.data.osm.Changeset; 015import org.openstreetmap.josm.gui.tagging.TagEditorPanel; 016import org.openstreetmap.josm.gui.tagging.TagModel; 017import org.openstreetmap.josm.tools.CheckParameterUtil; 018 019/** 020 * Tag settings panel of upload dialog. 021 * @since 2599 022 */ 023public class TagSettingsPanel extends JPanel implements TableModelListener { 024 025 /** checkbox for selecting whether an atomic upload is to be used */ 026 private final TagEditorPanel pnlTagEditor = new TagEditorPanel(null, null, Changeset.MAX_CHANGESET_TAG_LENGTH); 027 /** the model for the changeset comment */ 028 private final transient ChangesetCommentModel changesetCommentModel; 029 private final transient ChangesetCommentModel changesetSourceModel; 030 031 /** 032 * Creates a new panel 033 * 034 * @param changesetCommentModel the changeset comment model. Must not be null. 035 * @param changesetSourceModel the changeset source model. Must not be null. 036 * @throws IllegalArgumentException if {@code changesetCommentModel} is null 037 */ 038 public TagSettingsPanel(ChangesetCommentModel changesetCommentModel, ChangesetCommentModel changesetSourceModel) { 039 CheckParameterUtil.ensureParameterNotNull(changesetCommentModel, "changesetCommentModel"); 040 CheckParameterUtil.ensureParameterNotNull(changesetSourceModel, "changesetSourceModel"); 041 this.changesetCommentModel = changesetCommentModel; 042 this.changesetSourceModel = changesetSourceModel; 043 this.changesetCommentModel.addObserver(new ChangesetCommentObserver("comment")); 044 this.changesetSourceModel.addObserver(new ChangesetCommentObserver("source")); 045 build(); 046 pnlTagEditor.getModel().addTableModelListener(this); 047 } 048 049 protected void build() { 050 setLayout(new BorderLayout()); 051 add(pnlTagEditor, BorderLayout.CENTER); 052 } 053 054 protected void setProperty(String key, String value) { 055 String val = (value == null ? "" : value).trim(); 056 String commentInTag = getTagEditorValue(key); 057 if (val.equals(commentInTag)) 058 return; 059 060 if (val.isEmpty()) { 061 pnlTagEditor.getModel().delete(key); 062 return; 063 } 064 TagModel tag = pnlTagEditor.getModel().get(key); 065 if (tag == null) { 066 tag = new TagModel(key, val); 067 pnlTagEditor.getModel().add(tag); 068 } else { 069 pnlTagEditor.getModel().updateTagValue(tag, val); 070 } 071 } 072 073 protected String getTagEditorValue(String key) { 074 TagModel tag = pnlTagEditor.getModel().get(key); 075 return tag == null ? null : tag.getValue(); 076 } 077 078 /** 079 * Initialize panel from the given tags. 080 * @param tags the tags used to initialize the panel 081 */ 082 public void initFromTags(Map<String, String> tags) { 083 pnlTagEditor.getModel().initFromTags(tags); 084 } 085 086 /** 087 * Replies the map with the current tags in the tag editor model. 088 * @param keepEmpty {@code true} to keep empty tags 089 * @return the map with the current tags in the tag editor model. 090 */ 091 public Map<String, String> getTags(boolean keepEmpty) { 092 return pnlTagEditor.getModel().getTags(keepEmpty); 093 } 094 095 /** 096 * Initializes the panel for user input 097 */ 098 public void startUserInput() { 099 pnlTagEditor.initAutoCompletion(Main.main.getEditLayer()); 100 } 101 102 /* -------------------------------------------------------------------------- */ 103 /* Interface TableChangeListener */ 104 /* -------------------------------------------------------------------------- */ 105 @Override 106 public void tableChanged(TableModelEvent e) { 107 changesetCommentModel.setComment(getTagEditorValue("comment")); 108 changesetSourceModel.setComment(getTagEditorValue("source")); 109 } 110 111 /** 112 * Observes the changeset comment model and keeps the tag editor in sync 113 * with the current changeset comment 114 */ 115 class ChangesetCommentObserver implements Observer { 116 117 private final String key; 118 119 ChangesetCommentObserver(String key) { 120 this.key = key; 121 } 122 123 @Override 124 public void update(Observable o, Object arg) { 125 if (o instanceof ChangesetCommentModel) { 126 String newValue = (String) arg; 127 String oldValue = getTagEditorValue(key); 128 if (oldValue == null) { 129 oldValue = ""; 130 } 131 if (!oldValue.equals(newValue)) { 132 setProperty(key, (String) arg); 133 } 134 } 135 } 136 } 137}