View Javadoc

1   /*
2    *  File: TableExtension.java 
3    *  Copyright (c) 2004-2007  Peter Kliem (Peter.Kliem@jaret.de)
4    *  A commercial license is available, see http://www.jaret.de.
5    *
6    * All rights reserved. This program and the accompanying materials
7    * are made available under the terms of the Common Public License v1.0
8    * which accompanies this distribution, and is available at
9    * http://www.eclipse.org/legal/cpl-v10.html
10   */
11  package de.jaret.util.ui;
12  
13  import org.eclipse.jface.resource.ImageDescriptor;
14  import org.eclipse.jface.resource.ImageRegistry;
15  import org.eclipse.jface.viewers.IStructuredContentProvider;
16  import org.eclipse.jface.viewers.ITableLabelProvider;
17  import org.eclipse.jface.viewers.TableViewer;
18  import org.eclipse.jface.viewers.Viewer;
19  import org.eclipse.jface.viewers.ViewerComparator;
20  import org.eclipse.swt.events.DisposeEvent;
21  import org.eclipse.swt.events.DisposeListener;
22  import org.eclipse.swt.events.SelectionEvent;
23  import org.eclipse.swt.events.SelectionListener;
24  import org.eclipse.swt.graphics.GC;
25  import org.eclipse.swt.graphics.Point;
26  import org.eclipse.swt.widgets.TableColumn;
27  
28  /**
29   * TableExtension is a buddy for a TableViewer allowing sorting on click on the column header and a width optimization
30   * of the column on doubleclick on the column header.
31   * 
32   * The double click is handled manually by a selectionListener since the addListener(MouseDoubleClick ) on the cols does
33   * not work.
34   * 
35   * @author Peter Kliem
36   * @version $Id: TableExtension.java 242 2007-02-11 21:05:07Z olk $
37   */
38  public class TableExtension implements SelectionListener, DisposeListener {// , Listener {
39  
40      boolean _doWidthControl = true;
41      long _lastClick = -1;
42      int _lastClickColIdx = -1;
43      int _sortingcol = -1;
44      int _invert = 1;
45      TableViewer _tviewer;
46      TableExtensionViewerSorter _sorter;
47  
48      private ImageRegistry _imageRegistry;
49  
50      /**
51       * Constructor
52       * 
53       * @param tableViewer table viewer that is extended.
54       * @param doWidthOptimization true for enabling of widht optimization (double click)
55       */
56      public TableExtension(TableViewer tableViewer, boolean doWidthOptimization) {
57          _tviewer = tableViewer;
58          TableColumn cols[] = tableViewer.getTable().getColumns();
59          for (int i = 0; i < cols.length; i++) {
60              cols[i].addSelectionListener(this);
61              // cols[i].addListener(SWT.MouseDoubleClick, this);
62          }
63          _sorter = new TableExtensionViewerSorter();
64          setDoWidthOptimization(doWidthOptimization);
65          _tviewer.getTable().addDisposeListener(this);
66      }
67  
68      /**
69       * Constructor. Width optimization defaults to true.
70       * 
71       * @param tableViewer tableViewer table viewer that is extended.
72       */
73      public TableExtension(TableViewer tableViewer) {
74          this(tableViewer, true);
75      }
76  
77      /**
78       * If set to true the extension will react on double click doing a width change of the column.
79       * 
80       * @param doWidthControl true for enabling widht changes
81       */
82      public void setDoWidthOptimization(boolean doWidthControl) {
83          _doWidthControl = doWidthControl;
84      }
85  
86      /*
87       * (non-Javadoc)
88       * 
89       * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
90       */
91      public void widgetSelected(SelectionEvent event) {
92          TableColumn tc = (TableColumn) event.getSource();
93          int idx = _tviewer.getTable().indexOf(tc);
94  
95          if (_doWidthControl) {
96              if (_lastClickColIdx != idx) {
97                  _lastClickColIdx = idx;
98              } else {
99                  if (System.currentTimeMillis() - _lastClick < 800) {
100                     doWidthOpt(idx, tc);
101                 }
102             }
103             _lastClick = System.currentTimeMillis();
104         }
105 
106         if (_sortingcol != -1) {
107             _tviewer.getTable().getColumn(_sortingcol).setImage(null);
108         }
109         if (_sortingcol == idx && _invert == -1) {
110             _sortingcol = -1;
111             _invert = 1;
112             _tviewer.setSorter(null);
113         } else {
114             if (_sortingcol == idx) {
115                 _invert = _invert * -1;
116             } else {
117                 _invert = 1;
118             }
119             _sortingcol = idx;
120             if (_invert == 1) {
121                 tc.setImage(getImageRegistry().get("down"));
122             } else {
123                 tc.setImage(getImageRegistry().get("up"));
124             }
125             _tviewer.getTable().setRedraw(false);
126             _tviewer.setComparator(null);
127             _tviewer.setComparator(_sorter);
128             _tviewer.getTable().setRedraw(true);
129         }
130     }
131 
132     /**
133      * optimize the width of th column to the max wdth of the cuurently available using the gc of the table (maybe this
134      * should be changed to computeSize of the tabeitem)
135      * 
136      * @param tc
137      */
138     private void doWidthOpt(int idx, TableColumn tc) {
139         IStructuredContentProvider contentProvider = (IStructuredContentProvider) _tviewer.getContentProvider();
140         ITableLabelProvider lprovider = (ITableLabelProvider) _tviewer.getLabelProvider();
141         GC gc = new GC(_tviewer.getTable());
142 
143         Object items[] = contentProvider.getElements(_tviewer.getInput());
144         int max = 0;
145 
146         for (int i = 0; i < items.length; i++) {
147             String str = lprovider.getColumnText(items[i], idx);
148             Point p = gc.textExtent(str);
149             if (p.x > max) {
150                 max = p.x;
151             }
152         }
153         tc.setWidth(max + 20);
154         gc.dispose();
155     }
156 
157     /*
158      * (non-Javadoc)
159      * 
160      * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
161      */
162     public void widgetDefaultSelected(SelectionEvent arg0) {
163     }
164 
165     private ImageRegistry getImageRegistry() {
166         if (_imageRegistry == null) {
167             _imageRegistry = new ImageRegistry();
168             ImageDescriptor imgDesc = new ResourceImageDescriptor("/de/jaret/util/rsc/smallarrow_up.gif");
169             _imageRegistry.put("up", imgDesc);
170             imgDesc = new ResourceImageDescriptor("/de/jaret/util/rsc/smallarrow_down.gif");
171             _imageRegistry.put("down", imgDesc);
172         }
173         return _imageRegistry;
174     }
175 
176     private class TableExtensionViewerSorter extends ViewerComparator {
177         public int compare(Viewer viewer, Object e1, Object e2) {
178             ITableLabelProvider lprovider = (ITableLabelProvider) _tviewer.getLabelProvider();
179             String str1 = lprovider.getColumnText(e1, _sortingcol);
180             String str2 = lprovider.getColumnText(e2, _sortingcol);
181             return getComparator().compare(str1, str2) * _invert;
182         }
183     }
184 
185     /**
186      * On dispose of the table viewer dispose imgae registry
187      * 
188      * @param arg0
189      */
190     public void widgetDisposed(DisposeEvent arg0) {
191         if (_imageRegistry != null) {
192             _imageRegistry.dispose();
193         }
194     }
195 
196     /*
197      * (non-Javadoc)
198      * 
199      * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
200      */
201     /*
202      * public void handleEvent(Event arg0) { System.out.println("mouse double click " + arg0.button); }
203      */
204 }