Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » TreeViewers, Editing support and multiple Selection
TreeViewers, Editing support and multiple Selection [message #647247] Wed, 05 January 2011 11:05 Go to next message
Alex Lagarde is currently offline Alex Lagarde
Messages: 185
Registered: May 2010
Senior Member

Hy everyone !

I have defined a Tree Editor, that allows multiple selection.
When I try to install an editing support on the ViewerColumn associated to this tree :
ViewerColumn treeColumn = treeViewer.getViewerColumn(0);
treeColumn.setEditingSupport(myTreeEditingSupport)


It breaks the multiple selection (I can still select multiple TreeItems, but there is a lot of graphical bugs, and I cannot always see the TreeItems I have selected).

According to this post :
http://forums.dzone.com/eclipse/1463-multi-row-selection-tab leviewer-editing-support.html

it is impossible to set an Editing Support and keep mutliple selections capabilities.

I wondered if anyone had encountered this issue, and has a work around or a good solution to give.

Thanks by advance,
Alex
Re: TreeViewers, Editing support and multiple Selection [message #647355 is a reply to message #647247] Wed, 05 January 2011 18:30 Go to previous messageGo to next message
No real name is currently offline No real name
Messages: 8
Registered: January 2011
Junior Member
Hi,

I'm doing something quite different.
First I don't use TreeViewer (don't ask me why : ), but directly a Tree.

Second, I don't put Text fields in the TreeEditor to edit text, but I use TreeEditor, and put Button and CCombo inside. And I don't create them when user click on tree item, there created at tree item initialization.

Anyway, I suppose TreeViewer use TreeEditor and Text to perform editing, as this the way to do that thing.

I had some bug to fix, one of them was related to item selection like you.

I had to put some listener on my Button and the tree, this one :


button.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent dummy) {
			}
			public void widgetSelected(SelectionEvent event) {
			// have to manually select the underlining treeItem
				tree.forceFocus(); // on window, item will be grayed instead of blue without this
				if(mouseOnCheckBox[0]) {
					// I deals with check box buttons, in my case user clicked just on the box, not on the text of the button
					// so don't want to select the item, just do the action
					doSomething();
					return;
				}
				// user clicked on icon or text
				button.setSelection(!button.getSelection()); // ugly hack thing I have to do with my stupid check buttons
				// now I have to select the item, to be better, I have to handle CTRL or SHIFT key
				if((event.stateMask & SWT.SHIFT) == 0) {
					if((event.stateMask & SWT.MOD1) == 0)
						tree.deselectAll();	// user have no special key pressed
				} else if(tree.getSelection().length > 0) { // shift key : select items between last selection and current
					TreeItem treeItems[] = tree.getSelection();
					// It is a bug : I don't know how to retrieve the last selected item, I take the last in the list but it's wrong.
					TreeItem lastSelectedItem = treeItems[treeItems.length-1];
					// all my tree item got there data field set to an object, that allows to retrieve her index
					// I have to use virtual tree since TreeEditor and Button or CCombo create too much kernel object...
					if(getAbstractItem(lastSelectedItem) != null) {
						int index = getAbstractItem(lastSelectedItem).getIndex();
						int index2 = getAbstractItem(treeItem).getIndex();
						if(index > index2) {
							int swap = index;
							index = index2; index2 = swap;
						}
					// in fact, I just retrieve the range of item to select, when user have Shift key pressed
						for(; index <= index2; index++)
							tree.select(tree.getItem(index));
						return;
					}
				}
				if((event.stateMask & SWT.MOD1) != 0 && isSelected(treeItem)) // user clicked on ctrl or the item was already selected
					tree.deselect(treeItem);
				else
					tree.select(treeItem);
			}
		});





that's for the selection when user click on your Text field.

As you can see, that's bad because I "recreate the wheel", and badder...

