blob: 15c2ebe9c74db5ac56fd7b92f70611a062c84cad [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2008, 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.ui.refactoring;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.statet.ecommons.ui.components.CellEditorWizardStatusUpdater;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils.TreeComposite;
import org.eclipse.statet.internal.r.ui.RIdentifierCellValidator;
import org.eclipse.statet.r.core.model.RElement;
import org.eclipse.statet.r.core.model.RFrame;
import org.eclipse.statet.r.core.model.RSourceFrame;
import org.eclipse.statet.r.core.refactoring.RenameInRegionRefactoring;
import org.eclipse.statet.r.core.refactoring.RenameInRegionRefactoring.Variable;
import org.eclipse.statet.r.ui.RLabelProvider;
public class RenameInRegionWizard extends RefactoringWizard {
private static class RenameInRegionInputPage extends UserInputWizardPage {
public static final String PAGE_NAME= "RenameInRegion.InputPage"; //$NON-NLS-1$
private static class NameEditing extends EditingSupport {
private final TextCellEditor cellEditor;
public NameEditing(final ColumnViewer viewer) {
super(viewer);
this.cellEditor= new TextCellEditor((Composite) viewer.getControl());
this.cellEditor.getControl().setFont(JFaceResources.getTextFont());
this.cellEditor.setValidator(new RIdentifierCellValidator());
}
@Override
protected boolean canEdit(final Object element) {
return (element instanceof Variable);
}
@Override
protected CellEditor getCellEditor(final Object element) {
if (element instanceof Variable) {
return this.cellEditor;
}
return null;
}
@Override
protected Object getValue(final Object element) {
if (element instanceof Variable) {
final Variable variable= (Variable) element;
final String name= variable.getNewName();
if (name != null) {
return name;
}
return variable.getName();
}
return null;
}
@Override
protected void setValue(final Object element, final Object value) {
if (element instanceof Variable) {
final Variable variable= (Variable) element;
variable.setNewName((String) value);
getViewer().update(element, null);
}
}
}
private static final ViewerFilter[] FILTER_RESOLVED= new ViewerFilter[] {
new ViewerFilter() {
@Override
public boolean select(final Viewer viewer, final Object parentElement, final Object element) {
if (element instanceof Variable) {
final Variable variable= (Variable) element;
if (variable.getParent() instanceof RSourceFrame) {
final RSourceFrame frame= (RSourceFrame)variable.getParent();
return frame.isResolved(variable.getName());
}
}
return true;
}
}
};
private static final ViewerFilter[] FILTER_OFF= new ViewerFilter[0];
private TreeViewer variablesViewer;
public RenameInRegionInputPage() {
super(PAGE_NAME);
}
@Override
protected RenameInRegionRefactoring getRefactoring() {
return (RenameInRegionRefactoring) super.getRefactoring();
}
@Override
public void createControl(final Composite parent) {
final Composite composite= new Composite(parent, SWT.NONE);
composite.setLayout(LayoutUtils.newDialogGrid(2));
setControl(composite);
composite.setFont(JFaceResources.getDialogFont());
initializeDialogUnits(composite);
{ final Label label= new Label(composite, SWT.NONE);
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
label.setText(Messages.RenameInRegion_Wizard_header);
label.setFont(JFaceResources.getBannerFont());
}
LayoutUtils.addSmallFiller(composite, false);
final Control table= createVariablesTable(composite);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
LayoutUtils.addSmallFiller(composite, false);
Dialog.applyDialogFont(composite);
// PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), );
this.variablesViewer.setFilters(FILTER_RESOLVED);
this.variablesViewer.setInput(getRefactoring().getVariables());
}
private Control createVariablesTable(final Composite parent) {
final Composite composite= new Composite(parent, SWT.NONE);
composite.setLayout(LayoutUtils.newCompositeGrid(2));
{ final Composite above= new Composite(composite, SWT.NONE);
above.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false, 2, 1));
above.setLayout(LayoutUtils.newCompositeGrid(2));
final Label label= new Label(above, SWT.NONE);
label.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));
label.setText("Enter new variable name(s):");
label.addTraverseListener(new TraverseListener() {
@Override
public void keyTraversed(final TraverseEvent e) {
if (e.detail == SWT.TRAVERSE_MNEMONIC) {
e.doit= false;
RenameInRegionInputPage.this.variablesViewer.getControl().setFocus();
}
}
});
final Button showAll= new Button(above, SWT.CHECK);
showAll.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
showAll.setText("Show &all identifiers");
showAll.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
if (showAll.getSelection()) {
RenameInRegionInputPage.this.variablesViewer.setFilters(FILTER_OFF);
}
else {
RenameInRegionInputPage.this.variablesViewer.setFilters(FILTER_RESOLVED);
}
}
});
}
final TreeComposite table= new TreeComposite(composite, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
table.tree.setHeaderVisible(true);
table.tree.setLinesVisible(true);
final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
gd.heightHint= LayoutUtils.hintHeight(table.tree, 12);
table.setLayoutData(gd);
table.viewer.setAutoExpandLevel(2);
this.variablesViewer= table.viewer;
{ final TreeViewerColumn column= new TreeViewerColumn(table.viewer, SWT.NONE);
column.getColumn().setText("Scope / Variable");
table.layout.setColumnData(column.getColumn(), new ColumnWeightData(1));
column.setLabelProvider(new CellLabelProvider() {
private final RLabelProvider fFrameLabelProvider= new RLabelProvider();
@Override
public void update(final ViewerCell cell) {
cell.setBackground(null);
final Object element= cell.getElement();
if (element instanceof RFrame) {
cell.setFont(null);
final RFrame frame= (RFrame) element;
final List<? extends RElement> modelElements= frame.getModelElements();
cell.setImage(null);
if (modelElements.size() > 0) {
this.fFrameLabelProvider.update(cell, modelElements.get(0));
cell.setText(cell.getText() + " "); //$NON-NLS-1$
return;
}
// final IElementName elementName= frame.getElementName();
// if (elementName != null) {
// cell.setText(elementName.getDisplayName());
// return;
// }
cell.setText(frame.getFrameId() + " "); //$NON-NLS-1$
cell.setStyleRanges(null);
return;
}
if (element instanceof Variable) {
cell.setFont(null);
final Variable variable= (Variable) element;
final String name= variable.getName();
cell.setImage(null);
cell.setText(name + " "); //$NON-NLS-1$
cell.setStyleRanges(null);
return;
}
cell.setImage(null);
cell.setText(""); //$NON-NLS-1$
cell.setStyleRanges(null);
}
});
}
{ final TreeViewerColumn column= new TreeViewerColumn(table.viewer, SWT.NONE);
column.getColumn().setText("New Name");
table.layout.setColumnData(column.getColumn(), new ColumnWeightData(1));
column.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final Object element= cell.getElement();
if (element instanceof Variable) {
cell.setFont(JFaceResources.getTextFont());
final Variable variable= (Variable) element;
final String name= variable.getNewName();
if (name != null) {
cell.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW));
cell.setText(name);
cell.setStyleRanges(null);
}
else {
cell.setBackground(null);
cell.setText(variable.getName());
cell.setStyleRanges(null);
}
return;
}
cell.setBackground(null);
cell.setText(""); //$NON-NLS-1$
cell.setStyleRanges(null);
}
});
final NameEditing editing= new NameEditing(table.viewer);
new CellEditorWizardStatusUpdater(editing.cellEditor, RenameInRegionInputPage.this);
column.setEditingSupport(editing);
}
{ final TreeViewerColumn column= new TreeViewerColumn(table.viewer, SWT.NONE);
column.getColumn().setText("");
table.layout.setColumnData(column.getColumn(), new ColumnPixelData(convertWidthInCharsToPixels(5)));
column.getColumn().setToolTipText("Occurrences Count");
column.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
cell.setBackground(null);
cell.setFont(null);
final Object element= cell.getElement();
if (element instanceof Variable) {
final Variable variable= (Variable) element;
cell.setText(Integer.toString(variable.getOccurrencesCount()));
cell.setStyleRanges(null);
return;
}
cell.setText(""); //$NON-NLS-1$
cell.setStyleRanges(null);
}
});
}
ViewerUtils.installDefaultEditBehaviour(table.viewer);
table.viewer.setContentProvider(new ITreeContentProvider() {
private Map<RFrame, Map<String, Variable>> fVariables;
@Override
public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
this.fVariables= (Map<RFrame, Map<String, Variable>>)newInput;
}
@Override
public Object[] getElements(final Object inputElement) {
return this.fVariables.keySet().toArray();
}
@Override
public Object getParent(final Object element) {
if (element instanceof Variable) {
return ((Variable) element).getParent();
}
return null;
}
@Override
public boolean hasChildren(final Object element) {
if (element instanceof RFrame) {
return true;
}
if (element instanceof Variable) {
return !((Variable) element).getSubVariables().isEmpty();
}
return false;
}
@Override
public Object[] getChildren(final Object parentElement) {
if (parentElement instanceof RFrame) {
return this.fVariables.get(parentElement).values().toArray();
}
if (parentElement instanceof Variable) {
return ((Variable) parentElement).getSubVariables().values().toArray();
}
return null;
}
@Override
public void dispose() {
}
});
ViewerUtils.addDoubleClickExpansion(table.viewer);
return composite;
}
@Override
public void setVisible(final boolean visible) {
super.setVisible(visible);
this.variablesViewer.getControl().setFocus();
}
}
public RenameInRegionWizard(final RenameInRegionRefactoring ref) {
super(ref, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE | NO_BACK_BUTTON_ON_STATUS_DIALOG);
setDefaultPageTitle(Messages.RenameInRegion_Wizard_title);
}
@Override
protected void addUserInputPages() {
addPage(new RenameInRegionInputPage());
}
}