/* * Copyright 2009-2020 Contributors (see credits.txt) * * This file is part of jEveAssets. * * jEveAssets is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * jEveAssets is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with jEveAssets; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ package net.nikr.eve.jeveasset.gui.shared; import java.awt.Component; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.KeyStroke; import javax.swing.event.UndoableEditListener; import javax.swing.text.AbstractDocument; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import net.nikr.eve.jeveasset.gui.images.Images; import net.nikr.eve.jeveasset.gui.shared.components.CompoundUndoManager; import net.nikr.eve.jeveasset.i18n.GuiShared; public final class TextManager { private enum CopyPopupAction { CUT, COPY, PASTE } private final JTextComponent component; private final JPopupMenu jPopupMenu; private final JMenuItem jCut; private final JMenuItem jCopy; private final JMenuItem jPaste; private final JMenuItem jUndo; private final JMenuItem jRedo; public static void installAll(final Container container) { for (Component component : container.getComponents()) { if (component instanceof Container) { installAll((Container) component); } if (component instanceof JTextComponent) { installTextComponent((JTextComponent) component); } } } public static void installTextComponent(final JTextComponent component) { //Make sure this component does not already have a UndoManager Document document = component.getDocument(); boolean found = false; if (document instanceof AbstractDocument) { AbstractDocument abstractDocument = (AbstractDocument) document; for (UndoableEditListener editListener : abstractDocument.getUndoableEditListeners()) { if (editListener.getClass().equals(CompoundUndoManager.class)) { CompoundUndoManager undoManager = (CompoundUndoManager) editListener; undoManager.reset(); return; } } } if (!found) { new TextManager(component); } } private TextManager(final JTextComponent component) { this.component = component; ListenerClass listener = new ListenerClass(); component.addMouseListener(listener); jPopupMenu = new JPopupMenu(); jCut = new JMenuItem(GuiShared.get().cut()); jCut.setIcon(Images.EDIT_CUT.getIcon()); jCut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_DOWN_MASK)); jCut.setActionCommand(CopyPopupAction.CUT.name()); jCut.addActionListener(listener); jCopy = new JMenuItem(GuiShared.get().copy()); jCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK)); jCopy.setIcon(Images.EDIT_COPY.getIcon()); jCopy.setActionCommand(CopyPopupAction.COPY.name()); jCopy.addActionListener(listener); jPaste = new JMenuItem(GuiShared.get().paste()); jPaste.setIcon(Images.EDIT_PASTE.getIcon()); jPaste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK)); jPaste.setActionCommand(CopyPopupAction.PASTE.name()); jPaste.addActionListener(listener); CompoundUndoManager undoManager = new CompoundUndoManager(component); jUndo = new JMenuItem(undoManager.getUndoAction()); jUndo.setIcon(Images.EDIT_UNDO.getIcon()); jRedo = new JMenuItem(undoManager.getRedoAction()); jRedo.setIcon(Images.EDIT_REDO.getIcon()); } private void showPopupMenu(final MouseEvent e) { if (!component.isFocusable()) { //Don't show anything for unfocusable components return; } if (!component.hasFocus()) { component.requestFocus(); } jPopupMenu.removeAll(); String s = component.getSelectedText(); boolean canCopy = true; if (s == null) { canCopy = false; } else if (s.length() == 0) { canCopy = false; } if (component.isEditable()) { jCut.setEnabled(canCopy); jPopupMenu.add(jCut); } jCopy.setEnabled(canCopy); jPopupMenu.add(jCopy); if (component.isEditable()) { jPopupMenu.add(jPaste); jPopupMenu.addSeparator(); jPopupMenu.add(jUndo); jPopupMenu.add(jRedo); } jPopupMenu.show(e.getComponent(), e.getX(), e.getY()); } private class ListenerClass implements MouseListener, ActionListener { @Override public void mouseClicked(final MouseEvent e) { if (e.isPopupTrigger()) { showPopupMenu(e); } } @Override public void mousePressed(final MouseEvent e) { if (e.isPopupTrigger()) { showPopupMenu(e); } } @Override public void mouseReleased(final MouseEvent e) { if (e.isPopupTrigger()) { showPopupMenu(e); } } @Override public void mouseEntered(final MouseEvent e) { } @Override public void mouseExited(final MouseEvent e) { } @Override public void actionPerformed(final ActionEvent e) { if (CopyPopupAction.CUT.name().equals(e.getActionCommand())) { CopyHandler.cut(component); } if (CopyPopupAction.COPY.name().equals(e.getActionCommand())) { CopyHandler.toClipboard(component.getSelectedText()); } if (CopyPopupAction.PASTE.name().equals(e.getActionCommand())) { CopyHandler.paste(component); } } } }