Now, we have to make the Text background follow the tree item background (white, blue or gray).
Here I use a simple tree listener :

		// listener that set buttons background and foreground like tree items
		tree.addListener(SWT.EraseItem, new Listener() {
			public void handleEvent(Event event) {
				if(event.index != 0)
					return;
				// retrieve the button associated whith the tree item
				Button button = getButton(getAbstractItem((TreeItem)event.item));
				if(button != null && !button.isDisposed()) {
					button.setForeground(event.gc.getForeground());
					button.setBackground(event.gc.getBackground());
				}
			}
		});



There's still a bug under window : font color (getForeground()) don't follow. It stay black while it should goes white...

May be you can adapt this kind of work around to your treeViewer

[Updated on: Wed, 05 January 2011 19:58]

Report message to a moderator

Re: TreeViewers, Editing support and multiple Selection [message #647429 is a reply to message #647355] Thu, 06 January 2011 09:55 Go to previous message
Alex Lagarde is currently offline Alex Lagarde
Messages: 185
Registered: May 2010
Senior Member

Thanks a lot for your fast reply.

I have found a solution very similar to yours :

1. I define a Listener with the following handleEvent method :
 public void handleEvent(final Event event) {

        event.detail &= ~SWT.HOT;
        if ((event.detail & SWT.SELECTED) == 0)
            return; /* item not selected */
        final int clientWidth = treeViewer.getTree().getClientArea().width;
        final GC gc = event.gc;
        final Color oldBackground = gc.getBackground();
        if (DTableEraseItemListener.IS_WINDOWS_OS) {
            if (event.index == tableViewerManager.getActiveColumn()) {
                // Make some tests to correct the the Windows problem.
                if (lastSelectedLineDrawned != null && lastSelectedColumnDrawned != -1 && !lastSelectedLineDrawned.equals(event.item)
                        && lastSelectedColumnDrawned == tableViewerManager.getActiveColumn()) {
                    gc.setBackground(DTableEraseItemListener.COLOR_LIST_OTHER_CELLS_SELECTED);
                } else {
                    // Draw the background of the selected cell to another color
                    gc.setBackground(DTableEraseItemListener.COLOR_LIST_SELECTED);
                }
                lastSelectedLineDrawned = event.item;
                lastSelectedColumnDrawned = tableViewerManager.getActiveColumn();
            } else {
                // Draw the background to selected for the other cells of the
                // line of the selected cell
                gc.setBackground(DTableEraseItemListener.COLOR_LIST_OTHER_CELLS_SELECTED);
            }
            gc.fillRectangle(event.x, event.y, event.width, event.height);
        } else {
            if (tableViewerManager.getActiveColumn() == 0) {
                // Draw the background to selected for all the cells of the line
                gc.setBackground(DTableEraseItemListener.COLOR_LIST_SELECTED);
                gc.fillRectangle(0, event.y, clientWidth, event.height);
            } else if (event.index == tableViewerManager.getActiveColumn()) {
                // Draw the background of the selected cell to another color
                gc.setBackground(DTableEraseItemListener.COLOR_LIST_SELECTED);
                gc.fillRectangle(event.x, event.y, event.width, event.height);
            } else {
                // Draw the background to selected for the other cells of the
                // line of the selected cell
                gc.setBackground(DTableEraseItemListener.COLOR_LIST_OTHER_CELLS_SELECTED);
                gc.fillRectangle(event.x, event.y, event.width, event.height);
            }
        }
        // Reset to previous background
        gc.setBackground(oldBackground);
        event.detail &= ~SWT.SELECTED;
    }


2. I add this listener to my TreeViewer
treeViewer.getTree().addListener(SWT.EraseItem, myListener);


Everything then works fine !

Thanks again, hope this post will help Smile
Alex
Previous Topic:Mouse wheel scrolling under Windows
Next Topic:A custom copy/paste operation
Goto Forum:
  


Current Time: Tue Sep 16 23:48:51 GMT 2014

Powered by FUDForum. Page generated in 0.08188 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software