| /*=============================================================================# |
| # 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()); |
| } |
| |
| } |