[EDKT169]Add feature of sorting modules in FPD file.
authorjlin16 <jlin16@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 7 Aug 2006 03:51:22 +0000 (03:51 +0000)
committerjlin16 <jlin16@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 7 Aug 2006 03:51:22 +0000 (03:51 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1197 6f19259b-4bc3-4df7-8a09-765794883524

Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/FpdFileContents.java
Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/FpdFrameworkModules.java
Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/TableSorter.java [new file with mode: 0644]
Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/global/GlobalData.java

index d942add..8296b21 100644 (file)
@@ -1170,11 +1170,11 @@ public class FpdFileContents {
                 DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData pcdBuildData = \r
                     (DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData)cursor.getObject();\r
                 if (pcdBuildData.getCName().equals(cName) && pcdBuildData.getTokenSpaceGuidCName().equals(tsGuid)) {\r
-                    cursor.removeXml();\r
-                    if (getDynamicPcdBuildDataCount() == 0) {\r
+                    \r
+                    if (getDynamicPcdBuildDataCount() == 1) {\r
                         cursor.toParent();\r
-                        cursor.removeXml();\r
                     }\r
+                    cursor.removeXml();\r
                     cursor.dispose();\r
                     return;\r
                 }\r
index 954d992..d260bf5 100644 (file)
@@ -135,7 +135,9 @@ public class FpdFrameworkModules extends IInternalFrame {
     private JTable getJTableAllModules() {\r
         if (jTableAllModules == null) {\r
             modelAllModules = new NonEditableTableModel();\r
-            jTableAllModules = new JTable(modelAllModules);\r
+            TableSorter sorter = new TableSorter(modelAllModules);\r
+            jTableAllModules = new JTable(sorter);\r
+            sorter.setTableHeader(jTableAllModules.getTableHeader());\r
             jTableAllModules.setRowHeight(20);\r
             modelAllModules.addColumn("ModuleName");\r
             modelAllModules.addColumn("ModuleVersion");\r
@@ -181,6 +183,8 @@ public class FpdFrameworkModules extends IInternalFrame {
                         return;\r
                     }\r
                     \r
+                    TableSorter sorter = (TableSorter)jTableAllModules.getModel();\r
+                    selectedRow = sorter.modelIndex(selectedRow);\r
                     String path = modelAllModules.getValueAt(selectedRow, 4)+"";\r
                     ModuleIdentification mi = miList.get(selectedRow);\r
                     Vector<String> vArchs = null;\r
@@ -297,7 +301,9 @@ public class FpdFrameworkModules extends IInternalFrame {
     private JTable getJTableFpdModules() {\r
         if (jTableFpdModules == null) {\r
             modelFpdModules = new NonEditableTableModel();\r
-            jTableFpdModules = new JTable(modelFpdModules);\r
+            TableSorter sorter = new TableSorter(modelFpdModules);\r
+            jTableFpdModules = new JTable(sorter);\r
+            sorter.setTableHeader(jTableFpdModules.getTableHeader());\r
             jTableFpdModules.setRowHeight(20);\r
             modelFpdModules.addColumn("ModuleName");\r
             modelFpdModules.addColumn("ModuleVersion");            \r
@@ -327,6 +333,10 @@ public class FpdFrameworkModules extends IInternalFrame {
                     if (selectedRow < 0){\r
                         return;\r
                     }\r
+                    \r
+                    TableSorter sorter = (TableSorter)jTableFpdModules.getModel();\r
+                    selectedRow = sorter.modelIndex(selectedRow);\r
+                    \r
                     if (settingDlg == null) {\r
                         settingDlg = new FpdModuleSA(ffc);\r
                     }\r
@@ -362,6 +372,10 @@ public class FpdFrameworkModules extends IInternalFrame {
                     if (selectedRow < 0){\r
                         return;\r
                     }\r
+                    \r
+                    TableSorter sorter = (TableSorter)jTableFpdModules.getModel();\r
+                    selectedRow = sorter.modelIndex(selectedRow);\r
+                    \r
                     String[] sa = new String[5];\r
                     ffc.getFrameworkModuleInfo(selectedRow, sa);\r
                     String mg = sa[0];\r
diff --git a/Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/TableSorter.java b/Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/TableSorter.java
new file mode 100644 (file)
index 0000000..d7f1f13
--- /dev/null
@@ -0,0 +1,402 @@
+package org.tianocore.frameworkwizard.platform.ui;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.List;
+
+import javax.swing.*;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.*;
+
+
+public class TableSorter extends AbstractTableModel {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    protected TableModel tableModel;
+
+    public static final int DESCENDING = -1;
+    public static final int NOT_SORTED = 0;
+    public static final int ASCENDING = 1;
+
+    private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
+    
+
+    private Row[] viewToModel;
+    private int[] modelToView;
+
+    private JTableHeader tableHeader;
+    private MouseListener mouseListener;
+    private TableModelListener tableModelListener;
+    
+    private List<Directive> sortingColumns = new ArrayList<Directive>();
+
+    public TableSorter() {
+        this.mouseListener = new MouseHandler();
+        this.tableModelListener = new TableModelHandler();
+    }
+
+    public TableSorter(TableModel tableModel) {
+        this();
+        setTableModel(tableModel);
+    }
+
+
+    private void clearSortingState() {
+        viewToModel = null;
+        modelToView = null;
+    }
+
+    public TableModel getTableModel() {
+        return tableModel;
+    }
+
+    public void setTableModel(TableModel tableModel) {
+        if (this.tableModel != null) {
+            this.tableModel.removeTableModelListener(tableModelListener);
+        }
+
+        this.tableModel = tableModel;
+        if (this.tableModel != null) {
+            this.tableModel.addTableModelListener(tableModelListener);
+        }
+
+        clearSortingState();
+        fireTableStructureChanged();
+    }
+
+    public JTableHeader getTableHeader() {
+        return tableHeader;
+    }
+
+    public void setTableHeader(JTableHeader tableHeader) {
+        if (this.tableHeader != null) {
+            this.tableHeader.removeMouseListener(mouseListener);
+            TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
+            if (defaultRenderer instanceof SortableHeaderRenderer) {
+                this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
+            }
+        }
+        this.tableHeader = tableHeader;
+        if (this.tableHeader != null) {
+            this.tableHeader.addMouseListener(mouseListener);
+            this.tableHeader.setDefaultRenderer(
+                    new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
+        }
+    }
+
+    public boolean isSorting() {
+        return sortingColumns.size() != 0;
+    }
+
+    private Directive getDirective(int column) {
+        for (int i = 0; i < sortingColumns.size(); i++) {
+            Directive directive = (Directive)sortingColumns.get(i);
+            if (directive.column == column) {
+                return directive;
+            }
+        }
+        return EMPTY_DIRECTIVE;
+    }
+
+    public int getSortingStatus(int column) {
+        return getDirective(column).direction;
+    }
+
+    private void sortingStatusChanged() {
+        clearSortingState();
+        fireTableDataChanged();
+        if (tableHeader != null) {
+            tableHeader.repaint();
+        }
+    }
+
+    public void setSortingStatus(int column, int status) {
+        Directive directive = getDirective(column);
+        if (directive != EMPTY_DIRECTIVE) {
+            sortingColumns.remove(directive);
+        }
+        if (status != NOT_SORTED) {
+            sortingColumns.add(new Directive(column, status));
+        }
+        sortingStatusChanged();
+    }
+
+    protected Icon getHeaderRendererIcon(int column, int size) {
+        Directive directive = getDirective(column);
+        if (directive == EMPTY_DIRECTIVE) {
+            return null;
+        }
+        return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));
+    }
+
+    private void cancelSorting() {
+        sortingColumns.clear();
+        sortingStatusChanged();
+    }
+
+    private Row[] getViewToModel() {
+        if (viewToModel == null) {
+            int tableModelRowCount = tableModel.getRowCount();
+            viewToModel = new Row[tableModelRowCount];
+            for (int row = 0; row < tableModelRowCount; row++) {
+                viewToModel[row] = new Row(row);
+            }
+
+            if (isSorting()) {
+                Arrays.sort(viewToModel);
+            }
+        }
+        return viewToModel;
+    }
+
+    public int modelIndex(int viewIndex) {
+        return getViewToModel()[viewIndex].modelIndex;
+    }
+
+    private int[] getModelToView() {
+        if (modelToView == null) {
+            int n = getViewToModel().length;
+            modelToView = new int[n];
+            for (int i = 0; i < n; i++) {
+                modelToView[modelIndex(i)] = i;
+            }
+        }
+        return modelToView;
+    }
+
+    // TableModel interface methods 
+
+    public int getRowCount() {
+        return (tableModel == null) ? 0 : tableModel.getRowCount();
+    }
+
+    public int getColumnCount() {
+        return (tableModel == null) ? 0 : tableModel.getColumnCount();
+    }
+
+    public String getColumnName(int column) {
+        return tableModel.getColumnName(column);
+    }
+
+    public Class<?> getColumnClass(int column) {
+        return tableModel.getColumnClass(column);
+    }
+
+    public boolean isCellEditable(int row, int column) {
+        return tableModel.isCellEditable(modelIndex(row), column);
+    }
+
+    public Object getValueAt(int row, int column) {
+        return tableModel.getValueAt(modelIndex(row), column);
+    }
+
+    public void setValueAt(Object aValue, int row, int column) {
+        tableModel.setValueAt(aValue, modelIndex(row), column);
+    }
+
+    // Helper classes
+    
+    private class Row implements Comparable {
+        private int modelIndex;
+
+        public Row(int index) {
+            this.modelIndex = index;
+        }
+
+        public int compareTo(Object o) {
+            int row1 = modelIndex;
+            int row2 = ((Row) o).modelIndex;
+
+            for (Iterator it = sortingColumns.iterator(); it.hasNext();) {
+                Directive directive = (Directive) it.next();
+                int column = directive.column;
+                Object o1 = tableModel.getValueAt(row1, column);
+                Object o2 = tableModel.getValueAt(row2, column);
+
+                int comparison = 0;
+                // Define null less than everything, except null.
+                if (o1 == null && o2 == null) {
+                    comparison = 0;
+                } else if (o1 == null) {
+                    comparison = -1;
+                } else if (o2 == null) {
+                    comparison = 1;
+                } else {
+                    comparison = o1.toString().compareTo(o2.toString());;
+                }
+                if (comparison != 0) {
+                    return directive.direction == DESCENDING ? -comparison : comparison;
+                }
+            }
+            return 0;
+        }
+    }
+
+    private class TableModelHandler implements TableModelListener {
+        public void tableChanged(TableModelEvent e) {
+            // If we're not sorting by anything, just pass the event along.             
+            if (!isSorting()) {
+                clearSortingState();
+                fireTableChanged(e);
+                return;
+            }
+                
+            // If the table structure has changed, cancel the sorting; the             
+            // sorting columns may have been either moved or deleted from             
+            // the model. 
+            if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
+                cancelSorting();
+                fireTableChanged(e);
+                return;
+            }
+
+            // We can map a cell event through to the view without widening             
+            // when the following conditions apply: 
+            // 
+            // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and, 
+            // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
+            // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and, 
+            // d) a reverse lookup will not trigger a sort (modelToView != null)
+            //
+            // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
+            // 
+            // The last check, for (modelToView != null) is to see if modelToView 
+            // is already allocated. If we don't do this check; sorting can become 
+            // a performance bottleneck for applications where cells  
+            // change rapidly in different parts of the table. If cells 
+            // change alternately in the sorting column and then outside of             
+            // it this class can end up re-sorting on alternate cell updates - 
+            // which can be a performance problem for large tables. The last 
+            // clause avoids this problem. 
+            int column = e.getColumn();
+            if (e.getFirstRow() == e.getLastRow()
+                    && column != TableModelEvent.ALL_COLUMNS
+                    && getSortingStatus(column) == NOT_SORTED
+                    && modelToView != null) {
+                int viewIndex = getModelToView()[e.getFirstRow()];
+                fireTableChanged(new TableModelEvent(TableSorter.this, 
+                                                     viewIndex, viewIndex, 
+                                                     column, e.getType()));
+                return;
+            }
+
+            // Something has happened to the data that may have invalidated the row order. 
+            clearSortingState();
+            fireTableDataChanged();
+            return;
+        }
+    }
+
+    private class MouseHandler extends MouseAdapter {
+        public void mouseClicked(MouseEvent e) {
+            JTableHeader h = (JTableHeader) e.getSource();
+            TableColumnModel columnModel = h.getColumnModel();
+            int viewColumn = columnModel.getColumnIndexAtX(e.getX());
+            int column = columnModel.getColumn(viewColumn).getModelIndex();
+            if (column != -1) {
+                int status = getSortingStatus(column);
+                if (!e.isControlDown()) {
+                    cancelSorting();
+                }
+                // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or 
+                // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed. 
+                status = status + (e.isShiftDown() ? -1 : 1);
+                status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1}
+                setSortingStatus(column, status);
+            }
+        }
+    }
+
+    private static class Arrow implements Icon {
+        private boolean descending;
+        private int size;
+        private int priority;
+
+        public Arrow(boolean descending, int size, int priority) {
+            this.descending = descending;
+            this.size = size;
+            this.priority = priority;
+        }
+
+        public void paintIcon(Component c, Graphics g, int x, int y) {
+            Color color = c == null ? Color.GRAY : c.getBackground();             
+            // In a compound sort, make each succesive triangle 20% 
+            // smaller than the previous one. 
+            int dx = (int)(size/2*Math.pow(0.8, priority));
+            int dy = descending ? dx : -dx;
+            // Align icon (roughly) with font baseline. 
+            y = y + 5*size/6 + (descending ? -dy : 0);
+            int shift = descending ? 1 : -1;
+            g.translate(x, y);
+
+            // Right diagonal. 
+            g.setColor(color.darker());
+            g.drawLine(dx / 2, dy, 0, 0);
+            g.drawLine(dx / 2, dy + shift, 0, shift);
+            
+            // Left diagonal. 
+            g.setColor(color.brighter());
+            g.drawLine(dx / 2, dy, dx, 0);
+            g.drawLine(dx / 2, dy + shift, dx, shift);
+            
+            // Horizontal line. 
+            if (descending) {
+                g.setColor(color.darker().darker());
+            } else {
+                g.setColor(color.brighter().brighter());
+            }
+            g.drawLine(dx, 0, 0, 0);
+
+            g.setColor(color);
+            g.translate(-x, -y);
+        }
+
+        public int getIconWidth() {
+            return size;
+        }
+
+        public int getIconHeight() {
+            return size;
+        }
+    }
+
+    private class SortableHeaderRenderer implements TableCellRenderer {
+        private TableCellRenderer tableCellRenderer;
+
+        public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {
+            this.tableCellRenderer = tableCellRenderer;
+        }
+
+        public Component getTableCellRendererComponent(JTable table, 
+                                                       Object value,
+                                                       boolean isSelected, 
+                                                       boolean hasFocus,
+                                                       int row, 
+                                                       int column) {
+            Component c = tableCellRenderer.getTableCellRendererComponent(table, 
+                    value, isSelected, hasFocus, row, column);
+            if (c instanceof JLabel) {
+                JLabel l = (JLabel) c;
+                l.setHorizontalTextPosition(JLabel.LEFT);
+                int modelColumn = table.convertColumnIndexToModel(column);
+                l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize()));
+            }
+            return c;
+        }
+    }
+
+    private static class Directive {
+        private int column;
+        private int direction;
+
+        public Directive(int column, int direction) {
+            this.column = column;
+            this.direction = direction;
+        }
+    }
+}
index afa4c31..44f6f36 100644 (file)
@@ -126,6 +126,7 @@ public class GlobalData {
             //\r
             // Get package list\r
             //\r
+            packageList.clear();\r
             List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();\r
             \r
             Iterator iter = packages.iterator();\r
@@ -133,9 +134,7 @@ public class GlobalData {
                 DbPathAndFilename dbPath = (DbPathAndFilename)iter.next();\r
                 String fileName = dbPath.getStringValue();\r
                 Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));\r
-                if (!packageList.contains(spd.getPackageId())) {\r
-                    packageList.add(spd.getPackageId());\r
-                }\r
+                packageList.add(spd.getPackageId());\r
                 spdTable.put(spd.getPackageId(), spd);\r
             }\r
 \r