]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils.ui.workbench/src/org/simantics/utils/ui/workbench/ui/TableColumnSorter.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.utils.ui.workbench / src / org / simantics / utils / ui / workbench / ui / TableColumnSorter.java
diff --git a/bundles/org.simantics.utils.ui.workbench/src/org/simantics/utils/ui/workbench/ui/TableColumnSorter.java b/bundles/org.simantics.utils.ui.workbench/src/org/simantics/utils/ui/workbench/ui/TableColumnSorter.java
new file mode 100644 (file)
index 0000000..2ce76b5
--- /dev/null
@@ -0,0 +1,236 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.utils.ui.workbench.ui;\r
+\r
+import java.util.Comparator;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.viewers.IBaseLabelProvider;\r
+import org.eclipse.jface.viewers.ITableLabelProvider;\r
+import org.eclipse.jface.viewers.TableViewer;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.jface.viewers.ViewerSorter;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+import org.eclipse.ui.IMemento;\r
+\r
+/**\r
+ * This class adds column sorting functionality to SWT Table widget.\r
+ * <p>\r
+ * Attach this Sorter after you have created all columns.\r
+ * <p>\r
+ * Usage: TableColumnSorter.attachTableColumnSorter(myTable);\r
+ * \r
+ * @author Toni Kalajainen\r
+ */\r
+public class TableColumnSorter {\r
+\r
+    /** The table */\r
+    protected final TableViewer viewer;\r
+    \r
+    /** the sorter */\r
+    protected final ColumnSorter sorter;\r
+    \r
+    /** column specific comparators*/\r
+    protected Map<Integer, Comparator<?>> columnComparators = \r
+        new HashMap<Integer, Comparator<?>>();    \r
+    \r
+    public static TableColumnSorter attachTableColumnSorter(TableViewer viewer) {\r
+        return new TableColumnSorter(viewer);\r
+    }\r
+    \r
+    public static void unattachTableColumnSorter(TableViewer viewer) {\r
+        viewer.setSorter(null);\r
+    }\r
+    \r
+    public void setColumnComparator(int index, Comparator<?> comparator)\r
+    {\r
+        columnComparators.put(index, comparator);\r
+        viewer.refresh();\r
+    }\r
+    \r
+    private final static String PRI_ASC = "PriAsc";\r
+    private final static String SEC_ASC = "SecAsc";\r
+    private final static String PRI_IND = "PriInd";\r
+    private final static String SEC_IND = "SecInd";\r
+    \r
+    public void saveState(String id, IMemento memento) {\r
+        memento.putInteger(id+PRI_ASC, sorter.isAscending()?1:0);\r
+        memento.putInteger(id+SEC_ASC, sorter.isSecondaryAscending()?1:0);        \r
+        memento.putInteger(id+PRI_IND, sorter.getIndex());\r
+        memento.putInteger(id+SEC_IND, sorter.getSecondaryIndex());\r
+    }\r
+\r
+    public void restoreState(String id, IMemento memento) {\r
+        if (!hasState(id, memento)) return;\r
+            \r
+        sorter.setAscending( memento.getInteger(id+PRI_ASC)==1 );\r
+        sorter.setSecondaryAscending( memento.getInteger(id+SEC_ASC)==1 );\r
+        sorter.setIndex( memento.getInteger(id+PRI_IND) );\r
+        sorter.setSecondaryIndex( memento.getInteger(id+SEC_IND) );\r
+        \r
+        viewer.refresh();\r
+    }\r
+    \r
+    public boolean hasState(String id, IMemento memento) {\r
+        return (memento.getInteger(id+PRI_ASC)!=null) && \r
+               (memento.getInteger(id+SEC_ASC)!=null) && \r
+               (memento.getInteger(id+PRI_IND)!=null) && \r
+               (memento.getInteger(id+SEC_IND)!=null); \r
+    }\r
+    \r
+    public void setColumnAscending(int index)\r
+    {\r
+        sorter.setIndex(index);\r
+        sorter.setAscending(true);\r
+        viewer.refresh();\r
+    }    \r
+    \r
+    private TableColumnSorter(TableViewer viewer) {\r
+        this.viewer = viewer;\r
+        this.sorter = new ColumnSorter();\r
+        \r
+        // Attach columns\r
+        TableColumn columns[] = viewer.getTable().getColumns(); \r
+        for(int i=0; i<columns.length; i++) {\r
+            TableColumn column = columns[i];\r
+            column.setData("index", new Integer(i));\r
+            column.addSelectionListener(new SelectionAdapter() {\r
+                public void widgetSelected(SelectionEvent e) {                    \r
+                    int index = (Integer) e.widget.getData("index");\r
+                    if (index == TableColumnSorter.this.sorter.getIndex()) {\r
+                        // Reverse order\r
+                        TableColumnSorter.this.sorter.setAscending( !TableColumnSorter.this.sorter.isAscending() );\r
+                    } else {\r
+                        TableColumnSorter.this.sorter.setSecondaryIndex( TableColumnSorter.this.sorter.getIndex() );\r
+                        TableColumnSorter.this.sorter.setSecondaryAscending( TableColumnSorter.this.sorter.isAscending() );\r
+                        TableColumnSorter.this.sorter.setIndex(index);\r
+                        TableColumnSorter.this.sorter.setAscending(true);\r
+                    }\r
+                    TableColumnSorter.this.viewer.refresh();\r
+                }\r
+            });\r
+        }\r
+        viewer.setSorter(sorter);\r
+    }\r
+    \r
+    \r
+    class ColumnSorter extends ViewerSorter {\r
+        /** Sort direction */\r
+        private boolean ascending = true;\r
+        /** Secondary Sort direction */\r
+        private boolean secondaryAscending = true;\r
+        /** Sort column */\r
+        private int columnIndex = 0;\r
+        /** Secondary sort column */\r
+        private int secondaryColumnIndex = -1;\r
+        /** case sensitive */\r
+        private boolean caseSensitive = false;\r
+        \r
+        public void setAscending(boolean ascending) {\r
+            this.ascending = ascending;\r
+        }\r
+                \r
+        public boolean isAscending() {\r
+            return ascending;\r
+        }        \r
+        \r
+        public void setSecondaryAscending(boolean ascending) {\r
+            this.secondaryAscending = ascending;\r
+        }\r
+                \r
+        public boolean isSecondaryAscending() {\r
+            return secondaryAscending;\r
+        }        \r
+        \r
+        public void setIndex(int index) {\r
+            this.columnIndex = index;\r
+        }\r
+        \r
+        public int getIndex() {\r
+            return columnIndex;\r
+        }\r
+        \r
+        public void setSecondaryIndex(int index) {\r
+            this.secondaryColumnIndex = index;\r
+        }\r
+        \r
+        public int getSecondaryIndex() {\r
+            return secondaryColumnIndex;\r
+        }\r
+\r
+        @SuppressWarnings("unchecked")\r
+        private int compare(int columnIndex, String text1, String text2, Object o1, Object o2)\r
+        {\r
+            @SuppressWarnings("rawtypes")\r
+            Comparator c = columnComparators.get(columnIndex);\r
+            if (c==null || o1==null || o2==null)\r
+                return text1.compareTo(text2);\r
+            return c.compare(o1, o2);\r
+        }\r
+        \r
+        public int compare(Viewer viewer, Object e1, Object e2) {\r
+            int result = 0;\r
+            \r
+            TableViewer v = (TableViewer) viewer;            \r
+            IBaseLabelProvider blp = v.getLabelProvider();\r
+            if (!(blp instanceof ITableLabelProvider)) {\r
+                return super.compare(viewer, e1, e2);\r
+            }\r
+            ITableLabelProvider tlp = (ITableLabelProvider) blp;\r
+            \r
+            // Primary sort\r
+            String text1 = tlp.getColumnText(e1, columnIndex);\r
+            String text2 = tlp.getColumnText(e2, columnIndex);\r
+            if (text1==null) text1="";\r
+            if (text2==null) text2="";            \r
+            if (!caseSensitive) {\r
+                text1 = text1.toLowerCase();\r
+                text2 = text2.toLowerCase();\r
+            }            \r
+            result = compare(columnIndex, text1, text2, e1, e2);            \r
+            if (!ascending) return -result;\r
+            \r
+            // secondary sort\r
+            if (result==0 && (secondaryColumnIndex>=0)) {\r
+                text1 = tlp.getColumnText(e1, secondaryColumnIndex);\r
+                text2 = tlp.getColumnText(e2, secondaryColumnIndex);\r
+                if (text1==null) text1="";\r
+                if (text2==null) text2="";            \r
+                if (!caseSensitive) {\r
+                    text1 = text1.toLowerCase();\r
+                    text2 = text2.toLowerCase();\r
+                }            \r
+                result = compare(secondaryColumnIndex, text1, text2, e1, e2);\r
+                \r
+                if (!secondaryAscending) return -result;\r
+            }\r
+            \r
+            return result;\r
+        }\r
+\r
+        public boolean isCaseSensitive() {\r
+            return caseSensitive;\r
+        }\r
+\r
+        public void setCaseSensitive(boolean caseSensitive) {\r
+            this.caseSensitive = caseSensitive;\r
+        }\r
+    }\r
+\r
+    public ColumnSorter getSorter() {\r
+        return sorter;\r
+    }\r
+\r
+}\r