Bug 75114 - [Viewers] TableViewer-Enhancement for Editing
Summary: [Viewers] TableViewer-Enhancement for Editing
Status: RESOLVED DUPLICATE of bug 142655
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.0   Edit
Hardware: All All
: P4 enhancement with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Boris Bokowski CLA
QA Contact:
URL:
Whiteboard:
Keywords: helpwanted
Depends on:
Blocks:
 
Reported: 2004-09-27 14:40 EDT by Thomas Schindl CLA
Modified: 2006-05-19 07:37 EDT (History)
0 users

See Also:


Attachments
A modified TableViewer (26.00 KB, text/x-java)
2005-02-28 05:21 EST, Thomas Schindl CLA
no flags Details
A modified TableViewerImpl (12.35 KB, text/x-java)
2005-02-28 05:22 EST, Thomas Schindl CLA
no flags Details
This is very flexible implementation to add tab support to TableViewer (9.15 KB, patch)
2006-05-13 12:40 EDT, Thomas Schindl CLA
no flags Details | Diff
A more generalized version which also includes "support" for TreeViewer (18.17 KB, patch)
2006-05-13 14:12 EDT, Thomas Schindl CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Schindl CLA 2004-09-27 14:40:56 EDT
Not sure where to commit JFace feature requests. When using a TableViewer e.g.
as a frontend to a database-table where users can edit things it would be
extremely helpful if one could use the Tab-key to jump from column to column
instead of using the mouse.
Comment 1 Tod Creasey CLA 2004-09-28 07:52:22 EDT
You could do this with a key listener yourself as well but it would be an 
interesting idea.

If you have a suggested implementation of a key listener we would be happy toi 
look it over.
Comment 2 Thomas Schindl CLA 2004-09-28 08:16:01 EDT
I have already looked a little bit around and had the feeling that the
cell-editor has:
* to implement a TraverseListener 
* cancle the TAB-Keyevent
* move to the next column if one exist or to the first column in the next row

Still I'm not completely sure about this. I also asked at the mailling list
where Veronika pointed me to the following SWT-Snippet:
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet96.java?rev=HEAD&content-type=text/vnd.viewcvs-markup
Comment 3 Thomas Schindl CLA 2004-09-28 10:13:17 EDT
This is how far I got but I don't know how to active the editor in the
next/prevoius column. Does this make sense?
----------------8<----------------
public class TraversalTest implements TraverseListener {
    private int columnIdx = 0;
    private TableViewer viewer;
    
    public TraversalTest( TableViewer viewer, int columnIdx ) {
        this.columnIdx = columnIdx;
        this.viewer = viewer;
    }
    
    /* (non-Javadoc)
     * @see
org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent)
     */
    public void keyTraversed(TraverseEvent e) {
        // TODO Auto-generated method stub
            if( e.detail == SWT.TRAVERSE_TAB_PREVIOUS || e.detail ==
SWT.TRAVERSE_TAB_NEXT ) {
                if( viewer != null ) {
                    CellEditor[] editors = viewer.getCellEditors();
                    e.doit = false;
                    if( columnIdx > 0 && e.detail == SWT.TRAVERSE_TAB_PREVIOUS ) {
                        // editors[columnIdx].deactivate();
                        // editors[columnIdx-1].activate();
                        // editors[columnIdx-1].setFocus();
                        // editors[columnIdx-1].getControl().forceFocus();
                    } else if( e.detail == SWT.TRAVERSE_TAB_NEXT && columnIdx+1
< editors.length ) {
                        // editors[columnIdx].deactivate();
                        // editors[columnIdx+1].activate();
                        // editors[columnIdx-1].setFocus();
                        // editors[columnIdx+1].getControl().forceFocus();
                    } else {
                        System.out.println("We reached start or end of row");
                    }
                } else {
                    System.out.println("I have no viewer");
                }
            } else {
                System.out.println("No need to cancle its not a tab-event");
            }
    }
}
----------------8<----------------
Comment 4 Thomas Schindl CLA 2004-12-04 09:21:24 EST
I've got it now, overriding the method setCellEditors of TableViewerImpl and
adding an TraverseListener does the job perfectly. 

Still there a few issues not addressed by this implementation now:
* On Linux with Gtk using ComboViewer it does not work properly
* one can not turn on/off the Tabbing TableViewer

Any suggestions?

