    001// License: GPL. For details, see LICENSE file.
    002package org.openstreetmap.josm.plugins.streetside.gui.imageinfo;
    003
    004import java.awt.Color;
    005import java.awt.Component;
    006import java.awt.Toolkit;
    007import java.awt.datatransfer.Transferable;
    008import java.awt.event.ActionEvent;
    009
    010import javax.swing.AbstractAction;
    011import javax.swing.Action;
    012import javax.swing.BorderFactory;
    013import javax.swing.JLabel;
    014import javax.swing.JPopupMenu;
    015
    016import org.openstreetmap.josm.tools.I18n;
    017import org.openstreetmap.josm.tools.ImageProvider;
    018import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
    019
    020public class ClipboardAction extends AbstractAction {
    021
    022  private static final long serialVersionUID = -7298944557860158010L;
    023  /**
    024   * The duration in milliseconds for which the popup will be shown
    025   */
    026  private static final long POPUP_DURATION = 3000;
    027  /**
    028   * A small popup that shows up when the key has been moved to the clipboard
    029   */
    030  private final JPopupMenu popup;
    031  /**
    032   * The component which is used as parent of the shown popup.
    033   * If this is <code>null</code>, no popup will be shown.
    034   */
    035  private Component popupParent;
    036  /**
    037   * The UNIX epoch time when the popup for this action was shown the last time
    038   */
    039  private long lastPopupShowTime;
    040  /**
    041   * The contents that are transfered into the clipboard when the action is executed.
    042   * If this is <code>null</code>, the clipboard won't be changed.
    043   */
    044  private Transferable contents;
    045
    046  public ClipboardAction(final String name, final Transferable contents) {
    047    super(name, ImageProvider.get("copy", ImageSizes.SMALLICON));
    048    this.contents = contents;
    049
    050    // Init popup
    051    popup = new JPopupMenu();
    052    // TODO: tr( RRH
    053    JLabel label = new JLabel(I18n.tr("Key copied to clipboard") + '…');
    054    label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    055    popup.add(label);
    056    popup.setBackground(new Color(0f, 0f, 0f, .5f));
    057    label.setForeground(Color.WHITE);
    058  }
    059
    060  /**
    061   * @param contents the contents, which should be copied to the clipboard when the {@link Action} is executed
    062   */
    063  public void setContents(Transferable contents) {
    064    this.contents = contents;
    065    setEnabled(contents != null);
    066  }
    067
    068  /**
    069   * Sets the component, under which the popup will be shown, which indicates that the key was copied to the clipboard.
    070   * @param popupParent the component to set as parent of the popup
    071   */
    072  public void setPopupParent(Component popupParent) {
    073    this.popupParent = popupParent;
    074  }
    075
    076  /* (non-Javadoc)
    077   * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
    078   */
    079  @Override
    080  public void actionPerformed(ActionEvent e) {
    081    if (contents != null) {
    082      Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, null);
    083      if (popupParent != null) {
    084        popup.show(popupParent, 0, popupParent.getHeight() + 2);
    085        new Thread(() -> {
    086          long threadStart = System.currentTimeMillis();
    087          lastPopupShowTime = threadStart;
    088          try {
    089            Thread.sleep(POPUP_DURATION);
    090          } catch (InterruptedException e1) {
    091            if (threadStart == lastPopupShowTime) {
    092              popup.setVisible(false);
    093            }
    094          }
    095          if (System.currentTimeMillis() >= lastPopupShowTime + POPUP_DURATION) {
    096            popup.setVisible(false);
    097          }
    098        }).start();
    099      }
    100    }
    101  }
    102
    103}