Changeset 16672 in josm for trunk/src/org
- Timestamp:
- 2020-06-17T21:47:17+02:00 (4 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/io/BasicUploadSettingsPanel.java
r16237 r16672 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.BorderLayout;7 6 import java.awt.GridBagLayout; 8 7 import java.awt.event.ActionEvent; … … 20 19 21 20 import javax.swing.BorderFactory; 21 import javax.swing.BoxLayout; 22 22 import javax.swing.JCheckBox; 23 23 import javax.swing.JEditorPane; … … 76 76 protected JPanel buildUploadCommentPanel() { 77 77 JPanel pnl = new JPanel(new GridBagLayout()); 78 pnl.setBorder(BorderFactory.createTitledBorder(tr("Tags of changeset {0}", ""))); 79 80 JEditorPane commentLabel = new JMultilineLabel("<html><b>" + tr("Provide a brief comment for the changes you are uploading:")); 81 pnl.add(commentLabel, GBC.eol().insets(0, 5, 10, 3).fill(GBC.HORIZONTAL)); 78 pnl.setBorder(BorderFactory.createTitledBorder(tr("Provide a brief comment for the changes you are uploading:"))); 79 82 80 hcbUploadComment.setToolTipText(tr("Enter an upload comment")); 83 81 hcbUploadComment.setMaxTextLength(Changeset.MAX_CHANGESET_TAG_LENGTH); … … 87 85 hcbUploadComment.getEditorComponent().addFocusListener(commentModelListener); 88 86 pnl.add(hcbUploadComment, GBC.eol().fill(GBC.HORIZONTAL)); 89 90 JEditorPane sourceLabel = new JMultilineLabel("<html><b>" + tr("Specify the data source for the changes") + ":</b>"); 91 pnl.add(sourceLabel, GBC.eol().insets(0, 8, 10, 0).fill(GBC.HORIZONTAL)); 87 JLabel hcbUploadCommentFeedback = new JLabel(); 88 pnl.add(hcbUploadCommentFeedback, GBC.eol().insets(0, 3, 0, 0).fill(GBC.HORIZONTAL)); 89 new UploadTextComponentValidator.UploadCommentValidator(hcbUploadComment.getEditorComponent(), hcbUploadCommentFeedback); 90 return pnl; 91 } 92 93 protected JPanel buildUploadSourcePanel() { 94 JPanel pnl = new JPanel(new GridBagLayout()); 95 pnl.setBorder(BorderFactory.createTitledBorder(tr("Specify the data source for the changes"))); 96 92 97 JEditorPane obtainSourceOnce = new JMultilineLabel( 93 98 "<html>(<a href=\"urn:changeset-source\">" + tr("just once") + "</a>)</html>"); … … 119 124 hcbUploadSource.getEditorComponent().addFocusListener(sourceModelListener); 120 125 pnl.add(hcbUploadSource, GBC.eol().fill(GBC.HORIZONTAL)); 126 JLabel hcbUploadSourceFeedback = new JLabel(); 127 pnl.add(hcbUploadSourceFeedback, GBC.eol().insets(0, 3, 0, 0).fill(GBC.HORIZONTAL)); 128 new UploadTextComponentValidator.UploadSourceValidator(hcbUploadSource.getEditorComponent(), hcbUploadSourceFeedback); 121 129 if (obtainSourceAutomatically.isSelected()) { 122 130 automaticallyAddSource(); … … 181 189 182 190 protected void build() { 183 setLayout(new Bo rderLayout());191 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 184 192 setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); 185 add(buildUploadCommentPanel(), BorderLayout.NORTH); 186 add(pnlUploadParameterSummary, BorderLayout.CENTER); 193 add(buildUploadCommentPanel()); 194 add(buildUploadSourcePanel()); 195 add(pnlUploadParameterSummary); 187 196 if (Config.getPref().getBoolean("upload.show.review.request", true)) { 188 add(cbRequestReview, BorderLayout.SOUTH); 197 JPanel pnl = new JPanel(new GridBagLayout()); 198 pnl.add(cbRequestReview, GBC.eol().fill(GBC.HORIZONTAL)); 199 add(pnl); 189 200 cbRequestReview.addItemListener(e -> changesetReviewModel.setReviewRequested(e.getStateChange() == ItemEvent.SELECTED)); 190 201 } -
trunk/src/org/openstreetmap/josm/gui/io/UploadDialog.java
r16468 r16672 17 17 import java.lang.Character.UnicodeBlock; 18 18 import java.util.ArrayList; 19 import java.util.Arrays;20 19 import java.util.Collection; 21 20 import java.util.Collections; … … 30 29 import javax.swing.AbstractAction; 31 30 import javax.swing.BorderFactory; 32 import javax.swing.Icon;33 31 import javax.swing.JButton; 34 32 import javax.swing.JOptionPane; … … 41 39 import org.openstreetmap.josm.data.osm.DataSet; 42 40 import org.openstreetmap.josm.data.osm.OsmPrimitive; 43 import org.openstreetmap.josm.gui.ExtendedDialog;44 41 import org.openstreetmap.josm.gui.HelpAwareOptionPane; 45 42 import org.openstreetmap.josm.gui.MainApplication; … … 57 54 import org.openstreetmap.josm.spi.preferences.Setting; 58 55 import org.openstreetmap.josm.tools.GBC; 59 import org.openstreetmap.josm.tools.ImageOverlay;60 56 import org.openstreetmap.josm.tools.ImageProvider; 61 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;62 57 import org.openstreetmap.josm.tools.InputMapUtils; 63 58 import org.openstreetmap.josm.tools.Utils; … … 450 445 } 451 446 452 /**453 * Displays a warning message indicating that the upload comment is empty/short.454 * @return true if the user wants to revisit, false if they want to continue455 */456 protected boolean warnUploadComment() {457 return warnUploadTag(458 tr("Please revise upload comment"),459 tr("Your upload comment is <i>empty</i>, or <i>very short</i>.<br /><br />" +460 "This is technically allowed, but please consider that many users who are<br />" +461 "watching changes in their area depend on meaningful changeset comments<br />" +462 "to understand what is going on!<br /><br />" +463 "If you spend a minute now to explain your change, you will make life<br />" +464 "easier for many other mappers."),465 "upload_comment_is_empty_or_very_short"466 );467 }468 469 /**470 * Displays a warning message indicating that no changeset source is given.471 * @return true if the user wants to revisit, false if they want to continue472 */473 protected boolean warnUploadSource() {474 return warnUploadTag(475 tr("Please specify a changeset source"),476 tr("You did not specify a source for your changes.<br />" +477 "It is technically allowed, but this information helps<br />" +478 "other users to understand the origins of the data.<br /><br />" +479 "If you spend a minute now to explain your change, you will make life<br />" +480 "easier for many other mappers."),481 "upload_source_is_empty"482 );483 }484 485 /**486 * Displays a warning message indicating that the upload comment is rejected.487 * @param details details explaining why488 * @return {@code true}489 */490 protected boolean warnRejectedUploadComment(String details) {491 return warnRejectedUploadTag(492 tr("Please revise upload comment"),493 tr("Your upload comment is <i>rejected</i>.") + "<br />" + details494 );495 }496 497 /**498 * Displays a warning message indicating that the changeset source is rejected.499 * @param details details explaining why500 * @return {@code true}501 */502 protected boolean warnRejectedUploadSource(String details) {503 return warnRejectedUploadTag(504 tr("Please revise changeset source"),505 tr("Your changeset source is <i>rejected</i>.") + "<br />" + details506 );507 }508 509 /**510 * Warn about an upload tag with the possibility of resuming the upload.511 * @param title dialog title512 * @param message dialog message513 * @param togglePref preference entry to offer the user a "Do not show again" checkbox for the dialog514 * @return {@code true} if the user wants to revise the upload tag515 */516 protected boolean warnUploadTag(final String title, final String message, final String togglePref) {517 return warnUploadTag(title, message, togglePref, true);518 }519 520 /**521 * Warn about an upload tag without the possibility of resuming the upload.522 * @param title dialog title523 * @param message dialog message524 * @return {@code true}525 */526 protected boolean warnRejectedUploadTag(final String title, final String message) {527 return warnUploadTag(title, message, null, false);528 }529 530 private boolean warnUploadTag(final String title, final String message, final String togglePref, boolean allowContinue) {531 List<String> buttonTexts = new ArrayList<>(Arrays.asList(tr("Revise"), tr("Cancel")));532 List<Icon> buttonIcons = new ArrayList<>(Arrays.asList(533 new ImageProvider("ok").setMaxSize(ImageSizes.LARGEICON).get(),534 new ImageProvider("cancel").setMaxSize(ImageSizes.LARGEICON).get()));535 List<String> tooltips = new ArrayList<>(Arrays.asList(536 tr("Return to the previous dialog to enter a more descriptive comment"),537 tr("Cancel and return to the previous dialog")));538 if (allowContinue) {539 buttonTexts.add(tr("Continue as is"));540 buttonIcons.add(new ImageProvider("upload").setMaxSize(ImageSizes.LARGEICON).addOverlay(541 new ImageOverlay(new ImageProvider("warning-small"), 0.5, 0.5, 1.0, 1.0)).get());542 tooltips.add(tr("Ignore this hint and upload anyway"));543 }544 545 ExtendedDialog dlg = new ExtendedDialog((Component) dialog, title, buttonTexts.toArray(new String[] {})) {546 @Override547 public void setupDialog() {548 super.setupDialog();549 InputMapUtils.addCtrlEnterAction(getRootPane(), buttons.get(buttons.size() - 1).getAction());550 }551 };552 dlg.setContent("<html>" + message + "</html>");553 dlg.setButtonIcons(buttonIcons.toArray(new Icon[] {}));554 dlg.setToolTipTexts(tooltips.toArray(new String[] {}));555 dlg.setIcon(JOptionPane.WARNING_MESSAGE);556 if (allowContinue) {557 dlg.toggleEnable(togglePref);558 }559 dlg.setCancelButton(1, 2);560 return dlg.showDialog().getValue() != 3;561 }562 563 447 protected void warnIllegalChunkSize() { 564 448 HelpAwareOptionPane.showOptionDialog( … … 614 498 // force update of model in case dialog is closed before focus lost event, see #17452 615 499 dialog.forceUpdateActiveField(); 616 617 final List<String> def = Collections.emptyList();618 final String uploadComment = dialog.getUploadComment();619 final String uploadCommentRejection = validateUploadTag(620 uploadComment, "upload.comment", def, def, def);621 if ((isUploadCommentTooShort(uploadComment) && warnUploadComment()) ||622 (uploadCommentRejection != null && warnRejectedUploadComment(uploadCommentRejection))) {623 // abort for missing or rejected comment624 dialog.handleMissingComment();625 return;626 }627 final String uploadSource = dialog.getUploadSource();628 final String uploadSourceRejection = validateUploadTag(629 uploadSource, "upload.source", def, def, def);630 if ((Utils.isStripEmpty(uploadSource) && warnUploadSource()) ||631 (uploadSourceRejection != null && warnRejectedUploadSource(uploadSourceRejection))) {632 // abort for missing or rejected changeset source633 dialog.handleMissingSource();634 return;635 }636 500 637 501 /* test for empty tags in the changeset metadata and proceed only after user's confirmation. -
trunk/src/org/openstreetmap/josm/gui/widgets/AbstractTextComponentValidator.java
r16553 r16672 33 33 */ 34 34 public abstract class AbstractTextComponentValidator implements ActionListener, FocusListener, DocumentListener, PropertyChangeListener { 35 private static final Border ERROR_BORDER = BorderFactory.createLineBorder(Color.RED, 1); 36 private static final Color ERROR_BACKGROUND = new Color(255, 224, 224); 37 38 private JTextComponent tc; 39 /** remembers whether the content of the text component is currently valid or not; null means, 40 * we don't know yet 41 */ 42 private Boolean valid; 35 protected static final Color ERROR_COLOR = Color.RED; 36 protected static final Border ERROR_BORDER = BorderFactory.createLineBorder(ERROR_COLOR, 1); 37 protected static final Color ERROR_BACKGROUND = new Color(0xFFCCCC); 38 protected static final Color WARNING_COLOR = new Color(0xFFA500); 39 protected static final Border WARNING_BORDER = BorderFactory.createLineBorder(WARNING_COLOR, 1); 40 protected static final Color WARNING_BACKGROUND = new Color(0xFFEDCC); 41 protected static final Color VALID_COLOR = new Color(0x008000); 42 protected static final Border VALID_BORDER = BorderFactory.createLineBorder(VALID_COLOR, 1); 43 44 private final JTextComponent tc; 45 // remembers whether the content of the text component is currently valid or not; null means, we don't know yet 46 private Status status; 43 47 // remember the message 44 48 private String msg; 45 49 50 enum Status { 51 INVALID, WARNING, VALID 52 } 53 46 54 protected void feedbackInvalid(String msg) { 47 if ( valid == null || valid || !Objects.equals(msg, this.msg)) {55 if (hasChanged(msg, Status.INVALID)) { 48 56 // only provide feedback if the validity has changed. This avoids unnecessary UI updates. 49 57 tc.setBorder(ERROR_BORDER); 50 58 tc.setBackground(ERROR_BACKGROUND); 51 59 tc.setToolTipText(msg); 52 valid = Boolean.FALSE; 60 this.status = Status.INVALID; 61 this.msg = msg; 62 } 63 } 64 65 protected void feedbackWarning(String msg) { 66 if (hasChanged(msg, Status.WARNING)) { 67 // only provide feedback if the validity has changed. This avoids unnecessary UI updates. 68 tc.setBorder(WARNING_BORDER); 69 tc.setBackground(WARNING_BACKGROUND); 70 tc.setToolTipText(msg); 71 this.status = Status.WARNING; 53 72 this.msg = msg; 54 73 } … … 60 79 61 80 protected void feedbackValid(String msg) { 62 if ( valid == null || !valid || !Objects.equals(msg, this.msg)) {81 if (hasChanged(msg, Status.VALID)) { 63 82 // only provide feedback if the validity has changed. This avoids unnecessary UI updates. 64 tc.setBorder( UIManager.getBorder("TextField.border"));83 tc.setBorder(VALID_BORDER); 65 84 tc.setBackground(UIManager.getColor("TextField.background")); 66 85 tc.setToolTipText(msg == null ? "" : msg); 67 valid = Boolean.TRUE;86 this.status = Status.VALID; 68 87 this.msg = msg; 69 88 } 89 } 90 91 private boolean hasChanged(String msg, Status status) { 92 return !(Objects.equals(status, this.status) && Objects.equals(msg, this.msg)); 70 93 } 71 94
Note:
See TracChangeset
for help on using the changeset viewer.