------------------------8<------------------------
public void setCellEditors(CellEditor[] editors) {
        this.cellEditors = editors;
        
        for (int i = 0; i < editors.length; i++) {
            if (editors[i].getControl() != null) {
                editors[i].getControl().addTraverseListener( new
TraverseListener() {
                    public void keyTraversed(TraverseEvent e) {
                        if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS || e.detail ==
SWT.TRAVERSE_TAB_NEXT) {
                            e.doit = false;
                            
                            if( BesoTableViewerImpl.this.cellEditor != null ) {
                                BesoTableViewerImpl.this.cellEditor.deactivate();
                            }
                            
                            if( e.detail == SWT.TRAVERSE_TAB_PREVIOUS &&
columnNumber > 0 ) {
                                columnNumber--;
                                activateCellEditor();
                            } else if ( e.detail == SWT.TRAVERSE_TAB_NEXT &&
BesoTableViewerImpl.this.cellEditors.length > columnNumber+1 ) {
                                columnNumber++;
                                activateCellEditor();
                            }
                        }
                    }
                });
            }
        }
    }
------------------------8<------------------------
Comment 5 sekar CLA 2005-02-28 03:15:30 EST
Hi,
I read your implementation of the key listener in the TableViewer

I tried your suggestion of overriding the setCellEditors method, but the 
keytraversed method doesn’t seem to get fired on tab out from the column.

also after overriding the setCellEditors method,i also noticed that the table 
columns become non-editable

Any suggestions ?

thanks
sekar

Comment 6 Thomas Schindl CLA 2005-02-28 05:21:25 EST
Created attachment 18352 [details]
A modified TableViewer

This is a TableViewer allowing to Tab from col to  col. I'm not sure but I
think I have forked it from eclipse release 3.0.
Comment 7 Thomas Schindl CLA 2005-02-28 05:22:03 EST
Created attachment 18353 [details]
A modified TableViewerImpl

This is a TableViewer allowing to Tab from col to  col. I'm not sure but I
think I have forked it from eclipse release 3.0.
Comment 8 sekar CLA 2005-03-01 22:02:07 EST
thanks. the tab from col to col on a single row worked. 

> i noticed the current implementation does not support tab from first row to 
the next row
> also noticed problem to set the focus back onto column editor, while 
validating the table column data

any suggestions?

(In reply to comment #7)
> Created an attachment (id=18353) [edit]
> A modified TableViewerImpl
> This is a TableViewer allowing to Tab from col to  col. I'm not sure but I
> think I have forked it from eclipse release 3.0.

Comment 9 Bhadri Madapusi CLA 2005-08-01 19:47:24 EDT
The following enhancement to tomson's code must provide row tab support, Return
traversal, escape traversal and creating a new row with default model values
when tabbed to new row.

BesoTableViewerImpl:

    public void setCellEditors(CellEditor[] editors) {
        this.cellEditors = editors;
        
        for (int i = 0; i < editors.length; i++) {
            if (editors[i].getControl() != null) {
                editors[i].getControl().addTraverseListener( new
TraverseListener() {
                    public void keyTraversed(TraverseEvent e) {
                        if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS || e.detail ==
SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_RETURN || e.detail ==
SWT.TRAVERSE_ESCAPE) {
                            e.doit = false;
                            
                            if( BesoTableViewerImpl.this.cellEditor != null ) {
                                BesoTableViewerImpl.this.cellEditor.deactivate();
                            }
                            
                            if( e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
                            	//TODO check why check box behaviour is not as expected
                            	if(columnNumber > 1){
                            		columnNumber--;                            		
                            		activateCellEditor();
                            	} else{
                            		Table table = ((BesoTableViewer) viewer).getTable();
                            		int currentRow = table.getSelectionIndex();
                            		int previousRow = --currentRow;
                            		if(previousRow > -1){
                            			table.setSelection(previousRow);
                            			tableItem = table.getItem(previousRow);
                            		
columnNumber=BesoTableViewerImpl.this.cellEditors.length-1;
                            			activateCellEditor();
                            		}                            		                  
         		
                            	}
                            } else if ( e.detail == SWT.TRAVERSE_TAB_NEXT ||
e.detail == SWT.TRAVERSE_RETURN) {
                            	if(BesoTableViewerImpl.this.cellEditors.length >
columnNumber+1){
                            		columnNumber++;
                            		activateCellEditor();
                            	} else{
                            		Table table = ((BesoTableViewer) viewer).getTable();
                            		int currentRow = table.getSelectionIndex();
                            		int nextRow = ++currentRow;
                            		if(nextRow < table.getItemCount()){
                            			table.setSelection(nextRow);
                            			tableItem = table.getItem(nextRow);
                            			columnNumber=0;
                            			activateCellEditor();
                            		} else{
                            			ViewerSorter sorter = ((BesoTableViewer)
BesoTableViewerImpl.this.viewer).getSorter();
                            			((BesoTableViewer)
BesoTableViewerImpl.this.viewer).setSorter(null);
                            			((BesoTableViewer)
BesoTableViewerImpl.this.viewer).addDefault();
                            			//refresh table
                            			table = ((BesoTableViewer)
BesoTableViewerImpl.this.viewer).getTable();
                            			table.setSelection(nextRow);
                            			tableItem = table.getItem(nextRow);
                            			columnNumber=0;
                            			activateCellEditor();      
                            		}
                            	}
                            } else if ( e.detail == SWT.TRAVERSE_ESCAPE){
                            	activateCellEditor();
                            }
                        }
                    }
                });
            }
        }
    }

