001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.datatransfer.importers; 003 004import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 005import static org.openstreetmap.josm.tools.I18n.tr; 006 007import java.awt.GridBagLayout; 008import java.awt.datatransfer.DataFlavor; 009import java.awt.datatransfer.UnsupportedFlavorException; 010import java.io.IOException; 011import java.util.Map; 012 013import javax.swing.JLabel; 014import javax.swing.JOptionPane; 015import javax.swing.JPanel; 016import javax.swing.TransferHandler.TransferSupport; 017 018import org.openstreetmap.josm.Main; 019import org.openstreetmap.josm.gui.ExtendedDialog; 020import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils; 021import org.openstreetmap.josm.gui.help.HelpUtil; 022import org.openstreetmap.josm.gui.widgets.UrlLabel; 023import org.openstreetmap.josm.io.XmlWriter; 024import org.openstreetmap.josm.tools.GBC; 025import org.openstreetmap.josm.tools.LanguageInfo.LocaleType; 026import org.openstreetmap.josm.tools.Logging; 027import org.openstreetmap.josm.tools.TextTagParser; 028import org.openstreetmap.josm.tools.TextTagParser.TagWarningCallback; 029 030/** 031 * This transfer support allows us to import tags from the text that was copied to the clipboard. 032 * @author Michael Zangl 033 * @since 10604 034 */ 035public final class TextTagPaster extends AbstractTagPaster { 036 private static final String HELP = ht("/Action/PasteTags"); 037 038 /** 039 * Create a new {@link TextTagPaster} 040 */ 041 public TextTagPaster() { 042 super(DataFlavor.stringFlavor); 043 } 044 045 @Override 046 public boolean supports(TransferSupport support) { 047 try { 048 return super.supports(support) && containsValidTags(support); 049 } catch (UnsupportedFlavorException | IOException e) { 050 Logging.warn(e); 051 return false; 052 } 053 } 054 055 private boolean containsValidTags(TransferSupport support) throws UnsupportedFlavorException, IOException { 056 return !getTagsImpl(support).isEmpty(); 057 } 058 059 @Override 060 protected Map<String, String> getTags(TransferSupport support) throws UnsupportedFlavorException, IOException { 061 Map<String, String> tags = getTagsImpl(support); 062 if (tags.isEmpty()) { 063 showBadBufferMessage(HELP); 064 throw new IOException("Invalid tags to paste."); 065 } 066 if (!TextTagParser.validateTags(tags, TextTagPaster::warning)) { 067 throw new IOException("Tags to paste are not valid."); 068 } 069 return tags; 070 } 071 072 private Map<String, String> getTagsImpl(TransferSupport support) throws UnsupportedFlavorException, IOException { 073 return TextTagParser.readTagsFromText((String) support.getTransferable().getTransferData(df)); 074 } 075 076 /** 077 * Default {@link TagWarningCallback} implementation. 078 * Displays a warning about a problematic tag and ask user what to do about it. 079 * @param text Message to display 080 * @param data Tag key and/or value 081 * @param code to use with {@code ExtendedDialog#toggleEnable(String)} 082 * @return 1 to validate and display next warnings if any, 2 to cancel operation, 3 to clear buffer, 4 to paste tags 083 * @since 12683 084 */ 085 public static int warning(String text, String data, String code) { 086 ExtendedDialog ed = new ExtendedDialog( 087 Main.parent, 088 tr("Do you want to paste these tags?"), 089 tr("Ok"), tr("Cancel"), tr("Clear buffer"), tr("Ignore warnings")); 090 ed.setButtonIcons("ok", "cancel", "dialogs/delete", "pastetags"); 091 ed.setContent("<html><b>"+text + "</b><br/><br/><div width=\"300px\">"+XmlWriter.encode(data, true)+"</html>"); 092 ed.setDefaultButton(2); 093 ed.setCancelButton(2); 094 ed.setIcon(JOptionPane.WARNING_MESSAGE); 095 ed.toggleEnable(code); 096 ed.showDialog(); 097 int r = ed.getValue(); 098 if (r == 0) r = 2; 099 // clean clipboard if user asked 100 if (r == 3) ClipboardUtils.copyString(""); 101 return r; 102 } 103 104 /** 105 * Shows message that the buffer can not be pasted, allowing user to clean the buffer 106 * @param helpTopic the help topic of the parent action 107 * TODO: Replace by proper HelpAwareOptionPane instead of self-made help link 108 */ 109 public static void showBadBufferMessage(String helpTopic) { 110 String msg = tr("<html><p> Sorry, it is impossible to paste tags from buffer. It does not contain any JOSM object" 111 + " or suitable text. </p></html>"); 112 JPanel p = new JPanel(new GridBagLayout()); 113 p.add(new JLabel(msg), GBC.eop()); 114 String helpUrl = HelpUtil.getHelpTopicUrl(HelpUtil.buildAbsoluteHelpTopic(helpTopic, LocaleType.DEFAULT)); 115 if (helpUrl != null) { 116 p.add(new UrlLabel(helpUrl), GBC.eop()); 117 } 118 119 ExtendedDialog ed = new ExtendedDialog( 120 Main.parent, 121 tr("Warning"), 122 tr("Ok"), tr("Clear buffer")) 123 .setButtonIcons("ok", "dialogs/delete") 124 .setContent(p) 125 .setDefaultButton(1) 126 .setCancelButton(1) 127 .setIcon(JOptionPane.WARNING_MESSAGE) 128 .toggleEnable("tags.paste.cleanbadbuffer"); 129 130 ed.showDialog(); 131 132 // clean clipboard if user asked 133 if (ed.getValue() == 2) ClipboardUtils.copyString(""); 134 } 135}