/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ManipulateExports.java * * Copyright (c) 2008 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.dialogs; import com.sun.electric.Main; import com.sun.electric.database.hierarchy.Cell; import com.sun.electric.database.hierarchy.Export; import com.sun.electric.database.prototype.PortCharacteristic; import com.sun.electric.database.text.TextUtils; import com.sun.electric.database.variable.EditWindow_; import com.sun.electric.database.variable.UserInterface; import com.sun.electric.technology.ArcProto; import com.sun.electric.technology.technologies.Generic; import com.sun.electric.tool.Job; import com.sun.electric.tool.user.ExportChanges; import com.sun.electric.tool.user.ui.WindowFrame; import java.awt.Component; import java.awt.Frame; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import javax.swing.DefaultCellEditor; import javax.swing.JComboBox; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; /** * Class to handle the "Manipulate Exports" dialog. */ public class ManipulateExports extends EDialog { private static final String [] columnNames = {" ", "Name", "Layer", "Characteristic", "Body Only"}; private class ExportsTable extends JTable { private ExportTableModel model; /** * Constructor for ExportsTable */ public ExportsTable(Cell cell) { model = new ExportTableModel(cell); for(Iterator<Export> it = cell.getExports(); it.hasNext(); ) { Export e = it.next(); model.newVar(e); } model.sortTable(1, true); setModel(model); TableColumn tc = getColumn(getColumnName(0)); if (tc != null) tc.setPreferredWidth(10); tc = getColumn(getColumnName(1)); if (tc != null) tc.setPreferredWidth(120); tc = getColumn(getColumnName(2)); if (tc != null) tc.setPreferredWidth(100); tc = getColumn(getColumnName(3)); if (tc != null) { tc.setPreferredWidth(80); List<PortCharacteristic> chars = PortCharacteristic.getOrderedCharacteristics(); PortCharacteristic [] charNames = new PortCharacteristic[chars.size()]; for(int i=0; i<chars.size(); i++) charNames[i] = chars.get(i); tc.setCellRenderer(new CellComboBoxRenderer(charNames)); tc.setCellEditor(new CellComboBoxEditor(charNames)); } tc = getColumn(getColumnName(4)); if (tc != null) tc.setPreferredWidth(20); } public void toggleSelection() { int [] rows = getSelectedRows(); for(int i=0; i<rows.length; i++) { Boolean b = (Boolean)model.getValueAt(rows[i], 0); model.setValueAt(Boolean.valueOf(!b.booleanValue()), rows[i], 0); } } public ExportTableModel getModel() { return model; } public void selectAll() { model.selectAll(); } public void deselectAll() { model.deselectAll(); } public void renumberSelectedExports() { model.renumberSelectedExports(); } public void unExportSelected() { model.unExportSelected(); } public void showSelected() { model.showSelected(); } } public class CellComboBoxEditor extends DefaultCellEditor { public CellComboBoxEditor(Object[] items) { super(new JComboBox(items)); } } public class CellComboBoxRenderer extends JComboBox implements TableCellRenderer { public CellComboBoxRenderer(Object[] items) { super(items); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { setForeground(table.getSelectionForeground()); super.setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(table.getBackground()); } // Select the current value setSelectedItem(value); return this; } } /** * Model for storing Table data */ private class ExportTableModel extends AbstractTableModel { private Cell cell; private List<ExportEntry> exports; private class ExportEntry { private boolean selected; private String name; private PortCharacteristic ch; private Export e; private ExportEntry(Export e) { this.e = e; this.name = e.getName(); this.ch = e.getCharacteristic(); } private Export getExport() { return e; } private boolean isSelected() { return selected; } private void setSelected(boolean s) { selected = s; } } /** * Class to sort exports. */ public class ExportEntrySort implements Comparator<ExportEntry> { private int column; private boolean ascending; ExportEntrySort(int column, boolean ascending) { this.column = column; this.ascending = ascending; } public int compare(ExportEntry p1, ExportEntry p2) { if (!ascending) { ExportEntry swap = p1; p1 = p2; p2 = swap; } String s1 = null, s2 = null; switch (column) { case 0: // selection boolean b1 = p1.isSelected(); boolean b2 = p2.isSelected(); if (b1 == b2) return 0; if (b1) return 1; return -1; case 1: // name s1 = p1.name; s2 = p2.name; break; case 2: // layer s1 = getLayer(p1.getExport()); s2 = getLayer(p2.getExport()); break; case 3: // characteristics s1 = p1.ch.getName(); s2 = p2.ch.getName(); return s1.compareTo(s2); case 4: // body-only b1 = p1.getExport().isBodyOnly(); b2 = p2.getExport().isBodyOnly(); if (b1 == b2) return 0; if (b1) return 1; return -1; } return TextUtils.STRING_NUMBER_ORDER.compare(s1, s2); } } // constructor private ExportTableModel(Cell cell) { this.cell = cell; exports = new ArrayList<ExportEntry>(); } /** * Create a new var with default properties */ public void newVar(Export e) { ExportEntry ve = new ExportEntry(e); exports.add(ve); } public void sortTable(int column, boolean ascending) { Collections.sort(exports, new ExportEntrySort(column, ascending)); fireTableDataChanged(); } public void selectAll() { int i = 0; for(ExportEntry pe : exports) { pe.setSelected(true); fireTableCellUpdated(i++, 0); } } public void deselectAll() { int i = 0; for(ExportEntry pe : exports) { pe.setSelected(false); fireTableCellUpdated(i++, 0); } } public void renumberSelectedExports() { List<Export> queuedExports = new ArrayList<Export>(); for(ExportEntry pe : exports) { if (!pe.isSelected()) continue; queuedExports.add(pe.getExport()); } new ExportChanges.RenumberNumericExports(queuedExports); } public void unExportSelected() { List<Export> queuedExports = new ArrayList<Export>(); for(ExportEntry pe : exports) { if (!pe.isSelected()) continue; queuedExports.add(pe.getExport()); } ExportChanges.deleteExports(cell, queuedExports); } public void showSelected() { UserInterface ui = Job.getUserInterface(); EditWindow_ wnd = ui.getCurrentEditWindow_(); if (wnd == null) return; wnd.clearHighlighting(); for(ExportEntry pe : exports) { if (!pe.isSelected()) continue; wnd.addHighlightText(pe.getExport(), cell, Export.EXPORT_NAME); } wnd.finishedHighlighting(); } /** Method to get the number of columns. */ public int getColumnCount() { return 5; } /** Method to get the number of rows. */ public int getRowCount() { return exports.size(); } /** Method to get a location in the table. */ public Object getValueAt(int rowIndex, int columnIndex) { ExportEntry pe = exports.get(rowIndex); if (pe == null) return null; switch (columnIndex) { // selected case 0: return Boolean.valueOf(pe.isSelected()); // name case 1: return pe.name; // layer case 2: return getLayer(pe.getExport()); // characteristic case 3: return pe.ch; // body-only case 4: return Boolean.valueOf(pe.getExport().isBodyOnly()); } return null; } /** * Convert an Export to the layers on it. * @param e the Export. * @return the name of the layer on the export. */ private String getLayer(Export e) { ArcProto [] arcs = e.getBasePort().getConnections(); String layers = ""; ArcProto firstGeneric = null; for(int i=0; i<arcs.length; i++) { ArcProto ap = arcs[i]; if (ap.getTechnology() == Generic.tech()) { if (firstGeneric == null) firstGeneric = ap; } else { if (layers.length() > 0) layers += ", "; layers += ap.getLayer(0).getName(); } } if (layers.length() == 0 && firstGeneric != null) layers = firstGeneric.getLayer(0).getName(); return layers; } /** Method to get a column's header name. */ public String getColumnName(int col) { String colName = columnNames[col]; if (col == sortColumn) { if (sortAscending) colName += " \u21D3"; else colName += " \u21D1"; } return colName; } /** Method to determine whether a cell is editable. */ public boolean isCellEditable(int row, int col) { if (col == 0 || col == 1 || col == 3) return true; return false; } /** Method to set a value. */ public void setValueAt(Object aValue, int row, int col) { ExportEntry ve = exports.get(row); if (ve == null) return; if (col == 0) { // change the "checked" state of the export Boolean b = (Boolean)aValue; if (ve.isSelected() != b.booleanValue()) { ve.setSelected(b.booleanValue()); fireTableCellUpdated(row, col); } } else if (col == 1) { // change the name of the export ExportEntry pe = exports.get(row); if (pe == null) return; pe.name = (String)aValue; new ExportChanges.RenameExport(pe.getExport(), pe.name); } else if (col == 3) { // change the characteristics of the export ExportEntry pe = exports.get(row); if (pe == null) return; pe.ch = (PortCharacteristic)aValue; new ExportChanges.ChangeExportCharacteristic(pe.getExport(), pe.ch); } } public Class<?> getColumnClass(int col) { if (col == 0) return Boolean.class; return String.class; } } private ExportsTable exportTable; private int sortColumn; private boolean sortAscending; public static void showDialog() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new ManipulateExports(Main.getCurrentJFrame(), cell); } /** Creates new form Manipulate Exports */ private ManipulateExports(Frame parent, Cell cell) { super(parent, true); initComponents(); getRootPane().setDefaultButton(done); title.setText("Exports in cell " + cell.describe(false)); sortColumn = 1; sortAscending = true; exportTable = new ExportsTable(cell); JTableHeader header = exportTable.getTableHeader(); header.addMouseListener(new ColumnListener()); exportPane.setViewportView(exportTable); finishInitialization(); setVisible(true); } private class ColumnListener extends MouseAdapter { public ColumnListener() {} public void mouseClicked(MouseEvent e) { TableColumnModel colModel = exportTable.getColumnModel(); int colNumber = colModel.getColumnIndexAtX(e.getX()); int modelIndex = colModel.getColumn(colNumber).getModelIndex(); if (modelIndex < 0) return; if (sortColumn == modelIndex) sortAscending = !sortAscending; else sortColumn = modelIndex; ExportTableModel model = exportTable.getModel(); model.sortTable(modelIndex, sortAscending); model.fireTableStructureChanged(); } } protected void escapePressed() { doneActionPerformed(null); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; done = new javax.swing.JButton(); title = new javax.swing.JLabel(); exportPane = new javax.swing.JScrollPane(); selectAll = new javax.swing.JButton(); deselectAll = new javax.swing.JButton(); reNumberExports = new javax.swing.JButton(); jSeparator1 = new javax.swing.JSeparator(); deleteExports = new javax.swing.JButton(); showExports = new javax.swing.JButton(); toggleSelection = new javax.swing.JButton(); setTitle("Manipulate Exports"); setName(""); // NOI18N addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { closeDialog(evt); } }); getContentPane().setLayout(new java.awt.GridBagLayout()); done.setText("Done"); done.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { doneActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 6; gridBagConstraints.gridwidth = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(done, gridBagConstraints); title.setText("Exports in Cell"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(title, gridBagConstraints); exportPane.setMinimumSize(new java.awt.Dimension(200, 200)); exportPane.setPreferredSize(new java.awt.Dimension(200, 200)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; getContentPane().add(exportPane, gridBagConstraints); selectAll.setText("Select All Exports"); selectAll.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { selectAllActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 3; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(selectAll, gridBagConstraints); deselectAll.setText("Deselect All Exports"); deselectAll.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deselectAllActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 4; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(deselectAll, gridBagConstraints); reNumberExports.setText("Renumber Selected Numeric Export Names"); reNumberExports.setToolTipText("Renames the selected exports so that trailing numbers are in order"); reNumberExports.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { reNumberExportsActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 4; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(reNumberExports, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 5; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; getContentPane().add(jSeparator1, gridBagConstraints); deleteExports.setText("Delete Selected Exports"); deleteExports.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteExportsActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(deleteExports, gridBagConstraints); showExports.setText("Show Selected Exports"); showExports.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { showExportsActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 3; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(showExports, gridBagConstraints); toggleSelection.setText("Toggle Selection"); toggleSelection.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { toggleSelectionActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(toggleSelection, gridBagConstraints); pack(); }// </editor-fold>//GEN-END:initComponents private void toggleSelectionActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_toggleSelectionActionPerformed {//GEN-HEADEREND:event_toggleSelectionActionPerformed exportTable.toggleSelection(); }//GEN-LAST:event_toggleSelectionActionPerformed private void showExportsActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_showExportsActionPerformed {//GEN-HEADEREND:event_showExportsActionPerformed exportTable.showSelected(); }//GEN-LAST:event_showExportsActionPerformed private void deleteExportsActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_deleteExportsActionPerformed {//GEN-HEADEREND:event_deleteExportsActionPerformed exportTable.unExportSelected(); closeDialog(null); }//GEN-LAST:event_deleteExportsActionPerformed private void reNumberExportsActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_reNumberExportsActionPerformed {//GEN-HEADEREND:event_reNumberExportsActionPerformed exportTable.renumberSelectedExports(); closeDialog(null); }//GEN-LAST:event_reNumberExportsActionPerformed private void deselectAllActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_deselectAllActionPerformed {//GEN-HEADEREND:event_deselectAllActionPerformed exportTable.deselectAll(); }//GEN-LAST:event_deselectAllActionPerformed private void selectAllActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_selectAllActionPerformed {//GEN-HEADEREND:event_selectAllActionPerformed exportTable.selectAll(); }//GEN-LAST:event_selectAllActionPerformed private void doneActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_doneActionPerformed {//GEN-HEADEREND:event_doneActionPerformed closeDialog(null); }//GEN-LAST:event_doneActionPerformed /** Closes the dialog */ private void closeDialog(java.awt.event.WindowEvent evt)//GEN-FIRST:event_closeDialog { setVisible(false); dispose(); }//GEN-LAST:event_closeDialog // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton deleteExports; private javax.swing.JButton deselectAll; private javax.swing.JButton done; private javax.swing.JScrollPane exportPane; private javax.swing.JSeparator jSeparator1; private javax.swing.JButton reNumberExports; private javax.swing.JButton selectAll; private javax.swing.JButton showExports; private javax.swing.JLabel title; private javax.swing.JButton toggleSelection; // End of variables declaration//GEN-END:variables }