/*******************************************************************************
 * Copyright (c) 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.snippets;

/*
 * TreeCursor example snippet: navigate a Tree's cells with the arrow keys.
 * Edit when user hits Return key.  Exit edit mode by hitting Escape (cancels edit)
 * or Return (applies edit to tree).  Expand/Collapse with MOD1+Arrow keys.
 *
 * For a list of all SWT example snippets see
 * http://www.eclipse.org/swt/snippets/
 * 
 * @since 3.8
 */
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class Snippet360 {

public static void main(String[] args) {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setLayout(new GridLayout());

	// create a a tree with 3 columns and fill with data
	final Tree tree = new Tree(shell, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
	tree.setLayoutData(new GridData(GridData.FILL_BOTH));
	tree.setHeaderVisible(true);
	TreeColumn column1 = new TreeColumn(tree, SWT.NONE);
	TreeColumn column2 = new TreeColumn(tree, SWT.NONE);
	TreeColumn column3 = new TreeColumn(tree, SWT.NONE);
	for (int i = 0; i < 9; i++) {
		TreeItem item = new TreeItem(tree, SWT.NONE);
		item.setText(new String[] { "root " + i + " 0", "root " + i + " 1", "root " + i + " 2" });
		for (int j = 0; j < 9; j++) {
			TreeItem item2 = new TreeItem(item, SWT.NONE);
			item2.setText(new String[] { "child " + j + " 0", "child " + j + " 1", "child " + j + " 2" });
			TreeItem current = item2;
			for (int k = 0; k < 5; k++) {
				TreeItem item3 = new TreeItem(current, SWT.NONE);
				item3.setText(new String[] { "descendent " + k + " 0", "descendent " + k + " 1", "descendent " + k + " 2" });
				current = item3;
			}
		}
	}
	column1.setWidth(200);
	column2.setWidth(100);
	column3.setWidth(100);

	// create a TreeCursor to navigate around the tree
	final TreeCursor cursor = new TreeCursor(tree, SWT.NONE);
	// create an editor to edit the cell when the user hits "ENTER"
	// while over a cell in the tree
	final ControlEditor editor = new ControlEditor(cursor);
	editor.grabHorizontal = true;
	editor.grabVertical = true;

	cursor.addSelectionListener(new SelectionAdapter() {
		// when the TreeEditor is over a cell, select the corresponding row
		// in the tree
		@Override
		public void widgetSelected(SelectionEvent e) {
			tree.setSelection(new TreeItem[] { cursor.getRow() });
		}

		// when the user hits "ENTER" in the TreeCursor, pop up a text
		// editor so that they can change the text of the cell
		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			final Text text = new Text(cursor, SWT.NONE);
			TreeItem row = cursor.getRow();
			int column = cursor.getColumn();
			text.setText(row.getText(column));
			text.addKeyListener(new KeyAdapter() {
				@Override
				public void keyPressed(KeyEvent e) {
					// close the text editor and copy the data over
					// when the user hits "ENTER"
					if (e.character == SWT.CR) {
						TreeItem row = cursor.getRow();
						int column = cursor.getColumn();
						row.setText(column, text.getText());
						text.dispose();
					}
					// close the text editor when the user hits "ESC"
					if (e.character == SWT.ESC) {
						text.dispose();
					}
				}
			});
			editor.setEditor(text);
			text.setFocus();
		}
	});
	// Hide the TreeCursor when the user hits the "MOD1" or "MOD2" key.
	// This allows the user to select multiple items in the tree.
	cursor.addKeyListener(new KeyAdapter() {
		@Override
		public void keyPressed(KeyEvent e) {
			if (e.keyCode == SWT.MOD1 || e.keyCode == SWT.MOD2
					|| (e.stateMask & SWT.MOD1) != 0
					|| (e.stateMask & SWT.MOD2) != 0) {
				cursor.setVisible(false);
			}
		}
	});
	// Show the TreeCursor when the user releases the "MOD2" or "MOD1" key.
	// This signals the end of the multiple selection task.
	tree.addKeyListener(new KeyListener() {
		@Override
		public void keyReleased(KeyEvent e) {
			if (e.keyCode == SWT.MOD1 && (e.stateMask & SWT.MOD2) != 0) return;
			if (e.keyCode == SWT.MOD2 && (e.stateMask & SWT.MOD1) != 0) return;
			if (e.keyCode != SWT.MOD1 && (e.stateMask & SWT.MOD1) != 0) return;
			if (e.keyCode != SWT.MOD2 && (e.stateMask & SWT.MOD2) != 0) return;

			TreeItem[] selection = tree.getSelection();
			TreeItem row = (selection.length == 0) ? tree.getItem(tree.indexOf(tree.getTopItem())) : selection[0];
			tree.showItem(row);
			cursor.setSelection(row, cursor.getColumn());
			cursor.setVisible(true);
			cursor.setFocus();
		}
		@Override
		public void keyPressed(KeyEvent e) {
			switch (e.keyCode) {
				case SWT.ARROW_LEFT:
				case SWT.ARROW_RIGHT: {
					if ((e.stateMask & SWT.MOD1) != 0) {
						TreeItem[] selection = tree.getSelection();
						if (selection.length > 0) {
							selection[0].setExpanded(e.keyCode == SWT.ARROW_RIGHT);
						}
						break;
					}
				}
			}
		}
	});

	shell.pack();
	shell.open();
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch())
			display.sleep();
	}
	display.dispose();
}

}
