blob: 3350a06144b17f8c98f503866657ebead91a1f33 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 Exyte
* 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:
* Yuri Strot - initial API and Implementation
******************************************************************************/
package org.eclipse.ui.glance.controls.tree;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.glance.sources.ConfigurationManager;
public class TreeControlContent extends TreeContent {
private Tree tree;
private final Map<TreeCell, TreeItemContent> cellToContent = new HashMap<TreeCell, TreeItemContent>();
public TreeControlContent(Tree tree) {
this.tree = tree;
collectCells(this, tree.getItems());
}
@Override
public void dispose() {
tree = null;
}
@Override
public TreeItemContent getContent(TreeCell cell) {
TreeItemContent content = cellToContent.get(cell);
if (content == null) {
TreeItem parent = null;
do {
parent = cell.getTreeItem().getParentItem();
if (parent == null) {
break;
}
TreeCell parentCell = new TreeCell(parent, 0);
cell = parentCell;
content = cellToContent.get(parentCell);
} while (content == null);
if (content != null && parent != null) {
collectCells(content.getNode(), parent.getItems());
content = cellToContent.get(cell);
}
}
return content;
}
@Override
public void index(final IProgressMonitor monitor) {
if (tree == null || tree.isDisposed()) {
monitor.done();
return;
}
tree.getDisplay().asyncExec(new Runnable() {
public void run() {
try {
if (tree == null || tree.isDisposed()) {
return;
}
final LinkedList<TreeItem> items = new LinkedList<TreeItem>();
for (TreeItem item : tree.getItems()) {
items.add(item);
}
if (items.size() > 0) {
expand(items, monitor);
}
} finally {
monitor.done();
}
}
});
}
private void expand(final LinkedList<TreeItem> items,
final IProgressMonitor monitor) {
if (tree == null || tree.isDisposed())
return;
final Display display = tree.getDisplay();
BusyIndicatorUtils.withoutIndicator(display, new Runnable() {
public void run() {
int maxIndexingDepth = ConfigurationManager.getInstance()
.getMaxIndexingDepth();
int level = 1;
TreeItem lastInLevel = items.getLast();
monitor.beginTask("1/" + maxIndexingDepth, items.size());
while (true) {
if (tree == null
|| tree.isDisposed()
|| (maxIndexingDepth >= 0 && level >= maxIndexingDepth))
return;
if (monitor.isCanceled())
return;
TreeItem item = items.poll();
if (item == null)
return;
try {
if (item.isDisposed())
continue;
if (!item.getExpanded()) {
Event event = new Event();
event.item = item;
event.type = SWT.Expand;
event.widget = item.getParent();
event.display = display;
event.widget.notifyListeners(SWT.Expand, event);
}
TreeItem[] kids = item.getItems();
TreeItemContent content = getContent(item);
if (content != null) {
collectCells(content.getNode(), item.getItems());
}
for (TreeItem child : kids) {
items.addLast(child);
}
while (display.readAndDispatch())
;
} finally {
monitor.worked(1);
if (item == lastInLevel && items.size() > 0) {
lastInLevel = items.getLast();
level++;
int total = items.size();
monitor.beginTask(level + "/?", total);
}
}
}
}
});
}
private void collectCells(TreeNode node, TreeItem[] items) {
if (items.length > 0) {
int columns = items[0].getParent().getColumnCount();
if (columns == 0) {
columns = 1;
}
List<TreeNode> nodes = new ArrayList<TreeNode>(items.length);
for (int i = 0; i < items.length; i++) {
TreeItem item = items[i];
TreeItemContent c = getContent(item);
if (c != null) {
continue;
}
TreeNode child = new TreeNode(item);
for (int j = 0; j < columns; j++) {
TreeCell cell = new TreeCell(item, j);
TreeItemContent itemContent = new TreeItemContent(child,
item.getText(j), j);
cellToContent.put(cell, itemContent);
}
if (item.getExpanded()) {
collectCells(child, item.getItems());
}
nodes.add(child);
}
if (nodes.size() > 0) {
node.add(nodes.toArray(new TreeNode[nodes.size()]));
}
}
}
private TreeItemContent getContent(TreeItem item) {
return cellToContent.get(new TreeCell(item, 0));
}
}