001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.gui.io;
003
004 import static org.openstreetmap.josm.tools.I18n.tr;
005
006 import java.awt.BorderLayout;
007 import java.awt.GridBagLayout;
008 import java.awt.event.ActionEvent;
009 import java.awt.event.ActionListener;
010 import java.awt.event.FocusAdapter;
011 import java.awt.event.FocusEvent;
012 import java.awt.event.KeyEvent;
013 import java.awt.event.KeyListener;
014 import java.util.Collections;
015 import java.util.LinkedList;
016 import java.util.List;
017 import java.util.Observable;
018 import java.util.Observer;
019
020 import javax.swing.Action;
021 import javax.swing.BorderFactory;
022 import javax.swing.JLabel;
023 import javax.swing.JPanel;
024
025 import org.openstreetmap.josm.Main;
026 import org.openstreetmap.josm.data.osm.Changeset;
027 import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
028 import org.openstreetmap.josm.tools.CheckParameterUtil;
029 import org.openstreetmap.josm.tools.GBC;
030
031 /**
032 * BasicUploadSettingsPanel allows to enter the basic parameters required for uploading
033 * data.
034 *
035 */
036 public class BasicUploadSettingsPanel extends JPanel {
037 public static final String HISTORY_KEY = "upload.comment.history";
038 public static final String HISTORY_LAST_USED_KEY = "upload.comment.last-used";
039
040 /** the history combo box for the upload comment */
041 private HistoryComboBox hcbUploadComment;
042 /** the panel with a summary of the upload parameters */
043 private UploadParameterSummaryPanel pnlUploadParameterSummary;
044 /** the changset comment model */
045 private ChangesetCommentModel changesetCommentModel;
046
047 protected JPanel buildUploadCommentPanel() {
048 JPanel pnl = new JPanel();
049 pnl.setLayout(new GridBagLayout());
050 pnl.add(new JLabel(tr("Provide a brief comment for the changes you are uploading:")), GBC.eol().insets(0, 5, 10, 3));
051 hcbUploadComment = new HistoryComboBox();
052 hcbUploadComment.setToolTipText(tr("Enter an upload comment"));
053 hcbUploadComment.setMaxTextLength(Changeset.MAX_COMMENT_LENGTH);
054 List<String> cmtHistory = new LinkedList<String>(Main.pref.getCollection(HISTORY_KEY, new LinkedList<String>()));
055 // we have to reverse the history, because ComboBoxHistory will reverse it again
056 // in addElement()
057 //
058 Collections.reverse(cmtHistory);
059 hcbUploadComment.setPossibleItems(cmtHistory);
060 hcbUploadComment.getEditor().addActionListener(
061 new ActionListener() {
062 public void actionPerformed(ActionEvent e) {
063 changesetCommentModel.setComment(hcbUploadComment.getText());
064 }
065 }
066 );
067 hcbUploadComment.getEditor().getEditorComponent().addFocusListener(
068 new FocusAdapter() {
069 @Override
070 public void focusLost(FocusEvent e) {
071 changesetCommentModel.setComment(hcbUploadComment.getText());
072 }
073 }
074 );
075 pnl.add(hcbUploadComment, GBC.eol().fill(GBC.HORIZONTAL));
076 return pnl;
077 }
078
079 protected void build() {
080 setLayout(new BorderLayout());
081 setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
082 add(buildUploadCommentPanel(), BorderLayout.NORTH);
083 add(pnlUploadParameterSummary = new UploadParameterSummaryPanel(), BorderLayout.CENTER);
084 }
085
086 /**
087 * Creates the panel
088 *
089 * @param changesetCommentModel the model for the changeset comment. Must not be null
090 * @throws IllegalArgumentException thrown if {@code changesetCommentModel} is null
091 */
092 public BasicUploadSettingsPanel(ChangesetCommentModel changesetCommentModel) {
093 CheckParameterUtil.ensureParameterNotNull(changesetCommentModel, "changesetCommentModel");
094 this.changesetCommentModel = changesetCommentModel;
095 changesetCommentModel.addObserver(new ChangesetCommentObserver());
096 build();
097 }
098
099 public void setUploadCommentDownFocusTraversalHandler(final Action handler) {
100 hcbUploadComment.getEditor().addActionListener(handler);
101 hcbUploadComment.getEditor().getEditorComponent().addKeyListener(
102 new KeyListener() {
103 public void keyTyped(KeyEvent e) {
104 if (e.getKeyCode() == KeyEvent.VK_TAB) {
105 handler.actionPerformed(new ActionEvent(hcbUploadComment,0, "focusDown"));
106 }
107 }
108 public void keyReleased(KeyEvent e) {}
109
110 public void keyPressed(KeyEvent e) {}
111 }
112 );
113 }
114
115 /**
116 * Remembers the user input in the preference settings
117 */
118 public void rememberUserInput() {
119 // store the history of comments
120 hcbUploadComment.addCurrentItemToHistory();
121 Main.pref.putCollection(HISTORY_KEY, hcbUploadComment.getHistory());
122 Main.pref.putInteger(HISTORY_LAST_USED_KEY, (int) (System.currentTimeMillis() / 1000));
123 }
124
125 /**
126 * Initializes the panel for user input
127 */
128 public void startUserInput() {
129 List<String> history = hcbUploadComment.getHistory();
130 int age = (int) (System.currentTimeMillis()/1000 - Main.pref.getInteger(HISTORY_LAST_USED_KEY, 0));
131 // only pre-select latest entry if used less than 4 hours ago.
132 if (age < 4 * 3600 * 1000 && history != null && !history.isEmpty()) {
133 hcbUploadComment.setText(history.get(0));
134 }
135 hcbUploadComment.requestFocusInWindow();
136 hcbUploadComment.getEditor().getEditorComponent().requestFocusInWindow();
137 }
138
139 public void initEditingOfUploadComment() {
140 hcbUploadComment.getEditor().selectAll();
141 hcbUploadComment.requestFocusInWindow();
142 }
143
144 public UploadParameterSummaryPanel getUploadParameterSummaryPanel() {
145 return pnlUploadParameterSummary;
146 }
147
148 /**
149 * Observes the changeset comment model and keeps the comment input field
150 * in sync with the current changeset comment
151 */
152 class ChangesetCommentObserver implements Observer {
153 public void update(Observable o, Object arg) {
154 if (!(o instanceof ChangesetCommentModel)) return;
155 String newComment = (String)arg;
156 if (!hcbUploadComment.getText().equals(newComment)) {
157 hcbUploadComment.setText(newComment);
158 }
159 }
160 }
161 }