Ticket #20376: add_validation_info_to_middle_mouse_click_popup.patch

File add_validation_info_to_middle_mouse_click_popup.patch, 9.2 KB (added by mzagorski, 5 years ago)
  • src/org/openstreetmap/josm/gui/MapStatus.java

     
    8989import org.openstreetmap.josm.data.preferences.BooleanProperty;
    9090import org.openstreetmap.josm.data.preferences.DoubleProperty;
    9191import org.openstreetmap.josm.data.preferences.NamedColorProperty;
     92import org.openstreetmap.josm.data.validation.TestError;
    9293import org.openstreetmap.josm.gui.NavigatableComponent.ZoomChangeListener;
    9394import org.openstreetmap.josm.gui.help.Helpful;
    9495import org.openstreetmap.josm.gui.progress.swing.PleaseWaitProgressMonitor;
     
    104105import org.openstreetmap.josm.tools.GBC;
    105106import org.openstreetmap.josm.tools.ImageProvider;
    106107import org.openstreetmap.josm.tools.Logging;
     108import org.openstreetmap.josm.tools.MultiMap;
    107109import org.openstreetmap.josm.tools.SubclassFilteredCollection;
    108110import org.openstreetmap.josm.tools.Utils;
    109111
     
    119121 * nothing instead of whining and complaining.
    120122 *
    121123 * @author imi
     124 *
     125 * Change log:
     126 *      12-11-2019 @author Milla Zagorski: added validation results information to popup.
     127 *
    122128 */
    123129public final class MapStatus extends JPanel implements
    124130    Helpful, Destroyable, PreferenceChangedListener, SoMChangeListener, DataSelectionListener, DataSetListener, ZoomChangeListener {
     
    355361                    if (middleMouseDown || isAtOldPosition) {
    356362                        Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos, OsmPrimitive::isSelectable);
    357363
     364                        // Create validation info multimap
     365                        Collection<TestError> errors = MainApplication.getMap().validatorDialog.tree.getErrors();
     366                        MultiMap<Long, String> valInfoMultiMap = new MultiMap<>();
     367                        if (!errors.isEmpty()) {
     368                            for (TestError error : errors) {
     369                                for (OsmPrimitive prim : error.getPrimitives()) {
     370                                    String valInfo = error.getSeverity() + ": (#" + error.getCode() + ") "
     371                                            + error.getMessage();
     372                                    if (error.getDescription() != null) {
     373                                        valInfo += " | " + error.getDescription();
     374                                    }
     375                                    valInfoMultiMap.put(prim.getUniqueId(), valInfo);
     376                                }
     377                            }
     378                        }
     379
    358380                        final JPanel c = new JPanel(new GridBagLayout());
    359381                        final JLabel lbl = new JLabel(
    360382                                "<html>"+tr("Middle click again to cycle through.<br>"+
     
    376398                        // These labels may need to be updated from the outside so collect them
    377399                        List<JLabel> lbls = new ArrayList<>(osms.size());
    378400                        for (final OsmPrimitive osm : osms) {
     401
     402                            // Collect validation information
     403                            Collection<String> valInfoCollection = null;
     404                            if (!valInfoMultiMap.isEmpty()) {
     405                                for (Long key : valInfoMultiMap.keySet()) {
     406                                    if (key.equals(osm.getUniqueId())) {
     407                                        valInfoCollection = valInfoMultiMap.getValues(key);
     408                                    }
     409                                }
     410                            }
     411                            List<String> valInfoList = new ArrayList<>();
     412                            if (valInfoCollection != null) {
     413                                List<String> valErrors = new ArrayList<>();
     414                                List<String> valWarnings = new ArrayList<>();
     415                                List<String> valOther = new ArrayList<>();
     416                                for (String valInfo : valInfoCollection) {
     417                                    if (valInfo.startsWith("Errors")) {
     418                                        valInfo = valInfo.replaceFirst("Errors", "Error");
     419                                        valErrors.add(valInfo);
     420                                    }
     421                                    if (valInfo.startsWith("Warnings")) {
     422                                        valInfo = valInfo.replaceFirst("Warnings", "Warning");
     423                                        valWarnings.add(valInfo);
     424                                    }
     425                                    if (valInfo.startsWith("Other")) {
     426                                        valOther.add(valInfo);
     427                                    }
     428                                }
     429                                if (!valErrors.isEmpty()) {
     430                                    List<String> valErrorsSorted = valErrors.stream()
     431                                            .sorted(Comparator.comparing((String e) -> e.split(" ",0)[2].toUpperCase()))
     432                                            .collect(Collectors.toCollection(ArrayList::new));
     433                                    valInfoList.addAll(valErrorsSorted);
     434                                }
     435
     436                                if (!valWarnings.isEmpty()) {
     437                                    List<String> valWarningsSorted = valWarnings.stream()
     438                                            .sorted(Comparator.comparing((String e) -> e.split(" ",0)[2].toUpperCase()))
     439                                            .collect(Collectors.toCollection(ArrayList::new));
     440                                    valInfoList.addAll(valWarningsSorted);
     441                                }
     442
     443                                if (!valOther.isEmpty()) {
     444                                    List<String> valOtherSorted = valOther.stream()
     445                                            .sorted(Comparator.comparing((String e) -> e.split(" ",0)[2].toUpperCase()))
     446                                            .collect(Collectors.toCollection(ArrayList::new));
     447                                    valInfoList.addAll(valOtherSorted);
     448                                }
     449                            }
     450
    379451                            JLabel l = popupBuildPrimitiveLabels(osm);
    380452                            lbls.add(l);
    381453                            c.add(l, GBC.eol().fill(GBC.HORIZONTAL).insets(2, 0, 2, 2));
     454
     455                            if (!valInfoList.isEmpty()) {
     456                                JLabel k = popupBuildValidationLabels(osm, valInfoList);
     457                                if (k != null) {
     458                                    lbls.add(k);
     459                                    c.add(k, GBC.eol().fill(GBC.HORIZONTAL).insets(2, 0, 2, 2));
     460                                }
     461                            }
    382462                        }
    383463
    384464                        popupShowPopup(popupCreatePopup(c, ms), lbls);
     
    637717                text.append(" [id=").append(osm.getId()).append(']');
    638718            }
    639719
     720            if (osm.isNew() && !idShown) {
     721                text.append("<br>").append("This new feature has not been uploaded").append("<br>");
     722                text.append(" [temporary id=").append(osm.getUniqueId()).append(']');
     723            }
     724
    640725            if (osm.getUser() != null) {
    641726                text.append(" [").append(tr("User:")).append(' ')
    642727                    .append(Utils.escapeReservedCharactersHTML(osm.getUser().getName())).append(']');
     
    700785                 }
    701786            });
    702787            return l;
     788
    703789        }
    704790
    705791        /**
     792         * Builds labels with all necessary listeners for the info popup for the
     793         * given OsmPrimitive and corresponding validation information.
     794         * @author Milla Zagorski
     795         * @param osm  The primitive to create the label for
     796         * @param valInfoList  The list of validation results information
     797         * @return labels for validation info popup
     798         */
     799        private JLabel popupBuildValidationLabels(OsmPrimitive osm, List<String> valInfoList) {
     800            final StringBuilder valText = new StringBuilder(32);
     801
     802            if (valInfoList != null) {
     803                valText.append("Validation information:");
     804                for (String info : valInfoList) {
     805                    valText.append("<br>&nbsp;&nbsp;&nbsp;&nbsp;").append(info);
     806                }
     807
     808                JLabel l = new JLabel("<html>" + valText.toString() + "</html>",
     809                        ImageProvider.get("layer", "validator_small"), JLabel.HORIZONTAL);
     810                l.setOpaque(true);
     811                popupSetLabelColors(l, osm);
     812                l.setFont(l.getFont().deriveFont(Font.PLAIN));
     813                l.setVerticalTextPosition(JLabel.TOP);
     814                l.setHorizontalAlignment(JLabel.LEFT);
     815                l.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
     816                return l;
     817            } else {
     818                return null;
     819            }
     820        }
     821
     822        /**
    706823         * Called whenever the mouse position or modifiers changed.
    707824         * @param mousePos The new mouse position. <code>null</code> if it did not change.
    708825         * @param modifiers The new modifiers.