📄 clipboard.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Clipboard.java * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) 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 3 of the License, or * (at your option) any later version. * * Electric(tm) 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 Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool.user;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.Dimension2D;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.geometry.Orientation;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.Geometric;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.*;import com.sun.electric.database.text.TextUtils;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.user.ui.ClickZoomWireListener;import com.sun.electric.tool.user.ui.EditWindow;import com.sun.electric.tool.user.ui.WindowFrame;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;import java.awt.event.MouseWheelEvent;import java.awt.event.MouseWheelListener;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.util.ArrayList;import java.util.Collections;import java.util.EventListener;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import javax.swing.JMenuItem;import javax.swing.JPopupMenu;import javax.swing.KeyStroke;/** * Class for managing the circuitry clipboard (for copy and paste). */public class Clipboard //implements ClipboardOwner{ /** The Clipboard Library. */ private static Library clipLib = null; /** The Clipboard Cell. */ private static Cell clipCell; /** the last node that was duplicated */ private static NodeInst lastDup = null; /** the amount that the last node moved */ private static double lastDupX = 10, lastDupY = 10;// private static final Clipboard clip = new Clipboard(); /** * There is only one instance of this object (just one clipboard). */ private Clipboard() {}// public void lostOwnership (java.awt.datatransfer.Clipboard parClipboard, Transferable parTransferable) {} /** * Returns a printable version of this Clipboard. * @return a printable version of this Clipboard. */ public String toString() { return "Clipboard"; } // this is really only for debugging public static void editClipboard() { EditWindow wnd = EditWindow.getCurrent(); wnd.setCell(clipCell, VarContext.globalContext, null); } /** * Method to copy the selected objects to the clipboard. */ public static void copy() { // Clear text buffer TextUtils.setTextOnClipboard(null); // see what is highlighted EditWindow wnd = EditWindow.needCurrent(); if (wnd == null) return; Highlighter highlighter = wnd.getHighlighter(); List<Geometric> highlightedGeoms = highlighter.getHighlightedEObjs(true, true); List<DisplayedText> highlightedText = highlighter.getHighlightedText(true); if (highlightedGeoms.size() == 0 && highlightedText.size() == 0) { System.out.println("First select objects to copy"); return; } // special case: if one text object is selected, copy its text to the system clipboard copySelectedText(highlightedText); // create the transformation for "down in place" copying AffineTransform inPlace = new AffineTransform(); Orientation inPlaceOrient = Orientation.IDENT; if (wnd.isInPlaceEdit()) { List<NodeInst> nodes = wnd.getInPlaceEditNodePath(); for(NodeInst n : nodes) { Orientation o = n.getOrient().inverse(); inPlaceOrient = o.concatenate(inPlaceOrient); } AffineTransform justRotation = inPlaceOrient.pureRotate(); Rectangle2D pasteBounds = getPasteBounds(highlightedGeoms, highlightedText, wnd); AffineTransform untranslate = AffineTransform.getTranslateInstance(-pasteBounds.getCenterX(), -pasteBounds.getCenterY()); AffineTransform retranslate = AffineTransform.getTranslateInstance(pasteBounds.getCenterX(), pasteBounds.getCenterY()); inPlace.preConcatenate(untranslate); inPlace.preConcatenate(justRotation); inPlace.preConcatenate(retranslate); } // copy to Electric clipboard cell new CopyObjects(highlightedGeoms, highlightedText, User.getAlignmentToGrid(), inPlace, inPlaceOrient); } /** * Method to copy the selected objects to the clipboard and then delete them. */ public static void cut() { // see what is highlighted EditWindow wnd = EditWindow.needCurrent(); if (wnd == null) return; Highlighter highlighter = wnd.getHighlighter(); List<Geometric> highlightedGeoms = highlighter.getHighlightedEObjs(true, true); List<DisplayedText> highlightedText = highlighter.getHighlightedText(true); if (highlightedGeoms.size() == 0 && highlightedText.size() == 0) { System.out.println("First select objects to cut"); return; } highlighter.clear(); highlighter.finished(); // special case: if one text object is selected, copy its text to the system clipboard copySelectedText(highlightedText); // create the transformation for "down in place" copying AffineTransform inPlace = new AffineTransform(); Orientation inPlaceOrient = Orientation.IDENT; if (wnd.isInPlaceEdit()) { List<NodeInst> nodes = wnd.getInPlaceEditNodePath(); for(NodeInst n : nodes) { Orientation o = n.getOrient().inverse(); inPlaceOrient = o.concatenate(inPlaceOrient); } AffineTransform justRotation = inPlaceOrient.pureRotate(); Rectangle2D pasteBounds = getPasteBounds(highlightedGeoms, highlightedText, wnd); AffineTransform untranslate = AffineTransform.getTranslateInstance(-pasteBounds.getCenterX(), -pasteBounds.getCenterY()); AffineTransform retranslate = AffineTransform.getTranslateInstance(pasteBounds.getCenterX(), pasteBounds.getCenterY()); inPlace.preConcatenate(untranslate); inPlace.preConcatenate(justRotation); inPlace.preConcatenate(retranslate); } // cut from Electric, copy to clipboard cell new CutObjects(wnd.getCell(), highlightedGeoms, highlightedText, User.getAlignmentToGrid(), User.isReconstructArcsAndExportsToDeletedCells(), inPlace, inPlaceOrient); } /** * Method to paste the clipboard back into the current cell. */ public static void paste() { // Get text put in the clipboard but using variables. String extraText = TextUtils.getTextOnClipboard(); // get objects to paste int nTotal = 0, aTotal = 0, vTotal = 0; if (clipCell != null) { nTotal = clipCell.getNumNodes(); aTotal = clipCell.getNumArcs(); vTotal = clipCell.getNumVariables(); if (clipCell.getVar(User.FRAME_LAST_CHANGED_BY) != null) vTotal--; // discount this variable since it should not be copied. } // find out where the paste is going EditWindow wnd = EditWindow.needCurrent(); if (wnd == null) { System.out.println("No place to paste"); return; } Highlighter highlighter = wnd.getHighlighter(); Cell parent = wnd.getCell(); int total = nTotal + aTotal + vTotal; if (total == 0) { if (extraText != null) { List<DisplayedText> highlightedText = highlighter.getHighlightedText(true); new PasteSpecialText(highlightedText, extraText, parent); } else System.out.println("Nothing in the clipboard to paste"); return; } // special case of pasting on top of selected objects List<Geometric> geoms = highlighter.getHighlightedEObjs(true, true); if (geoms.size() > 0) { // can only paste a single object onto selection if (nTotal == 2 && aTotal == 1) { ArcInst ai = clipCell.getArcs().next(); NodeInst niHead = ai.getHeadPortInst().getNodeInst(); NodeInst niTail = ai.getTailPortInst().getNodeInst(); Iterator<NodeInst> nIt = clipCell.getNodes(); NodeInst ni1 = nIt.next(); NodeInst ni2 = nIt.next(); if ((ni1 == niHead && ni2 == niTail) || (ni1 == niTail && ni2 == niHead)) nTotal = 0; total = nTotal + aTotal; } if (total > 1) { System.out.println("Can only paste a single object on top of selected objects"); return; } for(Geometric geom : geoms) { if (geom instanceof NodeInst && nTotal == 1) { NodeInst ni = (NodeInst)geom; new PasteNodeToNode(ni, clipCell.getNodes().next()); } else if (geom instanceof ArcInst) { ArcInst ai = (ArcInst)geom; if (aTotal == 1) new PasteArcToArc(ai, clipCell.getArcs().next()); else ai.setName(extraText); } } return; } // make list of things to paste List<Geometric> geomList = new ArrayList<Geometric>(); for(Iterator<NodeInst> it = clipCell.getNodes(); it.hasNext(); ) geomList.add(it.next()); for(Iterator<ArcInst> it = clipCell.getArcs(); it.hasNext(); ) geomList.add(it.next()); List<DisplayedText> textList = new ArrayList<DisplayedText>(); for (Iterator<Variable> it = clipCell.getVariables(); it.hasNext(); ) { Variable var = it.next(); if (!var.isDisplay()) continue; textList.add(new DisplayedText(clipCell, var.getKey())); } if (geomList.size() == 0 && textList.size() == 0) return; // create the transformation for "down in place" pasting AffineTransform inPlace = new AffineTransform(); Orientation inPlaceOrient = Orientation.IDENT; if (wnd.isInPlaceEdit()) { List<NodeInst> nodes = wnd.getInPlaceEditNodePath(); for(NodeInst n : nodes) { Orientation o = n.getOrient(); inPlaceOrient = inPlaceOrient.concatenate(o); } AffineTransform justRotation = inPlaceOrient.pureRotate(); Rectangle2D pasteBounds = getPasteBounds(geomList, textList, wnd); AffineTransform untranslate = AffineTransform.getTranslateInstance(-pasteBounds.getCenterX(), -pasteBounds.getCenterY()); AffineTransform retranslate = AffineTransform.getTranslateInstance(pasteBounds.getCenterX(), pasteBounds.getCenterY()); inPlace.preConcatenate(untranslate); inPlace.preConcatenate(justRotation); inPlace.preConcatenate(retranslate); } if (User.isMoveAfterDuplicate()) { EventListener currentListener = WindowFrame.getListener(); WindowFrame.setListener(new PasteListener(wnd, geomList, textList, currentListener, inPlace, inPlaceOrient, false)); } else { new PasteObjects(parent, geomList, textList, lastDupX, lastDupY, User.getAlignmentToGrid(), User.isDupCopiesExports(), User.isArcsAutoIncremented(), inPlace, inPlaceOrient); } } /** * Method to duplicate the selected objects. */ public static void duplicate() { // see what is highlighted EditWindow wnd = EditWindow.needCurrent(); if (wnd == null) return; Highlighter highlighter = wnd.getHighlighter(); List<Geometric> geomList = highlighter.getHighlightedEObjs(true, true); List<DisplayedText> textList = new ArrayList<DisplayedText>(); for (Iterator<Variable> it = clipCell.getVariables(); it.hasNext(); ) { Variable var = it.next(); if (!var.isDisplay()) continue; textList.add(new DisplayedText(clipCell, var.getKey())); } if (geomList.size() == 0 && textList.size() == 0) { System.out.println("First select objects to duplicate"); return; } // do duplication if (User.isMoveAfterDuplicate()) { EventListener currentListener = WindowFrame.getListener(); WindowFrame.setListener(new PasteListener(wnd, geomList, textList, currentListener, null, null, true)); } else { new DuplicateObjects(wnd.getCell(), geomList, textList, User.getAlignmentToGrid()); } } /** * Method to track movement of the object that was just duplicated. * By following subsequent changes to that node, future duplications know where to place their copies. * @param ni the NodeInst that has just moved. * @param lastX the previous center X of the NodeInst. * @param lastY the previous center Y of the NodeInst. */ public static void nodeMoved(NodeInst ni, double lastX, double lastY) { if (ni != lastDup) return; lastDupX += ni.getAnchorCenterX() - lastX; lastDupY += ni.getAnchorCenterY() - lastY; } /** * Helper method to copy any selected text to the system-wide clipboard. */ private static void copySelectedText(List<DisplayedText> highlightedText) { // must be one text selected if (highlightedText.size() != 1) return; // get the text DisplayedText dt = highlightedText.get(0); ElectricObject eObj = dt.getElectricObject(); Variable.Key varKey = dt.getVariableKey(); String selected = null; if (varKey == ArcInst.ARC_NAME) { selected = ((ArcInst)eObj).getName(); } else if (varKey == NodeInst.NODE_NAME || varKey == NodeInst.NODE_PROTO) { selected = ((NodeInst)eObj).getName(); } else if (varKey == Export.EXPORT_NAME) { selected = ((Export)eObj).getName(); } else { Variable var = eObj.getParameterOrVariable(varKey); if (var == null) return; selected = var.describe(-1); } if (selected == null) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -