source: josm/trunk/src/org/openstreetmap/josm/gui/io/UploadTextComponentValidator.java

Last change on this file was 18782, checked in by taylor.smock, 9 months ago

Fix #23024: Set foreground color for feedback warning label (patch by Larsossum, modified)

This fixes an issue where a dark colour theme would use a light-coloured
foreground when we set the background colour to a light colour.

File size: 6.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.Collection;
7import java.util.Collections;
8import java.util.Objects;
9
10import javax.swing.JLabel;
11import javax.swing.text.JTextComponent;
12
13import org.openstreetmap.josm.data.osm.BBox;
14import org.openstreetmap.josm.data.osm.IPrimitive;
15import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
16import org.openstreetmap.josm.spi.preferences.Config;
17import org.openstreetmap.josm.tools.Utils;
18
19/**
20 * Input validators for {@link UploadDialog}
21 */
22abstract class UploadTextComponentValidator extends AbstractTextComponentValidator {
23 private final JLabel feedback;
24 protected boolean uploadRejected;
25
26 UploadTextComponentValidator(JTextComponent tc, JLabel feedback) {
27 super(tc);
28 this.feedback = feedback;
29 this.feedback.setOpaque(true);
30 validate();
31 }
32
33 @Override
34 protected void feedbackValid(String msg) {
35 msg = msg != null ? "<html>\u2714 " + msg : null;
36 super.feedbackValid(msg);
37 if (!Objects.equals(msg, feedback.getText())) {
38 feedback.setText(msg);
39 feedback.setForeground(VALID_COLOR);
40 feedback.setBackground(null);
41 feedback.setBorder(null);
42 }
43 }
44
45 @Override
46 protected void feedbackWarning(String msg) {
47 msg = msg != null ? "<html>" + msg : null;
48 super.feedbackWarning(msg);
49 if (!Objects.equals(msg, feedback.getText())) {
50 feedback.setText(msg);
51 feedback.setForeground(WARNING_FOREGROUND);
52 feedback.setBackground(WARNING_BACKGROUND);
53 feedback.setBorder(WARNING_BORDER);
54 }
55 }
56
57 @Override
58 public boolean isValid() {
59 throw new UnsupportedOperationException();
60 }
61
62 /**
63 * Determines if the input validator considers the violation bad enough to reject upload.
64 * @return {@code true} if the input validator considers the violation bad enough to reject upload
65 * @since 17238
66 */
67 public final boolean isUploadRejected() {
68 return uploadRejected;
69 }
70
71 /**
72 * Validator for the changeset {@code comment} tag
73 */
74 static class UploadCommentValidator extends UploadTextComponentValidator {
75
76 UploadCommentValidator(JTextComponent tc, JLabel feedback) {
77 super(tc, feedback);
78 }
79
80 @Override
81 public void validate() {
82 if (!Config.getPref().getBoolean("message.upload_comment_is_empty_or_very_short", true)) {
83 feedbackDisabled();
84 return;
85 }
86 final String uploadComment = getComponent().getText();
87 final String rejection = UploadDialog.UploadAction.validateUploadTag(uploadComment, "upload.comment",
88 Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
89
90 // Reject the upload if tags are required and are not in the input. If the tags exist or are not
91 // required, then check the length of the input and warn if it's too short (a short msg is not a rejection)
92 uploadRejected = rejection != null;
93
94 if (uploadRejected) {
95 feedbackWarning(tr("Your upload comment is <i>rejected</i>.") + "<br />" + rejection);
96 } else if (UploadDialog.UploadAction.isUploadCommentTooShort(uploadComment)) {
97 feedbackWarning(tr("Your upload comment is <i>empty</i>, or <i>very short</i>.<br /><br />" +
98 "This is technically allowed, but please consider that many users who are<br />" +
99 "watching changes in their area depend on meaningful changeset comments<br />" +
100 "to understand what is going on!<br /><br />" +
101 "If you spend a minute now to explain your change, you will make life<br />" +
102 "easier for many other mappers.").replace("<br />", " "));
103 } else {
104 feedbackValid(tr("Thank you for providing a changeset comment! " +
105 "This gives other mappers a better understanding of your intent."));
106 }
107 }
108 }
109
110 /**
111 * Validator for the changeset {@code source} tag
112 */
113 static class UploadSourceValidator extends UploadTextComponentValidator {
114
115 UploadSourceValidator(JTextComponent tc, JLabel feedback) {
116 super(tc, feedback);
117 }
118
119 @Override
120 public void validate() {
121 if (!Config.getPref().getBoolean("message.upload_source_is_empty", true)) {
122 feedbackDisabled();
123 return;
124 }
125 final String uploadSource = getComponent().getText();
126 final String rejection = UploadDialog.UploadAction.validateUploadTag(
127 uploadSource, "upload.source", Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
128
129 // Reject the upload only if tags are required and are not in the input. If the tags exist or are not
130 // required, then check the length of the input and warn if it's too short (a short msg is not a rejection)
131 uploadRejected = rejection != null;
132
133 if (uploadRejected) {
134 feedbackWarning(tr("Your changeset source is <i>rejected</i>.") + "<br />" + rejection);
135 } else if (Utils.isStripEmpty(uploadSource)) {
136 feedbackWarning(tr("You did not specify a source for your changes.<br />" +
137 "It is technically allowed, but this information helps<br />" +
138 "other users to understand the origins of the data.<br /><br />" +
139 "If you spend a minute now to explain your change, you will make life<br />" +
140 "easier for many other mappers.").replace("<br />", " "));
141 } else {
142 feedbackValid(tr("Thank you for providing the data source!"));
143 }
144 }
145 }
146
147 /**
148 * Validator for the changeset area
149 */
150 static class UploadAreaValidator extends UploadTextComponentValidator {
151 private double area = Double.NaN;
152
153 UploadAreaValidator(JTextComponent tc, JLabel feedback) {
154 super(tc, feedback);
155 }
156
157 void computeArea(Collection<? extends IPrimitive> primitives) {
158 this.area = primitives.stream()
159 .map(IPrimitive::getBBox)
160 .reduce(new BBox(), (b1, b2) -> {
161 b1.add(b2);
162 return b1;
163 }).area();
164 validate();
165 }
166
167 @Override
168 public void validate() {
169 if (Double.isFinite(area) && area <= Config.getPref().getDouble("upload.max-area", 3.)) {
170 feedbackValid(null);
171 } else {
172 feedbackWarning(tr("The bounding box of this changeset is very large – please consider splitting your changes!"));
173 }
174 }
175 }
176}
Note: See TracBrowser for help on using the repository browser.