blob: f604fc170fe465ec0769146bec8083a183d4e352 [file] [log] [blame]
/*
* Copyright (c) 2016 Ed Merks (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Ed Merks - initial API and implementation
*/
package org.eclipse.oomph.setup.ui;
import org.eclipse.oomph.setup.internal.core.util.IndexManager;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.ReflectUtil;
import org.eclipse.emf.common.ui.viewer.ColumnViewerInformationControlToolTipSupport;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.edit.provider.IItemFontProvider;
import org.eclipse.emf.edit.ui.provider.ExtendedFontRegistry;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.text.AbstractHoverInformationControlManager;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* @author Ed Merks
*/
public class IndexManagerDialog extends AbstractSetupDialog
{
public static final String TITLE = Messages.IndexManagerDialog_title;
public static final String DESCRIPTION = Messages.IndexManagerDialog_description;
private static final int REMOVE_ID = IDialogConstants.CLIENT_ID + 1;
private final IndexManager indexManager = new IndexManager();
private TableViewer indexViewer;
private Button removeButton;
private Map<URI, String> originalIndexChoices;
private Map<URI, String> indexChoices;
private Map<URI, Boolean> indexAvailability;
private IndexScope indexScope = IndexScope.LOCAL;
private URI originalIndexLocation;
public IndexManagerDialog(Shell parentShell)
{
super(parentShell, Messages.IndexManagerDialog_dialogTitle, 750, 300, SetupUIPlugin.INSTANCE, true);
indexChoices = indexManager.getIndexLabels(true);
originalIndexChoices = new LinkedHashMap<URI, String>(indexChoices);
if (!originalIndexChoices.isEmpty())
{
originalIndexLocation = originalIndexChoices.keySet().iterator().next();
}
new Job(Messages.IndexManagerDialog_availabilityCheckerJob_name)
{
@Override
protected IStatus run(IProgressMonitor monitor)
{
indexAvailability = indexManager.getIndexAvailability(false);
UIUtil.asyncExec(indexViewer.getControl(), new Runnable()
{
public void run()
{
indexViewer.refresh();
}
});
return Status.OK_STATUS;
}
}.schedule(1000);
}
@Override
protected String getShellText()
{
return TITLE;
}
@Override
protected String getDefaultMessage()
{
return DESCRIPTION + "."; //$NON-NLS-1$
}
@Override
protected void createUI(Composite parent)
{
indexViewer = new TableViewer(parent, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
indexViewer.getTable().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
indexViewer.setContentProvider(new IStructuredContentProvider()
{
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
// Do nothing.
}
public void dispose()
{
// Do nothing.
}
public Object[] getElements(Object inputElement)
{
return indexChoices.entrySet().toArray();
}
});
final ColumnViewerInformationControlToolTipSupport columnViewerInformationControlToolTipSupport = new ColumnViewerInformationControlToolTipSupport(
indexViewer, new LocationListener()
{
public void changing(LocationEvent event)
{
}
public void changed(LocationEvent event)
{
}
});
class MyLabelProvider extends CellLabelProvider implements ILabelProvider
{
private final Color gray = indexViewer.getTable().getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
private final Font normalFont = indexViewer.getTable().getFont();
private final Font italicFont = ExtendedFontRegistry.INSTANCE.getFont(normalFont, IItemFontProvider.ITALIC_FONT);
private final Font boldFont = ExtendedFontRegistry.INSTANCE.getFont(normalFont, IItemFontProvider.BOLD_FONT);
public String getText(Object element)
{
return asMapEntry(element).getValue();
}
public Image getImage(Object element)
{
return SetupUIPlugin.INSTANCE.getSWTImage("full/obj16/Index"); //$NON-NLS-1$
}
@Override
public String getToolTipText(Object element)
{
URI indexLocation = asMapEntry(element).getKey();
Map<URI, String> indexNames = indexManager.getIndexNames(true);
StringBuilder result = new StringBuilder();
String nameLine = "<divs style='white-space:nowrap;'><b>" + Messages.IndexManagerDialog_tooltip_name + "</b>:&nbsp;" + indexNames.get(indexLocation) //$NON-NLS-1$//$NON-NLS-2$
+ "</div>\n"; //$NON-NLS-1$
result.append(nameLine);
String locationLine = "<div style='white-space:nowrap;'><b>" + Messages.IndexManagerDialog_tooltip_location + "</b>:&nbsp;" + indexLocation //$NON-NLS-1$ //$NON-NLS-2$
+ "</div>\n"; //$NON-NLS-1$
result.append(locationLine);
String availabilityLine = "<div style='white-space:nowrap;'><b>" + Messages.IndexManagerDialog_tooltip_availability + "</b>:&nbsp;" //$NON-NLS-1$ //$NON-NLS-2$
+ (indexAvailability == null ? Messages.IndexManagerDialog_tooltip_availability_unknown
: indexAvailability.get(indexLocation) ? Messages.IndexManagerDialog_tooltip_availability_available
: Messages.IndexManagerDialog_tooltip_availability_unavailable)
+ "</div><br/><br/>\n"; //$NON-NLS-1$
result.append(availabilityLine);
try
{
AbstractHoverInformationControlManager hoverInformationControlManager = ReflectUtil.getValue("hoverInformationControlManager", //$NON-NLS-1$
columnViewerInformationControlToolTipSupport);
int max = Math.max(nameLine.length(), locationLine.length());
hoverInformationControlManager.setSizeConstraints(max, 6, false, false);
}
catch (Throwable throwable)
{
// Ignore.
}
return result.toString();
}
@Override
public void update(ViewerCell cell)
{
Object element = cell.getElement();
cell.setImage(getImage(element));
URI indexLocation = asMapEntry(element).getKey();
if (!originalIndexChoices.containsKey(indexLocation))
{
cell.setForeground(gray);
}
if (indexLocation.equals(originalIndexLocation))
{
cell.setFont(boldFont);
}
else if (indexAvailability != null && !indexAvailability.get(indexLocation))
{
cell.setFont(italicFont);
}
else
{
cell.setFont(normalFont);
}
cell.setText(getText(element) + " "); //$NON-NLS-1$
}
}
final ILabelProvider labelProvider = new MyLabelProvider();
indexViewer.setLabelProvider(labelProvider);
final TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(indexViewer, new FocusCellOwnerDrawHighlighter(indexViewer));
indexViewer.addSelectionChangedListener(new ISelectionChangedListener()
{
public void selectionChanged(SelectionChangedEvent event)
{
focusCellManager.getFocusCell();
updateEnablement();
}
});
indexViewer.setInput(indexManager);
TextCellEditor textCellEditor = new TextCellEditor(indexViewer.getTable(), SWT.BORDER);
indexViewer.setCellEditors(new CellEditor[] { textCellEditor });
indexViewer.setColumnProperties(new String[] { "label" }); //$NON-NLS-1$
ColumnViewerEditorActivationStrategy editorActivationStrategy = new ColumnViewerEditorActivationStrategy(indexViewer)
{
@Override
protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event)
{
return event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION
|| event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.F2;
}
};
TableViewerEditor.create(indexViewer, focusCellManager, editorActivationStrategy, ColumnViewerEditor.KEYBOARD_ACTIVATION);
indexViewer.setCellModifier(new ICellModifier()
{
public void modify(Object element, String property, Object value)
{
asMapEntry(((TableItem)element).getData()).setValue((String)value);
indexViewer.refresh(true);
}
public Object getValue(Object element, String property)
{
return labelProvider.getText(element).trim();
}
public boolean canModify(Object element, String property)
{
return true;
}
});
if (!indexChoices.isEmpty())
{
indexViewer.setSelection(new StructuredSelection(indexChoices.entrySet().iterator().next()));
}
}
@Override
protected Control createButtonBar(Composite parent)
{
return createButtonBarWithControls(parent);
}
@Override
protected void createControlsForButtonBar(Composite parent)
{
createLabel(parent, " " + Messages.IndexManagerDialog_scopeLabel); //$NON-NLS-1$
final Combo indexCombo = createCombo(parent);
String[] items = new String[] { Messages.IndexManagerDialog_indexCombo_local, Messages.IndexManagerDialog_indexCombo_localAndGlobal,
Messages.IndexManagerDialog_indexCombo_global };
indexCombo.setItems(items);
indexCombo.select(0);
indexCombo.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
IndexScope oldIndexScope = indexScope;
indexScope = IndexScope.values()[indexCombo.getSelectionIndex()];
switch (indexScope)
{
case LOCAL:
{
if (oldIndexScope == IndexScope.GLOBAL)
{
indexChoices = indexManager.getIndexLabels(true);
}
else
{
indexChoices.keySet().retainAll(indexManager.getIndexLabels(true).keySet());
}
break;
}
case LOCAL_AND_GLOBAL:
{
if (oldIndexScope == IndexScope.GLOBAL)
{
indexChoices = indexManager.getIndexLabels(false);
}
else
{
for (Map.Entry<URI, String> entry : indexManager.getIndexLabels(false).entrySet())
{
if (!indexChoices.containsKey(entry.getKey()))
{
indexChoices.put(entry.getKey(), entry.getValue());
}
}
}
break;
}
case GLOBAL:
{
indexChoices = indexManager.getGlobalIndexManager().getIndexLabels(true);
break;
}
}
// It just doesn't show an icon or the right font unless we do it twice.
indexViewer.refresh();
indexViewer.refresh();
updateEnablement();
}
});
}
@Override
protected void createButtonsForButtonBar(Composite parent)
{
removeButton = createButton(parent, REMOVE_ID, Messages.IndexManagerDialog_removeButton_text, false);
removeButton.setEnabled(false);
super.createButtonsForButtonBar(parent);
updateEnablement();
}
protected void updateEnablement()
{
if (removeButton != null)
{
removeButton.setEnabled(!indexViewer.getSelection().isEmpty());
}
}
@Override
protected void buttonPressed(int buttonId)
{
if (buttonId == REMOVE_ID)
{
IStructuredSelection selection = (IStructuredSelection)indexViewer.getSelection();
List<?> list = selection.toList();
Object newSelection = null;
boolean visitedRemovedEntry = false;
for (Map.Entry<URI, String> entry : indexChoices.entrySet())
{
if (list.contains(entry))
{
visitedRemovedEntry = true;
if (newSelection != null)
{
break;
}
}
else
{
newSelection = entry;
if (visitedRemovedEntry)
{
break;
}
}
}
indexChoices.entrySet().removeAll(list);
if (newSelection != null)
{
indexViewer.setSelection(new StructuredSelection(newSelection));
}
indexViewer.refresh();
}
super.buttonPressed(buttonId);
}
protected Map.Entry<URI, String> asMapEntry(Object object)
{
@SuppressWarnings("unchecked")
Map.Entry<URI, String> result = (Entry<URI, String>)object;
return result;
}
@Override
public String getHelpPath()
{
return SetupUIPlugin.INSTANCE.getSymbolicName() + "/html/IndexManagementHelp.html"; //$NON-NLS-1$
}
@Override
protected void okPressed()
{
IndexManager indexManager = indexScope == IndexScope.GLOBAL ? this.indexManager.getGlobalIndexManager() : this.indexManager;
boolean local = indexScope != IndexScope.LOCAL_AND_GLOBAL;
Map<URI, String> indexChoices = indexManager.getIndexLabels(true);
Set<URI> removedURIs = new LinkedHashSet<URI>(indexChoices.keySet());
removedURIs.removeAll(this.indexChoices.keySet());
for (URI indexLocation : removedURIs)
{
indexManager.remove(indexLocation, local);
}
Set<URI> addedURIs = new LinkedHashSet<URI>(this.indexChoices.keySet());
addedURIs.removeAll(indexChoices.keySet());
if (!addedURIs.isEmpty())
{
Map<URI, String> indexNames = indexManager.getIndexNames(false);
for (URI indexLocation : addedURIs)
{
indexManager.addIndex(indexLocation, indexNames.get(indexLocation), true);
indexManager.setLabel(indexLocation, this.indexChoices.get(indexLocation), local);
this.indexChoices.remove(indexLocation);
}
URI originalFirstIndexLocation = this.indexChoices.keySet().iterator().next();
indexManager.addIndex(originalFirstIndexLocation, indexNames.get(originalFirstIndexLocation), true);
}
for (Map.Entry<URI, String> entry : this.indexChoices.entrySet())
{
if (!indexChoices.get(entry.getKey()).equals(entry.getValue()))
{
indexManager.setLabel(entry.getKey(), entry.getValue(), local);
}
}
super.okPressed();
}
/**
* @author Ed Merks
*/
public static enum IndexScope
{
LOCAL, LOCAL_AND_GLOBAL, GLOBAL
}
}