提交 7c73f2bf 编写于 作者: J jurgen

Tree manager

上级 d112c753
......@@ -149,7 +149,7 @@ public class DatabaseSearchDialog extends HelpEnabledDialog implements IObjectSe
// Buttons
searchButton = createButton(parent, SEARCH_ID, "Search", true);
searchButton.setEnabled(searchEnabled);
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CLOSE_LABEL, false);
}
@Override
......
......@@ -246,25 +246,27 @@ public class DBNModel implements IResourceChangeListener {
String item = items.get(i);
List<? extends DBNNode> children = curNode.getChildren(monitor);
DBNNode nextChild = null;
for (DBNNode child : children) {
if (child instanceof DBNDatabaseFolder) {
DBXTreeFolder meta = ((DBNDatabaseFolder) child).getMeta();
if (meta != null && !CommonUtils.isEmpty(meta.getType()) && meta.getType().equals(item)) {
if (children != null && !children.isEmpty()) {
for (DBNNode child : children) {
if (child instanceof DBNDatabaseFolder) {
DBXTreeFolder meta = ((DBNDatabaseFolder) child).getMeta();
if (meta != null && !CommonUtils.isEmpty(meta.getType()) && meta.getType().equals(item)) {
nextChild = child;
}
}
if (child.getNodeName().equals(item)) {
nextChild = child;
}
}
if (child.getNodeName().equals(item)) {
nextChild = child;
}
if (nextChild != null) {
if (i < itemsSize - 1) {
nextChild = findNodeByPath(monitor, items, nextChild, i + 1);
if (nextChild != null) {
return nextChild;
if (nextChild != null) {
if (i < itemsSize - 1) {
nextChild = findNodeByPath(monitor, items, nextChild, i + 1);
if (nextChild != null) {
return nextChild;
}
continue;
}
continue;
break;
}
break;
}
}
curNode = nextChild;
......
......@@ -215,8 +215,8 @@ public class SearchDataPage extends AbstractSearchPage {
if (!checkedNodes.isEmpty()) {
for (DBNNode node : checkedNodes) {
((CheckboxTreeViewer)dataSourceTree.getViewer()).setChecked(node, true);
checkboxTreeManager.checkStateChanged(new CheckStateChangedEvent((CheckboxTreeViewer)dataSourceTree.getViewer(), node, true));
}
checkboxTreeManager.updateCheckStates();
}
updateEnablement();
}
......
......@@ -21,77 +21,123 @@ package org.jkiss.dbeaver.ui.views.navigator.database;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ViewerFilter;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.core.DBeaverUI;
import org.jkiss.dbeaver.model.navigator.DBNDataSource;
import org.jkiss.dbeaver.model.navigator.DBNDatabaseNode;
import org.jkiss.dbeaver.model.navigator.DBNNode;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress;
import org.jkiss.dbeaver.runtime.VoidProgressMonitor;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
public class CheckboxTreeManager implements ICheckStateListener {
private final CheckboxTreeViewer viewer;
private final Class<?>[] targetTypes;
private Object[] checkedElements;
private final ViewerFilter[] filters;
public CheckboxTreeManager(CheckboxTreeViewer viewer, Class<?>[] targetTypes) {
this.viewer = viewer;
this.targetTypes = targetTypes;
this.filters = viewer.getFilters();
}
@Override
public void checkStateChanged(CheckStateChangedEvent event) {
try {
VoidProgressMonitor monitor = VoidProgressMonitor.INSTANCE;
Object element = event.getElement();
boolean checked = event.getChecked();
public void checkStateChanged(final CheckStateChangedEvent event) {
updateElementsCheck(
new Object[] {event.getElement()},
event.getChecked(),
true);
}
updateElementHierarchy(monitor, element, checked, true);
private void updateElementsCheck(final Object[] elements, final boolean checked, final boolean change) {
checkedElements = viewer.getCheckedElements();
try {
DBeaverUI.runInProgressService(new DBRRunnableWithProgress() {
@Override
public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
monitor.beginTask("Load sources tree", 100 * elements.length);
try {
for (Object element : elements) {
updateElementHierarchy(monitor, element, checked, change);
if (element instanceof DBNDatabaseNode) {
for (DBNNode node = ((DBNDatabaseNode)element).getParentNode(); node != null; node = node.getParentNode()) {
if (node instanceof DBNDatabaseNode) {
updateElementHierarchy(monitor, node, checked, false);
}
if (node instanceof DBNDataSource) {
break;
if (change) {
// Update parent state
if (element instanceof DBNDatabaseNode) {
for (DBNNode node = ((DBNDatabaseNode) element).getParentNode(); node != null; node = node.getParentNode()) {
if (node instanceof DBNDatabaseNode) {
updateElementHierarchy(monitor, node, checked, false);
}
if (node instanceof DBNDataSource) {
break;
}
}
}
}
}
} catch (DBException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
}
} catch (DBException e) {
UIUtils.showErrorDialog(viewer.getControl().getShell(), "Error", "Can't collect child nodes", e);
});
} catch (InvocationTargetException e) {
UIUtils.showErrorDialog(viewer.getControl().getShell(), "Error", "Can't collect child nodes", e.getTargetException());
} catch (InterruptedException e) {
// ignore
}
}
private void updateElementHierarchy(VoidProgressMonitor monitor, Object element, boolean checked, boolean change) throws DBException {
List<DBNDatabaseNode> targetChildren = new ArrayList<DBNDatabaseNode>();
List<DBNDatabaseNode> targetContainers = new ArrayList<DBNDatabaseNode>();
private void updateElementHierarchy(final DBRProgressMonitor monitor, final Object element, final boolean checked, final boolean change) throws DBException {
final List<DBNDatabaseNode> targetChildren = new ArrayList<DBNDatabaseNode>();
final List<DBNDatabaseNode> targetContainers = new ArrayList<DBNDatabaseNode>();
collectChildren(monitor, element, targetChildren, targetContainers, !change);
if (change) {
for (DBNDatabaseNode child : targetChildren) {
viewer.setChecked(child, checked);
}
}
for (DBNDatabaseNode container : change ? targetContainers : Collections.singletonList((DBNDatabaseNode) element)) {
List<DBNDatabaseNode> directChildren = CommonUtils.safeList(container.getChildren(monitor));
boolean missing = Collections.disjoint(directChildren, targetChildren);
viewer.setChecked(container, change ? checked : !missing || !Collections.disjoint(directChildren, targetContainers));
viewer.setGrayed(container, missing);
}
// Run ui
viewer.getControl().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
if (change) {
for (DBNDatabaseNode child : targetChildren) {
viewer.setChecked(child, checked);
}
}
for (DBNDatabaseNode container : change ? targetContainers : Collections.singletonList((DBNDatabaseNode) element)) {
try {
List<DBNDatabaseNode> directChildren = CommonUtils.safeList(container.getChildren(VoidProgressMonitor.INSTANCE));
boolean missing = Collections.disjoint(directChildren, targetChildren);
viewer.setChecked(container, change ? checked : !missing || !Collections.disjoint(directChildren, targetContainers));
viewer.setGrayed(container, missing);
} catch (DBException e) {
// shouldn't be here
}
}
}
});
}
private boolean collectChildren(DBRProgressMonitor monitor, final Object element, List<DBNDatabaseNode> targetChildren, List<DBNDatabaseNode> targetContainers, boolean onlyChecked) throws DBException {
if (element instanceof DBNDatabaseNode) {
for (ViewerFilter filter : filters) {
if (!filter.select(viewer, ((DBNDatabaseNode) element).getParentNode(), element)) {
return false;
}
}
boolean isChecked = ArrayUtils.contains(checkedElements, element);
for (Class<?> type : targetTypes) {
if (type.isInstance(((DBNDatabaseNode) element).getObject())) {
if (!onlyChecked || viewer.getChecked(element)) {
if (!onlyChecked || isChecked) {
targetChildren.add((DBNDatabaseNode) element);
}
return true;
......@@ -107,7 +153,7 @@ public class CheckboxTreeManager implements ICheckStateListener {
}
}
if (foundChild) {
if (!onlyChecked || viewer.getChecked(element)) {
if (!onlyChecked || isChecked) {
targetContainers.add((DBNDatabaseNode) element);
}
}
......@@ -117,5 +163,16 @@ public class CheckboxTreeManager implements ICheckStateListener {
return false;
}
public void updateCheckStates() {
Set<DBNDatabaseNode> parentList = new LinkedHashSet<DBNDatabaseNode>();
for (Object element : viewer.getCheckedElements()) {
for (DBNNode node = ((DBNDatabaseNode)element).getParentNode(); node != null; node = node.getParentNode()) {
if (node instanceof DBNDatabaseNode) {
parentList.add((DBNDatabaseNode) node);
viewer.setChecked(node, true);
}
}
}
updateElementsCheck(parentList.toArray(), true, false);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册