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 }