📄 project.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Project.java * Project management tool * Written by: Steven M. Rubin * * Copyright (c) 2005 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.project;import com.sun.electric.database.CellBackup;import com.sun.electric.database.CellRevision;import com.sun.electric.database.ImmutableCell;import com.sun.electric.database.ImmutableElectricObject;import com.sun.electric.database.Snapshot;import com.sun.electric.database.change.Undo;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.hierarchy.View;import com.sun.electric.database.id.CellId;import com.sun.electric.database.network.NetworkTool;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.text.Pref;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.variable.Variable;import com.sun.electric.tool.Job;import com.sun.electric.tool.Listener;import com.sun.electric.tool.io.input.Input;import com.sun.electric.tool.io.input.LibraryFiles;import com.sun.electric.tool.io.output.Output;import com.sun.electric.tool.user.ViewChanges;import java.io.File;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import javax.swing.SwingUtilities;/** * This is the Project Management tool. */public class Project extends Listener{ public static final int NOTMANAGED = 0; public static final int CHECKEDIN = 1; public static final int CHECKEDOUTTOYOU = 2; public static final int CHECKEDOUTTOOTHERS = 3; public static final int OLDVERSION = 4; private static final Variable.Key PROJLOCKEDKEY = Variable.newKey("PROJ_locked"); static final Variable.Key PROJPATHKEY = Variable.newKey("PROJ_path"); static final Variable.Key PROJLIBRARYKEY = Variable.newKey("PROJ_library"); static final String PROJECTFILE = "project.proj"; /** the Project tool. */ private static Project tool = new Project(); /** nonzero to ignore broadcast changes */ private static boolean ignoreChanges; /** check modules */ private static List<FCheck> fCheckList = new ArrayList<FCheck>(); /** nonzero if the system is active */ static boolean pmActive; /** the database describing the project */ static ProjectDB projectDB = new ProjectDB(); /** * Each combination of cell and change-batch is queued by one of these objects. */ private static class FCheck { CellId entry; int batchNumber; }; /****************************** TOOL CONTROL ******************************/ /** * The constructor sets up the Project Management tool. */ private Project() { super("project"); } /** * Method to initialize the Project Management tool. */ public void init() { setOn(); pmActive = false; ignoreChanges = false; } /** * Method to retrieve the singleton associated with the Project tool. * @return the Project tool. */ public static Project getProjectTool() { return tool; } /** * Method to tell whether a Library is in the repository. * @param lib the Library in quesiton. * @return true if the Library is in the repository, and under the control of Project Management. */ public static boolean isLibraryManaged(Library lib) { ProjectLibrary pl = projectDB.findProjectLibrary(lib); if (pl.isEmpty()) return false; return true; } /** * Method to return the status of a Cell in Project Management. * @param cell the Cell in question. * @return NOTMANAGED: this cell is not in any repository<BR> * CHECKEDIN: the cell is checked into the repository and is available for checkout.<BR> * CHECKEDOUTTOYOU: the cell is checked out to the currently-logged in user.<BR> * CHECKEDOUTTOOTHERS: the cell is checked out to someone else * (use "getCellOwner" to find out who).<BR> * OLDVERSION: this is an old version of a cell in the repository.<BR> */ public static int getCellStatus(Cell cell) { Cell newestVersion = cell.getNewestVersion(); ProjectCell pc = projectDB.findProjectCell(newestVersion); if (pc == null) return NOTMANAGED; if (newestVersion != cell) return OLDVERSION; if (pc.getOwner().length() == 0) return CHECKEDIN; if (pc.getOwner().equals(getCurrentUserName())) return CHECKEDOUTTOYOU; return CHECKEDOUTTOOTHERS; } /** * Method to get the name of the owner of a Cell. * @param cell the Cell in question. * @return the name of the user who owns the Cell. * Returns a null string if no owner can be found. */ public static String getCellOwner(Cell cell) { ProjectCell pc = projectDB.findProjectCell(cell); if (pc == null) return ""; return pc.getOwner(); } /****************************** LISTENER INTERFACE ******************************/// /**// * Method to handle the start of a batch of changes.// * @param tool the tool that generated the changes.// * @param undoRedo true if these changes are from an undo or redo command.// */// public void startBatch(Tool tool, boolean undoRedo) {} /** * Handles database changes of a Job. * @param oldSnapshot database snapshot before Job. * @param undoRedo true if Job was Undo/Redo job. */ public void endBatch(Snapshot oldSnapshot, Snapshot newSnapshot, boolean undoRedo) { int batchNumber = newSnapshot.snapshotId; for (CellId cellId: newSnapshot.getChangedCells(oldSnapshot)) { CellBackup oldBackup = oldSnapshot.getCell(cellId); CellBackup newBackup = newSnapshot.getCell(cellId); if (cellChanged(oldBackup, newBackup)) queueCheck(cellId, batchNumber); } detectIllegalChanges(); // always reset change ignorance at the end of a batch ignoreChanges = false; }// /**// * Method to announce a change to a NodeInst.// * @param ni the NodeInst that was changed.// * @param oD the old contents of the NodeInst.// */// public void modifyNodeInst(NodeInst ni, ImmutableNodeInst oD)// {// if (ignoreChanges) return;// queueCheck(ni.getParent());// }//// /**// * Method to announce a change to an ArcInst.// * @param ai the ArcInst that changed.// * @param oD the old contents of the ArcInst.// */// public void modifyArcInst(ArcInst ai, ImmutableArcInst oD)// {// if (ignoreChanges) return;// queueCheck(ai.getParent());// }//// /**// * Method to handle a change to an Export.// * @param pp the Export that moved.// * @param oD the old contents of the Export.// */// public void modifyExport(Export pp, ImmutableExport oD)// {// if (ignoreChanges) return;// queueCheck((Cell)pp.getParent());// }//// /**// * Method to handle a change to a Cell.// * @param cell the Cell that was changed.// * @param oD the old contents of the Cell.// */// public void modifyCell(Cell cell, ImmutableCell oD) {// if (ignoreChanges) return;// if (cellDiffers(oD, cell.getD()))// queueCheck(cell);// }//// /**// * Method to announce a move of a Cell int CellGroup.// * @param cell the cell that was moved.// * @param oCellGroup the old CellGroup of the Cell.// */// public void modifyCellGroup(Cell cell, Cell.CellGroup oCellGroup)// {// if (ignoreChanges) return;// queueCheck(cell);// }//// /**// * Method to handle a change to a Library.// * @param lib the Library that was changed.// * @param oldD the old contents of the Library.// */// public void modifyLibrary(Library lib, ImmutableLibrary oldD) {}//// /**// * Method to handle the creation of a new ElectricObject.// * @param obj the ElectricObject that was just created.// */// public void newObject(ElectricObject obj)// {// checkObject(obj);// }//// /**// * Method to handle the deletion of an ElectricObject.// * @param obj the ElectricObject that was just deleted.// */// public void killObject(ElectricObject obj)// {// checkObject(obj);// }//// /**// * Method to handle the renaming of an ElectricObject.// * @param obj the ElectricObject that was renamed.// * @param oldName the former name of that ElectricObject.// */// public void renameObject(ElectricObject obj, Object oldName)// {// checkObject(obj);// } /** * Method to announce that a Library has been read. * @param lib the Library that was read. */ public void readLibrary(Library lib) { // scan the library to see if any cells are locked if (ignoreChanges) return; for(Iterator<Cell> it = lib.getCells(); it.hasNext(); ) { Cell cell = it.next(); if (cell.getVar(PROJLOCKEDKEY) != null) { pmActive = true; // see if this library has a known project database projectDB.findProjectLibrary(lib); } } }// /**// * Method to announce that a Library is about to be erased.// * @param lib the Library that will be erased.// */// public void eraseLibrary(Library lib) {}//// /**// * Method to announce that a Library is about to be written to disk.// * The method should always be called inside of a Job so that the// * implementation can make changes to the database.// * @param lib the Library that will be saved.// */// public void writeLibrary(Library lib) {} /****************************** LISTENER SUPPORT ******************************/ private static boolean alwaysCheckOut = false; private static void detectIllegalChanges() { if (!pmActive) return; if (fCheckList.size() == 0) return; int lowBatch = Integer.MAX_VALUE; List<Cell> cellsThatChanged = new ArrayList<Cell>(); for(FCheck f : fCheckList) { Cell cell = Cell.inCurrentThread(f.entry); // Cell cell = f.entry; if (cell == null) continue; // make sure cell is checked-out if (cell.getVar(PROJLOCKEDKEY) != null) { cellsThatChanged.add(cell); if (f.batchNumber < lowBatch) lowBatch = f.batchNumber; } } fCheckList.clear(); if (cellsThatChanged.size() > 0) { SwingUtilities.invokeLater(new UndoRunnable(lowBatch, cellsThatChanged)); } } /** * Class to undo changes made to cells that are not checked-out. */ private static class UndoRunnable implements Runnable { private int lowBatch; private List<Cell> cellsThatChanged; UndoRunnable(int lowBatch, List<Cell> cellsThatChanged) { this.lowBatch = lowBatch; this.cellsThatChanged = cellsThatChanged; } public void run() { // construct an error message boolean undoChange = true; if (alwaysCheckOut) undoChange = false; else { String errorMsg = ""; for(Cell cell : cellsThatChanged) { if (errorMsg.length() > 0) errorMsg += ", "; errorMsg += cell.describe(true); } int ret = 1; // String [] options = {"Yes", "No", "Always"}; //int ret = Job.getUserInterface().askForChoice("Cannot change unchecked-out cells: " + errorMsg + // ". Do you want to check them out?", "Change Blocked by Checked-in Cells", options, "No"); if (ret == 0) undoChange = false; if (ret == 2) { alwaysCheckOut = true; undoChange = false; } } if (undoChange) { // change disallowed: undo it new UndoBatchesJob(lowBatch); } else { // change allowed: check-out necessary cells new CheckOutJob(cellsThatChanged, true); } } } /** * This class undoes changes to locked cells. */ private static class UndoBatchesJob extends Undo.UndoJob { private UndoBatchesJob(int lowestBatch) { super("Undo changes to locked cells", lowestBatch); } public void terminateOK() { Undo.noRedoAllowed(); } }// private void checkObject(ElectricObject obj)// {// if (ignoreChanges) return;// if (obj instanceof NodeInst) { queueCheck(((NodeInst)obj).getParent()); return; }// if (obj instanceof ArcInst) { queueCheck(((ArcInst)obj).getParent()); return; }// if (obj instanceof Export) { queueCheck((Cell)((Export)obj).getParent()); return; }// if (obj instanceof Cell) { queueCheck((Cell)obj); return; }// } /** * Compares two CellBackups. Ignores value of PROJLOCKEDKEY. * @param oldBackup first CellBackup. * @param newBackup second ImmutableCell. * @param true if two ImmutableCells differs more than by value of PROJLOCKEDKEY. */ private boolean cellChanged(CellBackup oldBackup, CellBackup newBackup) { if (oldBackup == null || newBackup == null) return true; assert oldBackup != newBackup; CellRevision oldRevision = oldBackup.cellRevision; CellRevision newRevision = newBackup.cellRevision; if (oldRevision.nodes != newRevision.nodes) return true; if (oldRevision.arcs != newRevision.arcs) return true; if (oldRevision.exports != newRevision.exports) return true; // if (oldBackup.revisionDate != newBackup.revisionDate) return true; // if (oldBackup.modified != newBackup.modified) return true; // This will happen if subcells are renamed. ImmutableCell oldD = oldRevision.d; ImmutableCell newD = newRevision.d;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -