📄 errorloggertree.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ErrorLoggerTree.java * * Copyright (c) 2006 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.ui;import com.sun.electric.database.change.DatabaseChangeEvent;import com.sun.electric.database.change.DatabaseChangeListener;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.EDatabase;import com.sun.electric.database.id.CellId;import com.sun.electric.database.text.TextUtils;import com.sun.electric.tool.Job;import com.sun.electric.tool.drc.DRC;import com.sun.electric.tool.io.FileType;import com.sun.electric.tool.user.ErrorHighlight;import com.sun.electric.tool.user.ErrorLogger;import com.sun.electric.tool.user.Highlighter;import com.sun.electric.tool.user.UserInterfaceMain;import com.sun.electric.tool.user.ErrorLogger.MessageLog;import com.sun.electric.tool.user.dialogs.OpenFile;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import javax.swing.JOptionPane;import javax.swing.SwingUtilities;import javax.swing.tree.DefaultMutableTreeNode;import javax.swing.tree.TreeNode;import javax.swing.tree.TreePath;/** * Class to define a collection of highlighted errors in the Explorer tree. */// ----------------------------- Explorer Tree Stuff ---------------------------public class ErrorLoggerTree { public static final String errorNode = "ERRORS"; /** Top of error tree */ private static final DefaultMutableTreeNode errorTree = new DefaultMutableTreeNode(errorNode); /** Path to error tree */ private static final TreePath errorPath = (new TreePath(ExplorerTreeModel.rootNode)).pathByAddingChild(errorTree); /** Current Logger */ static DefaultMutableTreeNode currentLogger; private static final ErrorLogger networkErrorLogger = ErrorLogger.newInstance("Network Errors");// private static final ErrorLogger drcErrorLogger = ErrorLogger.newInstance("DRC (incremental)"); private static DefaultMutableTreeNode networkTree; private static DefaultMutableTreeNode drcTree; // public methods called from any thread public static boolean hasLogger(ErrorLogger logger) { return indexOf(logger) >= 0; }; public static void addLogger(ErrorLogger logger, boolean explain, boolean terminate) { logger.termLogging_(terminate); if (logger.getNumLogs() == 0) return; SwingUtilities.invokeLater(new AddLogger(logger, explain)); }; public static void updateNetworkErrors(Cell cell, List<ErrorLogger.MessageLog> errors) { SwingUtilities.invokeLater(new UpdateNetwork(cell.getId(), errors)); } public static void updateDrcErrors(Cell cell, List<ErrorLogger.MessageLog> newErrors, List<MessageLog> delErrors) { SwingUtilities.invokeLater(new UpdateDrc(cell.getId(), newErrors, delErrors)); } // public methods called from GUI thread public static DefaultMutableTreeNode getExplorerTree() { return errorTree; } /** * Method to advance to the next error and report it. */ public static String reportNextMessage() { if (currentLogger == null) return "No errors to report"; return ((ErrorLoggerTreeNode)currentLogger.getUserObject()).reportNextMessage_(true); } /** * Method to back up to the previous error and report it. */ public static String reportPrevMessage() { if (currentLogger == null) return "No errors to report"; return ((ErrorLoggerTreeNode)currentLogger.getUserObject()).reportPrevMessage_(); } /** * Method to show the current collection of errors. */ public static void showCurrentErrors() { WindowFrame wf = WindowFrame.getCurrentWindowFrame(); if (wf == null) return; if (currentLogger == null) return; Job.getUserInterface().getCurrentEditWindow_().clearHighlighting(); ErrorLoggerTreeNode node = (ErrorLoggerTreeNode)ErrorLoggerTree.currentLogger.getUserObject(); int index = indexOf(node); highlightLogger(index, -1); Job.getUserInterface().getCurrentEditWindow_().finishedHighlighting(); } private static class AddLogger implements Runnable { private ErrorLogger logger; private boolean explain; AddLogger(ErrorLogger logger, boolean explain) { this.logger = logger; this.explain = explain; } public void run() { int i = indexOf(logger); if (i >= 0) { updateTree((DefaultMutableTreeNode)errorTree.getChildAt(i)); } else { addLogger(errorTree.getChildCount(), logger); if (explain) explain(logger); } } } private static void explain(ErrorLogger logger) { // To print consistent message in message window String extraMsg = "errors/warnings"; if (logger.getNumErrors() == 0) extraMsg = "warnings"; else if (logger.getNumWarnings() == 0) extraMsg = "errors"; String msg = logger.getInfo(); System.out.println(msg); if (logger.getNumLogs() > 0) { System.out.println("Type > and < to step through " + extraMsg + ", or open the ERRORS view in the explorer"); } if (logger.getNumErrors() > 0) { JOptionPane.showMessageDialog(TopLevel.getCurrentJFrame(), msg, logger.getSystem() + " finished with Errors", JOptionPane.INFORMATION_MESSAGE); } } private static class UpdateNetwork implements Runnable { private CellId cellId; private List<ErrorLogger.MessageLog> errors; UpdateNetwork(CellId cellId, List<ErrorLogger.MessageLog> errors) { this.cellId = cellId; this.errors = new ArrayList<ErrorLogger.MessageLog>(errors); } public void run() { Cell cell = EDatabase.clientDatabase().getCell(cellId); if (cell == null) return; boolean changed = networkErrorLogger.clearLogs(cell) || !errors.isEmpty(); networkErrorLogger.addMessages(errors); if (!changed) return; networkErrorLogger.termLogging_(true); if (networkErrorLogger.getNumLogs() == 0) { removeLogger(0); return; } if (networkTree == null) networkTree = addLogger(0, networkErrorLogger); updateTree(networkTree); setCurrent(0); } } private static class UpdateDrc implements Runnable { private CellId cellId; private List<ErrorLogger.MessageLog> newErrors; private List<ErrorLogger.MessageLog> delErrors; UpdateDrc(CellId cId, List<ErrorLogger.MessageLog> newErrs, List<MessageLog> delErrs) { this.cellId = cId; if (newErrs != null) this.newErrors = new ArrayList<ErrorLogger.MessageLog>(newErrs); if (delErrs != null) this.delErrors = new ArrayList<ErrorLogger.MessageLog>(delErrs); } public void run() { Cell cell = EDatabase.clientDatabase().getCell(cellId); if (cell == null) return; ErrorLogger drcErrorLogger = DRC.getDRCIncrementalLogger();// boolean changed = drcErrorLogger.clearLogs(cell) || (newErrors != null && !newErrors.isEmpty() ||// (delErrors != null && !delErrors.isEmpty())); drcErrorLogger.addMessages(newErrors); drcErrorLogger.deleteMessages(delErrors);// if (!changed) return; drcErrorLogger.termLogging_(true); int index = networkTree != null ? 1 : 0; if (drcErrorLogger.getNumLogs() == 0) { if (drcTree != null) removeLogger(errorTree.getIndex(drcTree)); return; } if (drcTree == null) drcTree = addLogger(index, drcErrorLogger); updateTree(drcTree); setCurrent(index); } } private static DefaultMutableTreeNode addLogger(int index, ErrorLogger logger) { ErrorLoggerTreeNode tn = new ErrorLoggerTreeNode(logger); UserInterfaceMain.addDatabaseChangeListener(tn); DefaultMutableTreeNode newNode = new ErrorLoggerDefaultMutableTreeNode(tn); int[] childIndices = new int[] { index }; DefaultMutableTreeNode[] children = new DefaultMutableTreeNode[] { newNode }; setCurrent(-1); errorTree.insert(newNode, index); currentLogger = newNode; ExplorerTreeModel.fireTreeNodesInserted(errorTree, errorPath, childIndices, children); updateTree(newNode); return newNode; } private static void removeLogger(int index) { if (errorTree.getChildCount() <= index) return; // nothing to remove. Case of incremental errors DefaultMutableTreeNode node = (DefaultMutableTreeNode)errorTree.getChildAt(index); ErrorLoggerTreeNode treeNode = (ErrorLoggerTreeNode)node.getUserObject(); UserInterfaceMain.removeDatabaseChangeListener(treeNode); ErrorLogger drcErrorLogger = DRC.getDRCIncrementalLogger(); // Clean DRC incremental logger if (treeNode.getLogger() == drcErrorLogger) { drcErrorLogger.clearAllLogs(); } if (node == networkTree) networkTree = null; if (node == drcTree) drcTree = null; if (node == currentLogger) currentLogger = null; int[] childIndices = new int[] { index }; DefaultMutableTreeNode[] children = new DefaultMutableTreeNode[] { node }; errorTree.remove(index); ExplorerTreeModel.fireTreeNodesRemoved(errorTree, errorPath, childIndices, children); } private static void highlightLogger(int index, int sortKey) { EditWindow ew = EditWindow.getCurrent(); if (ew == null) return; Highlighter h = ew.getHighlighter(); DefaultMutableTreeNode node = (DefaultMutableTreeNode)errorTree.getChildAt(index); ErrorLoggerTreeNode eltn = (ErrorLoggerTreeNode)node.getUserObject(); ErrorLogger el = eltn.getLogger(); EDatabase database = EDatabase.clientDatabase(); for(int i=0; i<el.getNumLogs(); i++) { MessageLog ml = el.getLog(i); if (sortKey >= 0 && ml.getSortKey() != sortKey) continue; for(Iterator<ErrorHighlight> it = ml.getHighlights(); it.hasNext(); ) { ErrorHighlight eh = it.next(); eh.addToHighlighter(h, database); } } } private static void updateTree(DefaultMutableTreeNode loggerNode) { TreePath loggerPath = errorPath.pathByAddingChild(loggerNode); int oldChildCount = loggerNode.getChildCount(); if (oldChildCount != 0) { int[] childIndex = new int[oldChildCount]; DefaultMutableTreeNode[] children = new DefaultMutableTreeNode[oldChildCount]; for (int i = 0; i < oldChildCount; i++) { childIndex[i] = i; children[i] = (DefaultMutableTreeNode)loggerNode.getChildAt(i); } loggerNode.removeAllChildren(); ExplorerTreeModel.fireTreeNodesRemoved(errorTree, loggerPath, childIndex, children); } ErrorLoggerTreeNode eltn = (ErrorLoggerTreeNode)loggerNode.getUserObject(); ErrorLogger logger = eltn.logger; if (logger.getNumLogs() == 0) return; Map<Integer,DefaultMutableTreeNode> sortKeyMap = new HashMap<Integer,DefaultMutableTreeNode>(); Map<Integer,String> sortKeyGroupNamesMap = logger.getSortKeyToGroupNames(); // Extra level for loggers if (sortKeyGroupNamesMap != null) { for (Map.Entry e : sortKeyGroupNamesMap.entrySet()) { String name = (String)e.getValue(); Integer key = (Integer)e.getKey(); DefaultMutableTreeNode grpNode = new DefaultMutableTreeNode(new ErrorLoggerGroupNode(name, key.intValue(), eltn)); loggerNode.add(grpNode); sortKeyMap.put(key, grpNode); } } for (Iterator<ErrorLogger.MessageLog> it = logger.getLogs(); it.hasNext();) { ErrorLogger.MessageLog el = it.next(); // by default, groupNode is entire loggerNode // but, groupNode could be sub-node: DefaultMutableTreeNode groupNode = loggerNode; if (logger.getSortKeyToGroupNames() != null) { groupNode = sortKeyMap.get(new Integer(el.getSortKey())); if (groupNode == null) // not found, put in loggerNode groupNode = loggerNode; } DefaultMutableTreeNode node = new DefaultMutableTreeNode(el); groupNode.add(node); } int newChildCount = loggerNode.getChildCount(); int[] childIndex = new int[newChildCount]; DefaultMutableTreeNode[] children = new DefaultMutableTreeNode[newChildCount]; for (int i = 0; i < newChildCount; i++) { childIndex[i] = i; children[i] = (DefaultMutableTreeNode)loggerNode.getChildAt(i); } ExplorerTreeModel.fireTreeNodesInserted(errorTree, loggerPath, childIndex, children); } private static void setCurrent(int index) { int oldIndex = currentLogger != null ? indexOf((ErrorLoggerTreeNode)currentLogger.getUserObject()) : -1; if (index == oldIndex) return; currentLogger = index >= 0 ? (DefaultMutableTreeNode)errorTree.getChildAt(index) : null; int l = 0; if (oldIndex >= 0) l++; if (index >= 0) l++; int[] childIndex = new int[l]; TreeNode[] children = new TreeNode[l]; l = 0; if (oldIndex >= 0 && oldIndex < index) { childIndex[l] = oldIndex;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -