blob: 6373cd9c897bd94495b4442a82f524ec6528e162 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.internal.ui.dialogs;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import org.eclipse.dltk.core.search.IDLTKSearchScope;
import org.eclipse.dltk.core.search.MethodNameMatch;
import org.eclipse.dltk.core.search.SearchEngine;
import org.eclipse.dltk.internal.corext.util.Strings;
import org.eclipse.dltk.internal.ui.DLTKUIMessages;
import org.eclipse.dltk.internal.ui.search.DLTKSearchScopeFactory;
import org.eclipse.dltk.internal.ui.util.MethodNameMatchLabelProvider;
import org.eclipse.dltk.internal.ui.util.SWTUtil;
import org.eclipse.dltk.internal.ui.workingsets.WorkingSetFilterActionGroup;
import org.eclipse.dltk.ui.DLTKPluginImages;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.IDLTKUILanguageToolkit;
import org.eclipse.dltk.ui.dialogs.ITypeSelectionComponent;
import org.eclipse.dltk.ui.util.PixelConverter;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;
public class MethodSelectionComponent extends Composite implements ITypeSelectionComponent {
private IDialogSettings fSettings;
private boolean fMultipleSelection;
private ITitleLabel fTitleLabel;
private ToolBar fToolBar;
private ToolItem fToolItem;
private MenuManager fMenuManager;
private WorkingSetFilterActionGroup fFilterActionGroup;
private Text fFilter;
private String fInitialFilterText;
private IDLTKSearchScope fScope;
private MethodInfoViewer fViewer;
private ViewForm fForm;
private CLabel fLabel;
public static final int NONE = 0;
public static final int CARET_BEGINNING = 1;
public static final int FULL_SELECTION = 2;
private static final String DIALOG_SETTINGS = "org.eclipse.jdt.internal.ui.dialogs.TypeSelectionComponent"; //$NON-NLS-1$
private static final String SHOW_STATUS_LINE = "show_status_line"; //$NON-NLS-1$
private static final String WORKINGS_SET_SETTINGS = "workingset_settings"; //$NON-NLS-1$
private IDLTKUILanguageToolkit fToolkit;
private class ToggleStatusLineAction extends Action {
public ToggleStatusLineAction() {
super(DLTKUIMessages.TypeSelectionComponent_show_status_line_label, IAction.AS_CHECK_BOX);
}
@Override
public void run() {
if (fForm == null)
return;
GridData gd = (GridData) fForm.getLayoutData();
boolean checked = isChecked();
gd.exclude = !checked;
fForm.setVisible(checked);
fSettings.put(SHOW_STATUS_LINE, checked);
MethodSelectionComponent.this.layout();
}
}
/**
* Special interface to access a title lable in
* a generic fashion.
*/
public interface ITitleLabel {
/**
* Sets the title to the given text
*
* @param text the title text
*/
public void setText(String text);
}
public MethodSelectionComponent(Composite parent, int style, String message, boolean multi, IDLTKSearchScope scope, int elementKind, String initialFilter, ITitleLabel titleLabel, IDLTKUILanguageToolkit toolkit) {
super(parent, style);
this.fToolkit = toolkit;
setFont(parent.getFont());
fMultipleSelection = multi;
fScope = scope;
fInitialFilterText = initialFilter;
fTitleLabel = titleLabel;
IDialogSettings settings = DLTKUIPlugin.getDefault().getDialogSettings();
fSettings = settings.getSection(DIALOG_SETTINGS);
if (fSettings == null) {
fSettings = new DialogSettings(DIALOG_SETTINGS);
settings.addSection(fSettings);
}
if (fSettings.get(SHOW_STATUS_LINE) == null) {
fSettings.put(SHOW_STATUS_LINE, true);
}
createContent(message, elementKind);
}
@Override
public void triggerSearch() {
fViewer.forceSearch();
}
public MethodNameMatch[] getSelection() {
return fViewer.getSelection();
}
public IDLTKSearchScope getScope() {
return fScope;
}
private void createContent(final String message, int elementKind) {
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
setLayout(layout);
Font font = getFont();
Control header = createHeader(this, font, message);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
header.setLayoutData(gd);
fFilter = new Text(this, SWT.BORDER | SWT.FLAT);
fFilter.setFont(font);
if (fInitialFilterText != null) {
fFilter.setText(fInitialFilterText);
}
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fFilter.setLayoutData(gd);
fFilter.addModifyListener(e -> patternChanged((Text) e.widget));
fFilter.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.keyCode == SWT.ARROW_DOWN) {
fViewer.setFocus();
}
}
});
fFilter.getAccessible().addAccessibleListener(new AccessibleAdapter() {
@Override
public void getName(AccessibleEvent e) {
e.result = Strings.removeMnemonicIndicator(message);
}
});
TextFieldNavigationHandler.install(fFilter);
Label label = new Label(this, SWT.NONE);
label.setFont(font);
label.setText(DLTKUIMessages.MethodSelectionComponent_label);
label.addTraverseListener(e -> {
if (e.detail == SWT.TRAVERSE_MNEMONIC && e.doit) {
e.detail = SWT.TRAVERSE_NONE;
fViewer.setFocus();
}
});
label = new Label(this, SWT.RIGHT);
label.setFont(font);
gd = new GridData(GridData.FILL_HORIZONTAL);
label.setLayoutData(gd);
fViewer = new MethodInfoViewer(this, fMultipleSelection ? SWT.MULTI : SWT.NONE, label, fScope, elementKind, fInitialFilterText, this.fToolkit);
gd = new GridData(GridData.FILL_BOTH);
final Table table = fViewer.getTable();
PixelConverter converter = new PixelConverter(table);
gd.widthHint = converter.convertWidthInCharsToPixels(70);
gd.heightHint = SWTUtil.getTableHeightHint(table, 10);
gd.horizontalSpan = 2;
table.setLayoutData(gd);
table.getAccessible().addAccessibleListener(new AccessibleAdapter() {
@Override
public void getName(AccessibleEvent e) {
if (table.getSelectionCount() == 0) {
e.result = Strings.removeMnemonicIndicator(DLTKUIMessages.MethodSelectionComponent_label);
}
}
});
if (!fMultipleSelection) {
fForm = new ViewForm(this, SWT.BORDER | SWT.FLAT);
fForm.setFont(font);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
boolean showStatusLine = fSettings.getBoolean(SHOW_STATUS_LINE);
gd.exclude = !showStatusLine;
fForm.setVisible(showStatusLine);
fForm.setLayoutData(gd);
fLabel = new CLabel(fForm, SWT.FLAT);
fLabel.setFont(fForm.getFont());
fForm.setContent(fLabel);
table.addSelectionListener(new SelectionAdapter() {
private MethodNameMatchLabelProvider fLabelProvider = new MethodNameMatchLabelProvider(MethodNameMatchLabelProvider.SHOW_TYPE_CONTAINER_ONLY + MethodNameMatchLabelProvider.SHOW_ROOT_POSTFIX, fToolkit);
@Override
public void widgetSelected(SelectionEvent event) {
MethodNameMatch[] selection = fViewer.getSelection();
if (selection.length != 1) {
fLabel.setText(""); //$NON-NLS-1$
fLabel.setImage(null);
} else {
MethodNameMatch type = selection[0];
fLabel.setText(fViewer.getLabelProvider().getQualificationText(type));
fLabel.setImage(fLabelProvider.getImage(type));
}
}
});
}
addDisposeListener(event -> disposeComponent());
}
public void addSelectionListener(SelectionListener listener) {
fViewer.getTable().addSelectionListener(listener);
}
public void populate(int selectionMode) {
if (fInitialFilterText != null) {
switch (selectionMode) {
case CARET_BEGINNING:
fFilter.setSelection(0, 0);
break;
case FULL_SELECTION:
fFilter.setSelection(0, fInitialFilterText.length());
break;
}
}
fFilter.setFocus();
fViewer.startup();
}
private void patternChanged(Text text) {
fViewer.setSearchPattern(text.getText());
}
private Control createHeader(Composite parent, Font font, String message) {
Composite header = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
header.setLayout(layout);
header.setFont(font);
Label label = new Label(header, SWT.NONE);
label.setText(message);
label.setFont(font);
label.addTraverseListener(e -> {
if (e.detail == SWT.TRAVERSE_MNEMONIC && e.doit) {
e.detail = SWT.TRAVERSE_NONE;
fFilter.setFocus();
}
});
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
label.setLayoutData(gd);
createViewMenu(header);
return header;
}
private void createViewMenu(Composite parent) {
fToolBar = new ToolBar(parent, SWT.FLAT);
fToolItem = new ToolItem(fToolBar, SWT.PUSH, 0);
GridData data = new GridData();
data.horizontalAlignment = GridData.END;
fToolBar.setLayoutData(data);
fToolItem.setImage(DLTKUIPlugin.getImageDescriptorRegistry().get(
DLTKPluginImages.DESC_ELCL_VIEW_MENU));
fToolItem.setDisabledImage(DLTKUIPlugin.getImageDescriptorRegistry()
.get(DLTKPluginImages.DESC_DLCL_VIEW_MENU));
fToolItem.setToolTipText(DLTKUIMessages.TypeSelectionComponent_menu);
fToolItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
showViewMenu();
}
});
fMenuManager = new MenuManager();
fillViewMenu(fMenuManager);
// ICommandService commandService= (ICommandService)PlatformUI.getWorkbench().getAdapter(ICommandService.class);
// IHandlerService handlerService= (IHandlerService)PlatformUI.getWorkbench().getAdapter(IHandlerService.class);
}
private void showViewMenu() {
Menu menu = fMenuManager.createContextMenu(getShell());
Rectangle bounds = fToolItem.getBounds();
Point topLeft = new Point(bounds.x, bounds.y + bounds.height);
topLeft = fToolBar.toDisplay(topLeft);
menu.setLocation(topLeft.x, topLeft.y);
menu.setVisible(true);
}
private void fillViewMenu(IMenuManager viewMenu) {
if (!fMultipleSelection) {
ToggleStatusLineAction showStatusLineAction = new ToggleStatusLineAction();
showStatusLineAction.setChecked(fSettings.getBoolean(SHOW_STATUS_LINE));
viewMenu.add(showStatusLineAction);
}
if (fScope == null) {
fFilterActionGroup = new WorkingSetFilterActionGroup(getShell(),
DLTKUIPlugin.getActivePage(), event -> {
IWorkingSet ws = (IWorkingSet) event.getNewValue();
if (ws == null || (ws.isAggregateWorkingSet()
&& ws.isEmpty())) {
fScope = SearchEngine.createWorkspaceScope(
fToolkit.getCoreToolkit());
fTitleLabel.setText(null);
} else {
fScope = DLTKSearchScopeFactory.getInstance()
.createSearchScope(ws, true,
fToolkit.getCoreToolkit());
fTitleLabel.setText(ws.getLabel());
}
fViewer.setSearchScope(fScope, true);
});
String setting = fSettings.get(WORKINGS_SET_SETTINGS);
if (setting != null) {
try {
IMemento memento = XMLMemento.createReadRoot(new StringReader(setting));
fFilterActionGroup.restoreState(memento);
} catch (WorkbenchException e) {
}
}
IWorkingSet ws = fFilterActionGroup.getWorkingSet();
if (ws == null || (ws.isAggregateWorkingSet() && ws.isEmpty())) {
fScope = SearchEngine.createWorkspaceScope(fToolkit.getCoreToolkit());
fTitleLabel.setText(null);
} else {
fScope = DLTKSearchScopeFactory.getInstance().createSearchScope(ws, true, fToolkit.getCoreToolkit());
fTitleLabel.setText(ws.getLabel());
}
fFilterActionGroup.fillViewMenu(viewMenu);
}
}
private void disposeComponent() {
if (fFilterActionGroup != null) {
XMLMemento memento = XMLMemento.createWriteRoot("workingSet"); //$NON-NLS-1$
fFilterActionGroup.saveState(memento);
fFilterActionGroup.dispose();
StringWriter writer = new StringWriter();
try {
memento.save(writer);
fSettings.put(WORKINGS_SET_SETTINGS, writer.getBuffer().toString());
} catch (IOException e) {
// don't do anything. Simply don't store the settings
}
}
}
}