001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.dialogs.properties; 003 004import java.awt.event.ActionEvent; 005import java.util.Arrays; 006import java.util.Collection; 007import java.util.Objects; 008import java.util.function.IntFunction; 009import java.util.function.Supplier; 010import java.util.stream.Collectors; 011import java.util.stream.Stream; 012 013import javax.swing.AbstractAction; 014import javax.swing.JTable; 015 016import org.openstreetmap.josm.data.osm.Tagged; 017import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils; 018import org.openstreetmap.josm.tools.Utils; 019 020/** 021 * Super class of all copy actions from tag table. 022 * @since 13521 023 */ 024public abstract class AbstractCopyAction extends AbstractAction { 025 026 private final JTable tagTable; 027 private final IntFunction<String> keySupplier; 028 private final Supplier<Collection<? extends Tagged>> objectSupplier; 029 030 /** 031 * Constructs a new {@code AbstractCopyAction}. 032 * @param tagTable the tag table 033 * @param keySupplier a supplier which returns the selected key for a given row index 034 * @param objectSupplier a supplier which returns the selected tagged object(s) 035 */ 036 protected AbstractCopyAction(JTable tagTable, IntFunction<String> keySupplier, Supplier<Collection<? extends Tagged>> objectSupplier) { 037 this.tagTable = Objects.requireNonNull(tagTable); 038 this.keySupplier = Objects.requireNonNull(keySupplier); 039 this.objectSupplier = Objects.requireNonNull(objectSupplier); 040 } 041 042 protected abstract Collection<String> getString(Tagged p, String key); 043 044 protected Stream<String> valueStream() { 045 int[] rows = tagTable.getSelectedRows(); 046 Collection<? extends Tagged> sel = objectSupplier.get(); 047 if (rows.length == 0 || Utils.isEmpty(sel)) return Stream.empty(); 048 return Arrays.stream(rows) 049 .mapToObj(keySupplier) 050 .flatMap(key -> sel.stream().map(p -> getString(p, key))) 051 .filter(Objects::nonNull) 052 .flatMap(Collection::stream) 053 .distinct(); 054 } 055 056 @Override 057 public void actionPerformed(ActionEvent ae) { 058 final String values = valueStream() 059 .sorted() 060 .collect(Collectors.joining("\n")); 061 if (!values.isEmpty()) { 062 ClipboardUtils.copyString(values); 063 } 064 } 065}