blob: 9cb0e56c4f4f0d7f31606661016d5f72b959db30 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.help.ui.internal.search;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.help.internal.HelpPlugin;
import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.criteria.CriterionResource;
import org.eclipse.help.internal.workingset.AdaptableHelpResource;
import org.eclipse.help.internal.workingset.WorkingSet;
import org.eclipse.help.ui.IEngineDescriptor;
import org.eclipse.help.ui.RootScopePage;
import org.eclipse.help.ui.internal.Messages;
import org.eclipse.help.ui.internal.search.HelpCriteriaContentProvider.CriterionName;
import org.eclipse.help.ui.internal.search.HelpCriteriaContentProvider.CriterionValue;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
/**
* Local Help participant in the federated search.
*/
public class LocalHelpPage extends RootScopePage {
private Button searchAll;
private Button searchSelected;
private CheckboxTreeViewer contentTree;
private ITreeContentProvider contentTreeContentProvider;
private ILabelProvider contentTreeLabelProvider;
private CheckboxTreeViewer criteriaTree;
private ITreeContentProvider criteriaTreeContentProvider;
private ILabelProvider criteriaTreeLabelProvider;
//private boolean firstCheck;
private WorkingSet workingSet;
@Override
public void init(IEngineDescriptor ed, String scopeSetName) {
super.init(ed, scopeSetName);
if (scopeSetName != null)
workingSet = BaseHelpSystem.getWorkingSetManager().getWorkingSet(
scopeSetName);
}
/**
* Default constructor.
*/
public LocalHelpPage() {
//firstCheck = true;
}
@Override
protected int createScopeContents(Composite parent) {
Font font = parent.getFont();
initializeDialogUnits(parent);
searchAll = new Button(parent, SWT.RADIO);
searchAll.setText(Messages.selectAll);
GridData gd = new GridData();
gd.horizontalSpan = 2;
searchAll.setLayoutData(gd);
searchAll.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
contentTree.getTree().setEnabled(false);
if (criteriaTree != null) {
criteriaTree.getTree().setEnabled(false);
}
}
});
searchSelected = new Button(parent, SWT.RADIO);
searchSelected.setText(Messages.selectWorkingSet);
gd = new GridData();
gd.horizontalSpan = 2;
searchSelected.setLayoutData(gd);
searchSelected.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
contentTree.getTree().setEnabled(true);
if (criteriaTree != null) {
criteriaTree.getTree().setEnabled(true);
}
}
});
if (workingSet == null)
searchAll.setSelection(true);
else
searchSelected.setSelection(true);
Label contentLabel = new Label(parent, SWT.WRAP);
contentLabel.setFont(font);
contentLabel.setText(Messages.WorkingSetContent);
gd = new GridData(GridData.GRAB_HORIZONTAL
| GridData.HORIZONTAL_ALIGN_FILL
| GridData.VERTICAL_ALIGN_CENTER);
gd.horizontalSpan = 2;
contentLabel.setLayoutData(gd);
createContentTree(parent, font);
if (HelpPlugin.getCriteriaManager().isCriteriaEnabled()) {
Label criteriaLabel = new Label(parent, SWT.WRAP);
criteriaLabel.setFont(font);
criteriaLabel.setText(Messages.WorkingSetCriteria);
gd = new GridData(GridData.GRAB_HORIZONTAL
| GridData.HORIZONTAL_ALIGN_FILL
| GridData.VERTICAL_ALIGN_CENTER);
gd.horizontalSpan = 2;
criteriaLabel.setLayoutData(gd);
createCriteriaTree(parent, font);
}
initializeCheckedState();
applyDialogFont(parent);
// Set help for the page
// WorkbenchHelp.setHelp(tree, "help_workingset_page");
return 1;
}
protected void createContentTree(Composite parent, Font font) {
GridData gd;
contentTree = new CheckboxTreeViewer(parent, SWT.BORDER | SWT.H_SCROLL
| SWT.V_SCROLL);
gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL);
gd.heightHint = getTreeHeightHint();
gd.horizontalSpan = 2;
contentTree.getControl().setLayoutData(gd);
contentTree.getControl().setFont(font);
contentTreeContentProvider = new HelpWorkingSetTreeContentProvider();
contentTree.setContentProvider(contentTreeContentProvider);
contentTreeLabelProvider = new HelpWorkingSetElementLabelProvider();
contentTree.setLabelProvider(contentTreeLabelProvider);
contentTree.setUseHashlookup(true);
contentTree.setInput(BaseHelpSystem.getWorkingSetManager().getRoot());
contentTree.addCheckStateListener(
event -> handleCheckStateChange(event, contentTree, contentTreeContentProvider));
contentTree.addTreeListener(new ITreeViewerListener() {
@Override
public void treeCollapsed(TreeExpansionEvent event) {
}
@Override
public void treeExpanded(TreeExpansionEvent event) {
final Object element = event.getElement();
if (contentTree.getGrayed(element) == false)
BusyIndicator.showWhile(getShell().getDisplay(),
() -> setSubtreeChecked(element, contentTree.getChecked(element), false,
contentTree, contentTreeContentProvider));
}
});
contentTree.getTree().setEnabled(workingSet != null);
}
protected int getTreeHeightHint() {
if (HelpPlugin.getCriteriaManager().isCriteriaEnabled()) {
return convertHeightInCharsToPixels(8);
}
return convertHeightInCharsToPixels(15);
}
protected void createCriteriaTree(Composite parent, Font font) {
GridData gd;
criteriaTree = new CheckboxTreeViewer(parent, SWT.BORDER | SWT.H_SCROLL
| SWT.V_SCROLL);
gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL);
gd.heightHint = getTreeHeightHint();
gd.horizontalSpan = 2;
criteriaTree.getControl().setLayoutData(gd);
criteriaTree.getControl().setFont(font);
criteriaTreeContentProvider = new HelpCriteriaContentProvider();
criteriaTree.setContentProvider(criteriaTreeContentProvider);
criteriaTreeLabelProvider = new HelpCriteriaLabelProvider();
criteriaTree.setLabelProvider(criteriaTreeLabelProvider);
criteriaTree.setUseHashlookup(true);
criteriaTree.setInput(BaseHelpSystem.getWorkingSetManager().getCriterionIds());
criteriaTree.addCheckStateListener(
event -> handleCheckStateChange(event, criteriaTree, criteriaTreeContentProvider));
criteriaTree.addTreeListener(new ITreeViewerListener() {
@Override
public void treeCollapsed(TreeExpansionEvent event) {
}
@Override
public void treeExpanded(TreeExpansionEvent event) {
final Object element = event.getElement();
if (criteriaTree.getGrayed(element) == false)
BusyIndicator.showWhile(getShell().getDisplay(),
() -> setSubtreeChecked(element, criteriaTree.getChecked(element), false,
criteriaTree, criteriaTreeContentProvider));
}
});
criteriaTree.getTree().setEnabled(workingSet != null);
}
private void initializeCheckedState() {
if (workingSet == null)
return;
BusyIndicator.showWhile(getShell().getDisplay(), () -> {
initializeContentTree();
if (HelpPlugin.getCriteriaManager().isCriteriaEnabled()) {
initializeCriteriaTree();
}
});
}
boolean isExpandable(Object element, ITreeContentProvider contentProvider) {
return contentProvider.hasChildren(element);
}
void updateParentState(Object child, boolean baseChildState,
CheckboxTreeViewer tree, ITreeContentProvider contentProvider) {
if (child == null)
return;
Object parent = contentProvider.getParent(child);
if (parent == null)
return;
boolean allSameState = true;
Object[] children = null;
children = contentProvider.getChildren(parent);
for (int i = children.length - 1; i >= 0; i--) {
if (tree.getChecked(children[i]) != baseChildState
|| tree.getGrayed(children[i])) {
allSameState = false;
break;
}
}
tree.setGrayed(parent, !allSameState);
tree.setChecked(parent, !allSameState || baseChildState);
updateParentState(parent, baseChildState, tree, contentProvider);
}
void setSubtreeChecked(Object parent, boolean state,
boolean checkExpandedState,
CheckboxTreeViewer tree, ITreeContentProvider contentProvider) {
Object[] children = contentProvider.getChildren(parent);
for (int i = children.length - 1; i >= 0; i--) {
Object element = children[i];
if (state) {
tree.setChecked(element, true);
tree.setGrayed(element, false);
} else
tree.setGrayChecked(element, false);
if (isExpandable(element, contentProvider))
setSubtreeChecked(element, state, checkExpandedState, tree, contentProvider);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void findCheckedElements(java.util.List checkedResources, Object parent,
CheckboxTreeViewer tree, ITreeContentProvider contentProvider) {
Object[] children = contentProvider.getChildren(parent);
for (int i = 0; i < children.length; i++) {
if (tree.getGrayed(children[i]))
findCheckedElements(checkedResources, children[i], tree, contentProvider);
else if (tree.getChecked(children[i]))
checkedResources.add(children[i]);
}
}
private CriterionResource[] findCheckedCriteria(Object parent,
CheckboxTreeViewer tree, ITreeContentProvider contentProvider) {
Object[] children = contentProvider.getChildren(parent);
List<CriterionResource> resources = new ArrayList<>();
for (int i = 0; i < children.length; i++) {
// First level children are names
CriterionName name = (CriterionName) children[i];
CriterionResource resource = new CriterionResource(name.getId());
Object[] grandChildren = contentProvider.getChildren(name);
for (int j = 0; j < grandChildren.length; j++) {
if (tree.getChecked(grandChildren[j])) {
CriterionValue value = (CriterionValue) grandChildren[j];
resource.addCriterionValue(value.getId());
}
}
if (resource.getCriterionValues().size() > 0) {
resources.add(resource);
}
}
return resources.toArray(new CriterionResource[resources.size()]);
}
void handleCheckStateChange(final CheckStateChangedEvent event,
final CheckboxTreeViewer tree, final ITreeContentProvider contentProvider) {
BusyIndicator.showWhile(getShell().getDisplay(), () -> {
Object element = event.getElement();
boolean state = event.getChecked();
tree.setGrayed(element, false);
if (isExpandable(element, contentProvider))
setSubtreeChecked(element, state, state, tree, contentProvider);
// only check subtree if state is set to true
updateParentState(element, state, tree, contentProvider);
// validateInput();
});
}
public WorkingSet getWorkingSet() {
ArrayList<AdaptableHelpResource> elements = new ArrayList<>(10);
CriterionResource[] criteria;
if (!HelpPlugin.getCriteriaManager().isCriteriaEnabled()) {
criteria = new CriterionResource[0];
} else {
criteria = findCheckedCriteria(
criteriaTree.getInput(),
criteriaTree,
criteriaTreeContentProvider);
}
findCheckedElements(elements, contentTree.getInput(), contentTree, contentTreeContentProvider);
if (workingSet == null) {
workingSet = new WorkingSet(
getScopeSetName(),
elements.toArray(new AdaptableHelpResource[elements.size()]), criteria);
} else {
workingSet.setName(getScopeSetName());
workingSet.setElements(elements.toArray(new AdaptableHelpResource[elements.size()]));
workingSet.setCriteria(criteria);
}
return workingSet;
}
@Override
public boolean performOk() {
if (searchSelected.getSelection())
BaseHelpSystem.getWorkingSetManager()
.addWorkingSet(getWorkingSet());
else
BaseHelpSystem.getWorkingSetManager().removeWorkingSet(
getWorkingSet());
getPreferenceStore().setValue(
getKey(LocalSearchScopeFactory.P_WORKING_SET),
getScopeSetName());
getPreferenceStore().setValue(
getKey(LocalSearchScopeFactory.P_CAPABILITY_FILTERING),
false);
return super.performOk();
}
private String getKey(String key) {
return getEngineDescriptor().getId() + "." + key; //$NON-NLS-1$
}
protected void initializeContentTree() {
Object[] elements = workingSet.getElements();
contentTree.setCheckedElements(elements);
for (int i = 0; i < elements.length; i++) {
Object element = elements[i];
if (isExpandable(element, contentTreeContentProvider))
setSubtreeChecked(element, true, true, contentTree, contentTreeContentProvider);
updateParentState(element, true, contentTree, contentTreeContentProvider);
}
}
protected void initializeCriteriaTree() {
CriterionResource[] criteria = workingSet.getCriteria();
criteriaTree.setCheckedElements(criteria);
for (int i = 0; i < criteria.length; i++) {
CriterionResource element = criteria[i];
CriterionName name = new CriterionName(element.getCriterionName(), null);
List<String> values = element.getCriterionValues();
for (Iterator<String> iter = values.iterator(); iter.hasNext();) {
String valueString = iter.next();
CriterionValue value = new CriterionValue(valueString, name);
criteriaTree.setChecked(value, true);
updateParentState(value, true, criteriaTree, criteriaTreeContentProvider);
}
}
}
@Override
protected void performDefaults() {
searchAll.setSelection(true);
searchSelected.setSelection(false);
contentTree.setCheckedElements(new Object[0]);
if (criteriaTree != null) {
criteriaTree.setCheckedElements(new Object[0]);
}
super.performDefaults();
}
@Override
protected Label createDescriptionLabel(Composite parent) {
if ( getContainer() == null ) {
return null;
}
return super.createDescriptionLabel(parent);
}
}