BesoTableViewer changes:
    public void addDefault(){
//Assumes content provider provides a default row creation by calling
//viewer.add(Object) method
    	((ExampleContentProvider) getContentProvider()).addTask();
    }
(In reply to comment #8)
> thanks. the tab from col to col on a single row worked. 
> 
> > i noticed the current implementation does not support tab from first row to 
> the next row
> > also noticed problem to set the focus back onto column editor, while 
> validating the table column data
> 
> any suggestions?
> 
> (In reply to comment #7)
> > Created an attachment (id=18353) [edit] [edit]
> > A modified TableViewerImpl
> > This is a TableViewer allowing to Tab from col to  col. I'm not sure but I
> > think I have forked it from eclipse release 3.0.
> 
> 
Comment 10 Bhadri Madapusi CLA 2005-08-01 19:50:16 EDT
You may want to create a new ComboCellEditor as CCombo does not handle tab
traversal as expected. YOu may want to use Combo instead or try to fix CCombo
traversal issue (there is a bug opened for fixing CCombo).
Comment 11 Boris Bokowski CLA 2005-11-08 16:43:07 EST
There is overlap between this bug and bug 75557.
Comment 12 Orestis Markou CLA 2006-05-11 14:02:04 EDT
Any updates on this ?
Comment 13 Boris Bokowski CLA 2006-05-11 17:16:50 EDT
(In reply to comment #12)
> Any updates on this ?

Platform/UI did not have the resources to look at this for 3.2.  We should try to get this in for 3.3. 

I should make it clear though that if we put anything in, it should be in a form we can review easily (patch against org.eclipse.jface), and the support for keyboard navigation must be done in an opt-in way so that existing clients of TableViewer who implemented key listeners are not broken.
Comment 14 Thomas Schindl CLA 2006-05-13 12:40:10 EDT
Created attachment 41404 [details]
This is very flexible implementation to add tab support to TableViewer

This is a very flexible implementation to add tabing support to TableViewer. 
It does the following:
- added a traversal listeners to all cell-editors
- the traversal listeners uses a Delegation-class to enable the next column, row, ... this allows the user to define his selection algorithm
Comment 15 Thomas Schindl CLA 2006-05-13 14:12:39 EDT
Created attachment 41408 [details]
A more generalized version which also includes "support" for TreeViewer

This is a revised patch for the last one it is not so dependend on TableViewer and Table and has because of this the possibility to add Tab-Support even to TreeViewer (at the moment without tabing from row to row)
Comment 16 Thomas Schindl CLA 2006-05-18 18:45:26 EDT
I've now rethought the whole thing and have running version of the Viewers where the listener is only added/removed from the current element. If you are interested in a fully running example see bug #142655
Comment 17 Thomas Schindl CLA 2006-05-18 18:47:07 EDT
(In reply to comment #16)
> I've now rethought the whole thing and have running version of the Viewers
> where the listener is only added/removed from the current element. If you are
> interested in a fully running example see bug #142655
> 
Does people agree with my concept? If yes then will prepare a patch for jface?
Comment 18 Boris Bokowski CLA 2006-05-18 20:24:01 EDT
I agree that it would be good to introduce an abstraction for columns. Since bug 142655 has a broader scope, I would like to close this bug as a duplicate of the newer bug. Comments?
Comment 19 Thomas Schindl CLA 2006-05-19 06:24:31 EDT
(In reply to comment #18)
> I agree that it would be good to introduce an abstraction for columns. Since
> bug 142655 has a broader scope, I would like to close this bug as a duplicate
> of the newer bug. Comments?
> 

Agreed. This bug could be closed. The implementation provided in #142655 is even better than this one.
Comment 20 Boris Bokowski CLA 2006-05-19 07:37:14 EDT

*** This bug has been marked as a duplicate of 142655 ***