blob: b800081c29cc1acac3325e8ae708c56972db538e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 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.help.ui.internal.views;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.help.ui.internal.HelpUIResources;
import org.eclipse.help.ui.internal.IHelpUIConstants;
import org.eclipse.help.ui.internal.Messages;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.preference.PreferenceManager;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.PlatformUI;
/**
* Scope dialog for federated search.
*/
public class ScopeSetDialog extends TrayDialog {
public class NonDefaultFilter extends ViewerFilter {
@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (element instanceof ScopeSet && ((ScopeSet)element).isDefault()) {
return false;
}
return true;
}
}
public class ShowAllListener extends SelectionAdapter {
@Override
public void widgetSelected(SelectionEvent e) {
enableTable();
}
}
private ScopeSetManager manager;
private EngineDescriptorManager descManager;
private static final int NEW_ID = IDialogConstants.CLIENT_ID + 1;
private static final int EDIT_ID = IDialogConstants.CLIENT_ID + 2;
private static final int RENAME_ID = IDialogConstants.CLIENT_ID +3;
private static final int REMOVE_ID = IDialogConstants.CLIENT_ID + 4;
private Button editButton;
private Button renameButton;
private Button removeButton;
private ArrayList<ScopeSet> sets;
private ArrayList<PendingOperation> operations;
private IStructuredContentProvider contentProvider;
private Button showAllRadio;
private Button showSelectedRadio;
private ILabelProvider labelProvider;
private Object input;
private TableViewer viewer;
private int widthInChars = 55;
private int heightInChars = 15;
private ScopeSet initialSelection;
private Object[] result;
private boolean localOnly;
private abstract class PendingOperation {
ScopeSet set;
public PendingOperation(ScopeSet set) {
this.set = set;
}
public abstract void commit();
public abstract void cancel();
}
private class AddOperation extends PendingOperation {
public AddOperation(ScopeSet set) {
super(set);
}
@Override
public void commit() {
manager.add(set);
}
@Override
public void cancel() {
set.dispose();
}
}
private class RenameOperation extends PendingOperation {
private String newName;
public RenameOperation(ScopeSet set, String newName) {
super(set);
this.newName = newName;
}
@Override
public void commit() {
this.set.setName(newName);
}
@Override
public void cancel() {
}
}
/*
private class EditOperation extends PendingOperation {
public EditOperation(ScopeSet set) {
super(set);
}
public void commit() {
}
public void cancel() {
}
}
*/
private class RemoveOperation extends PendingOperation {
public RemoveOperation(ScopeSet set) {
super(set);
}
@Override
public void commit() {
manager.remove(set);
}
@Override
public void cancel() {
}
}
private class ScopeContentProvider implements IStructuredContentProvider {
@Override
public Object[] getElements(Object inputElement) {
return sets.toArray();
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
private class ScopeLabelProvider extends LabelProvider {
@Override
public String getText(Object obj) {
String name = findNewName((ScopeSet)obj);
if (name!=null)
return name;
return ((ScopeSet)obj).getName();
}
private String findNewName(ScopeSet set) {
PendingOperation op = findOperation(set, RenameOperation.class);
if (op!=null) {
RenameOperation rop = (RenameOperation)op;
return rop.newName;
}
return null;
}
@Override
public Image getImage(Object obj) {
return HelpUIResources.getImage(IHelpUIConstants.IMAGE_SCOPE_SET);
}
}
/**
* @param parent
*/
public ScopeSetDialog(Shell parent, ScopeSetManager manager, EngineDescriptorManager descManager, boolean localOnly) {
super(parent);
this.manager = manager;
this.descManager = descManager;
this.sets = extractSets(manager.getScopeSets(false));
this.localOnly = localOnly;
contentProvider = new ScopeContentProvider();
labelProvider = new ScopeLabelProvider();
setInitialSelections( manager.getActiveSet());
}
private void setInitialSelections(ScopeSet scopeSet) {
initialSelection = scopeSet;
}
private ArrayList<ScopeSet> extractSets(ScopeSet[] array) {
ArrayList<ScopeSet> list = new ArrayList<>();
for (int i=0; i<array.length; i++) {
list.add(array[i]);
}
return list;
}
@Override
protected Control createDialogArea(Composite container) {
Composite innerContainer = (Composite)super.createDialogArea(container);
createRadioButtons(innerContainer);
createTable(innerContainer);
enableTable();
PlatformUI.getWorkbench().getHelpSystem().setHelp(innerContainer,
"org.eclipse.help.ui.searchScope"); //$NON-NLS-1$
createEditingButtons(innerContainer);
viewer.addSelectionChangedListener(event -> updateButtons());
ViewerFilter[] filters = { new NonDefaultFilter() };
viewer.setFilters(filters );
return innerContainer;
}
private void createRadioButtons(Composite parent) {
boolean showAll = initialSelection != null && initialSelection.isDefault();
showAllRadio = new Button(parent, SWT.RADIO);
showAllRadio.setText(Messages.ScopeSet_selectAll);
showSelectedRadio = new Button(parent, SWT.RADIO);
showSelectedRadio.setText(Messages.ScopeSet_selectWorkingSet);
showAllRadio.addSelectionListener(new ShowAllListener());
showAllRadio.setSelection(showAll);
showSelectedRadio.setSelection(!showAll);
}
private void createTable(Composite parent) {
viewer = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
viewer.setContentProvider(contentProvider);
viewer.setLabelProvider(labelProvider);
viewer.setInput(input);
viewer.addDoubleClickListener(event -> okPressed());
if (initialSelection != null) {
viewer.setSelection(new StructuredSelection(initialSelection));
}
GridData gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = convertHeightInCharsToPixels(heightInChars);
gd.widthHint = convertWidthInCharsToPixels(widthInChars);
Table table = viewer.getTable();
table.setLayoutData(gd);
table.setFont(parent.getFont());
}
private void enableTable() {
if (viewer != null) {
boolean showSelected = showSelectedRadio.getSelection();
viewer.getTable().setEnabled(showSelected);
viewer.refresh();
// Ensure that a scope is selected unless there are no
// user defined scopes
if (showSelected && viewer.getSelection().isEmpty()) {
Object firstElement = viewer.getElementAt(0);
if ( firstElement != null ) {
viewer.setSelection(new StructuredSelection(firstElement));
}
}
}
}
private void createEditingButtons(Composite composite) {
Composite buttonComposite= new Composite(composite, SWT.RIGHT);
GridLayout layout= new GridLayout();
layout.numColumns= 2;
buttonComposite.setLayout(layout);
GridData data= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
data.grabExcessHorizontalSpace= true;
composite.setData(data);
createButton(buttonComposite, NEW_ID, Messages.ScopeSetDialog_new, false);
renameButton = createButton(buttonComposite, RENAME_ID, Messages.ScopeSetDialog_rename, false);
editButton = createButton(buttonComposite, EDIT_ID, Messages.ScopeSetDialog_edit, false);
removeButton = createButton(buttonComposite, REMOVE_ID, Messages.ScopeSetDialog_remove, false);
updateButtons();
}
public ScopeSet getActiveSet() {
if (result!=null && result.length>0)
return (ScopeSet)result[0];
return null;
}
@Override
protected void okPressed() {
if (operations!=null) {
for (int i=0; i<operations.size(); i++) {
PendingOperation operation = operations.get(i);
operation.commit();
}
operations = null;
}
if (showAllRadio.getSelection()) {
setResult(manager.getDefaultScope());
} else {
// Build a list of selected children.
IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
setResult(selection.toList());
}
super.okPressed();
}
private void setResult(ScopeSet scope) {
result = new Object[] { scope };
}
private void setResult(List<?> newResult) {
if (newResult == null) {
result = null;
} else {
result = new Object[newResult.size()];
newResult.toArray(result);
}
}
@Override
protected void cancelPressed() {
if (operations!=null) {
for (int i=0; i<operations.size(); i++) {
PendingOperation operation = operations.get(i);
operation.cancel();
}
operations = null;
}
super.cancelPressed();
}
@Override
protected void buttonPressed(int buttonId) {
switch (buttonId) {
case NEW_ID:
doNew();
doEdit();
break;
case EDIT_ID:
doEdit();
break;
case RENAME_ID:
doRename();
break;
case REMOVE_ID:
doRemove();
break;
}
super.buttonPressed(buttonId);
}
private void doNew() {
ScopeSet newSet = new ScopeSet(getDefaultName());
String name = getNewName(newSet.getName(), false);
if (name!=null) {
newSet.setName(name);
scheduleOperation(new AddOperation(newSet));
sets.add(newSet);
viewer.refresh();
viewer.setSelection(new StructuredSelection(newSet));
updateButtons();
}
}
private String getDefaultName() {
Set<String> namesInUse = new HashSet<>();
for (int i=0; i<sets.size(); i++) {
ScopeSet set = sets.get(i);
namesInUse.add(set.getName().toLowerCase());
}
for (int i = 1; i < 1000; i++) {
String name = Messages.ScopeSetDialog_defaultName + i;
if (!namesInUse.contains(name.toLowerCase())) {
return name;
}
}
return ""; //$NON-NLS-1$
}
private void doEdit() {
IStructuredSelection ssel = (IStructuredSelection)viewer.getSelection();
ScopeSet set = (ScopeSet)ssel.getFirstElement();
if (set==null) {
return;
}
PreferenceManager manager = new ScopePreferenceManager(descManager, set);
if (!localOnly) {
PreferenceDialog dialog = new ScopePreferenceDialog(getShell(), manager, descManager, set.isEditable());
dialog.setPreferenceStore(set.getPreferenceStore());
dialog.create();
dialog.getShell().setText(NLS.bind(Messages.ScopePreferenceDialog_wtitle, set.getName()));
dialog.open();
} else {
LocalScopeDialog localDialog = new LocalScopeDialog(getShell(), manager, descManager, set);
localDialog.create();
localDialog.getShell().setText(NLS.bind(Messages.ScopePreferenceDialog_wtitle, set.getName()));
localDialog.open();
}
}
private void doRename() {
IStructuredSelection ssel = (IStructuredSelection)viewer.getSelection();
ScopeSet set = (ScopeSet)ssel.getFirstElement();
if (set!=null) {
RenameOperation rop = (RenameOperation)findOperation(set, RenameOperation.class);
String oldName = rop!=null?rop.newName:set.getName();
String newName = getNewName(oldName, true);
if (newName!=null) {
if (rop!=null)
rop.newName = newName;
else
scheduleOperation(new RenameOperation(set, newName));
viewer.update(set, null);
updateButtons();
}
}
}
private String getNewName(String oldName, boolean isRename) {
RenameDialog dialog = new RenameDialog(getShell(), oldName);
for (int i=0; i<sets.size(); i++) {
ScopeSet set = sets.get(i);
dialog.addOldName(set.getName());
}
dialog.create();
String dialogTitle = isRename ?
Messages.RenameDialog_wtitle : Messages.NewDialog_wtitle;
dialog.getShell().setText(dialogTitle);
if (dialog.open()==RenameDialog.OK) {
return dialog.getNewName();
}
return null;
}
private void doRemove() {
IStructuredSelection ssel = (IStructuredSelection)viewer.getSelection();
ScopeSet set = (ScopeSet)ssel.getFirstElement();
if (set!=null) {
scheduleOperation(new RemoveOperation(set));
sets.remove(set);
viewer.refresh();
// Set the selection to the first remaining element
Object element = viewer.getElementAt(0);
if (element != null) {
viewer.setSelection(new StructuredSelection(element));
}
updateButtons();
}
}
private void scheduleOperation(PendingOperation op) {
if (operations==null)
operations = new ArrayList<>();
operations.add(op);
}
private void updateButtons() {
IStructuredSelection ssel = (IStructuredSelection)viewer.getSelection();
editButton.setEnabled(ssel.isEmpty()==false);
ScopeSet set = (ScopeSet)ssel.getFirstElement();
boolean editableSet = set!=null && set.isEditable() && !set.isImplicit();
removeButton.setEnabled(editableSet);
renameButton.setEnabled(editableSet);
}
private PendingOperation findOperation(ScopeSet set, Class<?> type) {
if (operations!=null) {
for (int i=0; i<operations.size(); i++) {
PendingOperation op = operations.get(i);
if (op.getClass().equals(type)) {
if (op.set.equals(set))
return op;
}
}
}
return null;
}
public void setInput(ScopeSetManager scopeSetManager) {
input = scopeSetManager;
}
}