| /* |
| * 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>: " + 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>: " + 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>: " //$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 |
| } |
| } |