]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.utils.ui.workbench.ui;\r
13 \r
14 import java.util.Comparator;\r
15 import java.util.HashMap;\r
16 import java.util.Map;\r
17 \r
18 import org.eclipse.jface.viewers.IBaseLabelProvider;\r
19 import org.eclipse.jface.viewers.ITableLabelProvider;\r
20 import org.eclipse.jface.viewers.TableViewer;\r
21 import org.eclipse.jface.viewers.Viewer;\r
22 import org.eclipse.jface.viewers.ViewerSorter;\r
23 import org.eclipse.swt.events.SelectionAdapter;\r
24 import org.eclipse.swt.events.SelectionEvent;\r
25 import org.eclipse.swt.widgets.TableColumn;\r
26 import org.eclipse.ui.IMemento;\r
27 \r
28 /**\r
29  * This class adds column sorting functionality to SWT Table widget.\r
30  * <p>\r
31  * Attach this Sorter after you have created all columns.\r
32  * <p>\r
33  * Usage: TableColumnSorter.attachTableColumnSorter(myTable);\r
34  * \r
35  * @author Toni Kalajainen\r
36  */\r
37 public class TableColumnSorter {\r
38 \r
39     /** The table */\r
40     protected final TableViewer viewer;\r
41     \r
42     /** the sorter */\r
43     protected final ColumnSorter sorter;\r
44     \r
45     /** column specific comparators*/\r
46     protected Map<Integer, Comparator<?>> columnComparators = \r
47         new HashMap<Integer, Comparator<?>>();    \r
48     \r
49     public static TableColumnSorter attachTableColumnSorter(TableViewer viewer) {\r
50         return new TableColumnSorter(viewer);\r
51     }\r
52     \r
53     public static void unattachTableColumnSorter(TableViewer viewer) {\r
54         viewer.setSorter(null);\r
55     }\r
56     \r
57     public void setColumnComparator(int index, Comparator<?> comparator)\r
58     {\r
59         columnComparators.put(index, comparator);\r
60         viewer.refresh();\r
61     }\r
62     \r
63     private final static String PRI_ASC = "PriAsc";\r
64     private final static String SEC_ASC = "SecAsc";\r
65     private final static String PRI_IND = "PriInd";\r
66     private final static String SEC_IND = "SecInd";\r
67     \r
68     public void saveState(String id, IMemento memento) {\r
69         memento.putInteger(id+PRI_ASC, sorter.isAscending()?1:0);\r
70         memento.putInteger(id+SEC_ASC, sorter.isSecondaryAscending()?1:0);        \r
71         memento.putInteger(id+PRI_IND, sorter.getIndex());\r
72         memento.putInteger(id+SEC_IND, sorter.getSecondaryIndex());\r
73     }\r
74 \r
75     public void restoreState(String id, IMemento memento) {\r
76         if (!hasState(id, memento)) return;\r
77             \r
78         sorter.setAscending( memento.getInteger(id+PRI_ASC)==1 );\r
79         sorter.setSecondaryAscending( memento.getInteger(id+SEC_ASC)==1 );\r
80         sorter.setIndex( memento.getInteger(id+PRI_IND) );\r
81         sorter.setSecondaryIndex( memento.getInteger(id+SEC_IND) );\r
82         \r
83         viewer.refresh();\r
84     }\r
85     \r
86     public boolean hasState(String id, IMemento memento) {\r
87         return (memento.getInteger(id+PRI_ASC)!=null) && \r
88                (memento.getInteger(id+SEC_ASC)!=null) && \r
89                (memento.getInteger(id+PRI_IND)!=null) && \r
90                (memento.getInteger(id+SEC_IND)!=null); \r
91     }\r
92     \r
93     public void setColumnAscending(int index)\r
94     {\r
95         sorter.setIndex(index);\r
96         sorter.setAscending(true);\r
97         viewer.refresh();\r
98     }    \r
99     \r
100     private TableColumnSorter(TableViewer viewer) {\r
101         this.viewer = viewer;\r
102         this.sorter = new ColumnSorter();\r
103         \r
104         // Attach columns\r
105         TableColumn columns[] = viewer.getTable().getColumns(); \r
106         for(int i=0; i<columns.length; i++) {\r
107             TableColumn column = columns[i];\r
108             column.setData("index", new Integer(i));\r
109             column.addSelectionListener(new SelectionAdapter() {\r
110                 public void widgetSelected(SelectionEvent e) {                    \r
111                     int index = (Integer) e.widget.getData("index");\r
112                     if (index == TableColumnSorter.this.sorter.getIndex()) {\r
113                         // Reverse order\r
114                         TableColumnSorter.this.sorter.setAscending( !TableColumnSorter.this.sorter.isAscending() );\r
115                     } else {\r
116                         TableColumnSorter.this.sorter.setSecondaryIndex( TableColumnSorter.this.sorter.getIndex() );\r
117                         TableColumnSorter.this.sorter.setSecondaryAscending( TableColumnSorter.this.sorter.isAscending() );\r
118                         TableColumnSorter.this.sorter.setIndex(index);\r
119                         TableColumnSorter.this.sorter.setAscending(true);\r
120                     }\r
121                     TableColumnSorter.this.viewer.refresh();\r
122                 }\r
123             });\r
124         }\r
125         viewer.setSorter(sorter);\r
126     }\r
127     \r
128     \r
129     class ColumnSorter extends ViewerSorter {\r
130         /** Sort direction */\r
131         private boolean ascending = true;\r
132         /** Secondary Sort direction */\r
133         private boolean secondaryAscending = true;\r
134         /** Sort column */\r
135         private int columnIndex = 0;\r
136         /** Secondary sort column */\r
137         private int secondaryColumnIndex = -1;\r
138         /** case sensitive */\r
139         private boolean caseSensitive = false;\r
140         \r
141         public void setAscending(boolean ascending) {\r
142             this.ascending = ascending;\r
143         }\r
144                 \r
145         public boolean isAscending() {\r
146             return ascending;\r
147         }        \r
148         \r
149         public void setSecondaryAscending(boolean ascending) {\r
150             this.secondaryAscending = ascending;\r
151         }\r
152                 \r
153         public boolean isSecondaryAscending() {\r
154             return secondaryAscending;\r
155         }        \r
156         \r
157         public void setIndex(int index) {\r
158             this.columnIndex = index;\r
159         }\r
160         \r
161         public int getIndex() {\r
162             return columnIndex;\r
163         }\r
164         \r
165         public void setSecondaryIndex(int index) {\r
166             this.secondaryColumnIndex = index;\r
167         }\r
168         \r
169         public int getSecondaryIndex() {\r
170             return secondaryColumnIndex;\r
171         }\r
172 \r
173         @SuppressWarnings("unchecked")\r
174         private int compare(int columnIndex, String text1, String text2, Object o1, Object o2)\r
175         {\r
176             @SuppressWarnings("rawtypes")\r
177             Comparator c = columnComparators.get(columnIndex);\r
178             if (c==null || o1==null || o2==null)\r
179                 return text1.compareTo(text2);\r
180             return c.compare(o1, o2);\r
181         }\r
182         \r
183         public int compare(Viewer viewer, Object e1, Object e2) {\r
184             int result = 0;\r
185             \r
186             TableViewer v = (TableViewer) viewer;            \r
187             IBaseLabelProvider blp = v.getLabelProvider();\r
188             if (!(blp instanceof ITableLabelProvider)) {\r
189                 return super.compare(viewer, e1, e2);\r
190             }\r
191             ITableLabelProvider tlp = (ITableLabelProvider) blp;\r
192             \r
193             // Primary sort\r
194             String text1 = tlp.getColumnText(e1, columnIndex);\r
195             String text2 = tlp.getColumnText(e2, columnIndex);\r
196             if (text1==null) text1="";\r
197             if (text2==null) text2="";            \r
198             if (!caseSensitive) {\r
199                 text1 = text1.toLowerCase();\r
200                 text2 = text2.toLowerCase();\r
201             }            \r
202             result = compare(columnIndex, text1, text2, e1, e2);            \r
203             if (!ascending) return -result;\r
204             \r
205             // secondary sort\r
206             if (result==0 && (secondaryColumnIndex>=0)) {\r
207                 text1 = tlp.getColumnText(e1, secondaryColumnIndex);\r
208                 text2 = tlp.getColumnText(e2, secondaryColumnIndex);\r
209                 if (text1==null) text1="";\r
210                 if (text2==null) text2="";            \r
211                 if (!caseSensitive) {\r
212                     text1 = text1.toLowerCase();\r
213                     text2 = text2.toLowerCase();\r
214                 }            \r
215                 result = compare(secondaryColumnIndex, text1, text2, e1, e2);\r
216                 \r
217                 if (!secondaryAscending) return -result;\r
218             }\r
219             \r
220             return result;\r
221         }\r
222 \r
223         public boolean isCaseSensitive() {\r
224             return caseSensitive;\r
225         }\r
226 \r
227         public void setCaseSensitive(boolean caseSensitive) {\r
228             this.caseSensitive = caseSensitive;\r
229         }\r
230     }\r
231 \r
232     public ColumnSorter getSorter() {\r
233         return sorter;\r
234     }\r
235 \r
236 }\r