Changeset 18839 in josm for trunk


Ignore:
Timestamp:
2023-09-21T19:04:05+02:00 (14 months ago)
Author:
taylor.smock
Message:

Fix #23179: Include changeset in note comment if feasible (patch by qeef, modified)

Modifications are as follows:

  • Unit tests
  • Better note matching
  • Find multiple changesets referring the same note
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/NoteInputDialog.java

    r16435 r18839  
    4545     */
    4646    public void showNoteDialog(String message, Icon icon) {
     47        showNoteDialog(message, icon, "");
     48    }
     49
     50    /**
     51     * Displays the dialog to the user
     52     * @param message Translated message to display to the user as input prompt
     53     * @param icon Icon to display in the action button
     54     * @param text Default text of the note's comment
     55     * @since xxx
     56     */
     57    public void showNoteDialog(String message, Icon icon, String text) {
     58        textArea.setText(text);
    4759        textArea.setRows(6);
    4860        textArea.setColumns(30);
  • trunk/src/org/openstreetmap/josm/gui/dialogs/NotesDialog.java

    r18715 r18839  
    1515import java.util.Arrays;
    1616import java.util.Collection;
     17import java.util.Collections;
    1718import java.util.List;
    1819import java.util.Objects;
    1920import java.util.function.Predicate;
     21import java.util.regex.Matcher;
    2022import java.util.regex.Pattern;
    2123import java.util.stream.Collectors;
     
    4143import org.openstreetmap.josm.data.notes.Note.State;
    4244import org.openstreetmap.josm.data.notes.NoteComment;
     45import org.openstreetmap.josm.data.osm.Changeset;
     46import org.openstreetmap.josm.data.osm.ChangesetCache;
    4347import org.openstreetmap.josm.data.osm.NoteData;
    4448import org.openstreetmap.josm.data.osm.NoteData.NoteDataUpdateListener;
     
    5862import org.openstreetmap.josm.gui.widgets.JosmTextField;
    5963import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
     64import org.openstreetmap.josm.io.OsmApi;
    6065import org.openstreetmap.josm.spi.preferences.Config;
    6166import org.openstreetmap.josm.tools.ImageProvider;
     
    423428        @Override
    424429        public void actionPerformed(ActionEvent e) {
     430            Note note = displayList.getSelectedValue();
     431            final List<String> changesetUrls = note == null ? Collections.emptyList() : getRelatedChangesetUrls(note.getId());
    425432            NoteInputDialog dialog = new NoteInputDialog(MainApplication.getMainFrame(), tr("Close note"), tr("Close note"));
    426             dialog.showNoteDialog(tr("Close note with message:"), ImageProvider.get("dialogs/notes", "note_closed"));
     433            dialog.showNoteDialog(tr("Close note with message:"), ImageProvider.get("dialogs/notes", "note_closed"),
     434                    String.join("\n", changesetUrls));
    427435            if (dialog.getValue() != 1) {
    428436                return;
    429437            }
    430             Note note = displayList.getSelectedValue();
    431438            if (note != null) {
    432439                int selectedIndex = displayList.getSelectedIndex();
     
    443450
    444451    /**
     452     * Get a list of changeset urls that may have fixed a note
     453     * @param noteId The note ID to look for
     454     * @return A list of changeset URLs
     455     */
     456    static List<String> getRelatedChangesetUrls(long noteId) {
     457        final List<String> changesetUrls = new ArrayList<>();
     458        final int patternFlags = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CHARACTER_CLASS;
     459        final Matcher noteMatcher = Pattern.compile("note " + noteId + "( |$)", patternFlags).matcher("");
     460        final Matcher shortOsmMatcher = Pattern.compile("osm.org/note/" + noteId + "( |$)", patternFlags).matcher("");
     461        final String hostUrl = Pattern.compile("https?://(www\\.)?")
     462                .matcher(Config.getUrls().getBaseBrowseUrl())
     463                .replaceFirst("");
     464        final Matcher longOsmMatcher = Pattern.compile(hostUrl + "/note/" + noteId + "( |$)", patternFlags).matcher("");
     465        final boolean isUsingDefaultOsmApi = Config.getUrls().getDefaultOsmApiUrl().equals(OsmApi.getOsmApi().getServerUrl());
     466        for (Changeset cs: ChangesetCache.getInstance().getChangesets()) {
     467            final String comment = cs.getComment();
     468            if ((isUsingDefaultOsmApi && (shortOsmMatcher.reset(comment).find() || noteMatcher.reset(comment).find()))
     469                    || longOsmMatcher.reset(comment).find()) {
     470                changesetUrls.add(Config.getUrls().getBaseBrowseUrl() + "/changeset/" + cs.getId());
     471            }
     472        }
     473        return changesetUrls;
     474    }
     475
     476    /**
    445477     * Create a new note
    446478     */
  • trunk/test/unit/org/openstreetmap/josm/gui/dialogs/NotesDialogTest.java

    r18454 r18839  
    99
    1010import java.time.Instant;
     11import java.util.Arrays;
    1112import java.util.Collections;
     13import java.util.List;
     14import java.util.stream.Stream;
    1215
    1316import javax.swing.JLabel;
     
    1619import org.junit.jupiter.api.Test;
    1720import org.junit.jupiter.api.extension.RegisterExtension;
     21import org.junit.jupiter.params.ParameterizedTest;
     22import org.junit.jupiter.params.provider.Arguments;
     23import org.junit.jupiter.params.provider.MethodSource;
    1824import org.junit.platform.commons.util.ReflectionUtils;
    1925import org.openstreetmap.josm.TestUtils;
     
    2127import org.openstreetmap.josm.data.notes.Note;
    2228import org.openstreetmap.josm.data.notes.NoteComment;
     29import org.openstreetmap.josm.data.osm.Changeset;
     30import org.openstreetmap.josm.data.osm.ChangesetCache;
    2331import org.openstreetmap.josm.data.osm.User;
    2432import org.openstreetmap.josm.gui.ExtendedDialog;
     
    2735import org.openstreetmap.josm.gui.layer.NoteLayer;
    2836import org.openstreetmap.josm.gui.widgets.JosmTextField;
     37import org.openstreetmap.josm.spi.preferences.Config;
    2938import org.openstreetmap.josm.testutils.JOSMTestRules;
    3039import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
     
    97106        assertDoesNotThrow(() -> closeAction.actionPerformed(null));
    98107    }
     108
     109    static Stream<Arguments> testCloseActionGetRelatedChangesetUrls() {
     110        return Stream.of(
     111                Arguments.of(1, 0, Collections.singletonList("/note/123")),
     112                Arguments.of(1, 0, Collections.singletonList("/note/231")),
     113                Arguments.of(1, 1, Collections.singletonList("/note/1")),
     114                Arguments.of(1, 2, Arrays.asList("/note/1", "/note/1 again")),
     115                Arguments.of(1, 2, Arrays.asList("/note/1", "/note/1 again", "/note/12 here")),
     116                Arguments.of(1, 2, Arrays.asList("/note/1", "/note/12 again", "/note/1 here")),
     117                Arguments.of(1, 2, Arrays.asList("/note/12", "/note/1 again", "/note/1 here")),
     118                Arguments.of(1, 3, Arrays.asList("/note/1", "/note/1 again", "/note/1 here")),
     119                Arguments.of(1, 3, Arrays.asList("note 1", "note 1 again", "note 1 here"))
     120        );
     121    }
     122
     123    @ParameterizedTest
     124    @MethodSource
     125    void testCloseActionGetRelatedChangesetUrls(long noteId, int expectedChangesets, List<String> changesetComments) {
     126        try {
     127            Config.getPref().put("osm-server.url", null);
     128            final String[] apiList = {"osm.org", "openstreetmap.org", Config.getUrls().getBaseBrowseUrl()};
     129            for (int i = 0; i < changesetComments.size(); i++) {
     130                final String comment = changesetComments.get(i);
     131                final Changeset cs = new Changeset(i + 1);
     132                cs.put("comment", apiList[i % 3] + comment);
     133                ChangesetCache.getInstance().update(cs);
     134            }
     135            final List<String> changesetUrls = NotesDialog.getRelatedChangesetUrls(noteId);
     136            assertEquals(expectedChangesets, changesetUrls.size());
     137        } finally {
     138            ChangesetCache.getInstance().clear();
     139        }
     140    }
    99141}
  • trunk/test/unit/org/openstreetmap/josm/gui/dialogs/layer/DeleteLayerActionTest.java

    r18837 r18839  
     1// License: GPL. For details, see LICENSE file.
    12package org.openstreetmap.josm.gui.dialogs.layer;
    23
Note: See TracChangeset for help on using the changeset viewer.