| /*=============================================================================# |
| # Copyright (c) 2009, 2019 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.nico.ui.preferences; |
| |
| import org.eclipse.core.databinding.UpdateValueStrategy; |
| import org.eclipse.core.databinding.observable.list.IObservableList; |
| import org.eclipse.core.databinding.observable.list.WritableList; |
| import org.eclipse.core.databinding.observable.value.IObservableValue; |
| import org.eclipse.core.databinding.observable.value.WritableValue; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.jface.databinding.swt.typed.WidgetProperties; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.ArrayContentProvider; |
| import org.eclipse.jface.viewers.CellLabelProvider; |
| import org.eclipse.jface.viewers.ColumnWeightData; |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.jface.viewers.TableViewerColumn; |
| import org.eclipse.jface.viewers.ViewerCell; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| import org.eclipse.statet.ecommons.databinding.NotEmptyValidator; |
| import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport; |
| import org.eclipse.statet.ecommons.net.resourcemapping.core.IResourceMapping; |
| import org.eclipse.statet.ecommons.net.resourcemapping.core.IResourceMappingManager; |
| import org.eclipse.statet.ecommons.net.resourcemapping.core.ResourceMappingUtils; |
| import org.eclipse.statet.ecommons.preferences.ui.ConfigurationBlock; |
| import org.eclipse.statet.ecommons.preferences.ui.ConfigurationBlockPreferencePage; |
| import org.eclipse.statet.ecommons.ui.components.ButtonGroup; |
| import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils; |
| import org.eclipse.statet.ecommons.ui.dialogs.ExtStatusDialog; |
| import org.eclipse.statet.ecommons.ui.util.LayoutUtils; |
| import org.eclipse.statet.ecommons.ui.util.VariableFilterUtils; |
| import org.eclipse.statet.ecommons.ui.viewers.ComparatorViewerComparator; |
| import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils; |
| import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils.TableComposite; |
| import org.eclipse.statet.ecommons.ui.workbench.ResourceInputComposite; |
| |
| import org.eclipse.statet.internal.nico.core.ResourceMapping; |
| import org.eclipse.statet.internal.nico.core.ResourceMappingManager; |
| import org.eclipse.statet.internal.nico.ui.NicoUIPlugin; |
| |
| |
| @NonNullByDefault |
| public class ResourceMappingPreferencePage extends ConfigurationBlockPreferencePage { |
| |
| |
| public ResourceMappingPreferencePage() { |
| } |
| |
| |
| @Override |
| protected ConfigurationBlock createConfigurationBlock() throws CoreException { |
| return new ResourceMappingConfigurationBlock(); |
| } |
| |
| } |
| |
| |
| @NonNullByDefault |
| class ResourceMappingConfigurationBlock extends ConfigurationBlock { |
| |
| |
| private TableViewer listViewer; |
| private ButtonGroup<ResourceMapping> listButtons; |
| |
| private final IObservableList<ResourceMapping> list= new WritableList<>(); |
| |
| private @Nullable ResourceMappingManager manager; |
| |
| |
| public ResourceMappingConfigurationBlock() { |
| } |
| |
| |
| @Override |
| protected String getHelpContext() { |
| return "org.eclipse.statet.nico.ui.resourcemapping"; //$NON-NLS-1$ |
| } |
| |
| @Override |
| protected void createBlockArea(final Composite pageComposite) { |
| { // Table area |
| final Composite composite= new Composite(pageComposite, SWT.NONE); |
| composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| composite.setLayout(LayoutUtils.newCompositeGrid(2)); |
| |
| final Composite table= createTable(composite); |
| table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| |
| this.listButtons= new ButtonGroup<ResourceMapping>(composite) { |
| @Override |
| protected @Nullable ResourceMapping edit1(final @Nullable ResourceMapping item, final boolean newItem, final @Nullable Object parent) { |
| final EditMappingDialog dialog= new EditMappingDialog(getShell(), item, newItem); |
| if (dialog.open() == Window.OK) { |
| return dialog.getResult(); |
| } |
| return null; |
| } |
| }; |
| this.listButtons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, true)); |
| this.listButtons.addAddButton(null); |
| this.listButtons.addCopyButton(null); |
| this.listButtons.addEditButton(null); |
| this.listButtons.addDeleteButton(null); |
| |
| this.listButtons.connectTo(this.listViewer, this.list, null); |
| this.listViewer.setInput(this.list); |
| ViewerUtils.scheduleStandardSelection(this.listViewer); |
| } |
| |
| final IResourceMappingManager manager= ResourceMappingUtils.getManager(); |
| if (manager instanceof ResourceMappingManager) { |
| this.manager= (ResourceMappingManager) manager; |
| } |
| if (this.manager != null) { |
| this.list.addAll(this.manager.getList()); |
| } |
| else { |
| DialogUtils.setEnabled(pageComposite, null, false); |
| } |
| |
| updateControls(); |
| } |
| |
| protected Composite createTable(final Composite parent) { |
| final TableComposite composite= new ViewerUtils.TableComposite(parent, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION); |
| this.listViewer= composite.viewer; |
| composite.table.setHeaderVisible(true); |
| composite.table.setLinesVisible(true); |
| |
| { final TableViewerColumn column= new TableViewerColumn(composite.viewer, SWT.NONE); |
| composite.layout.setColumnData(column.getColumn(), new ColumnWeightData(1)); |
| column.getColumn().setText("Local"); |
| column.setLabelProvider(new CellLabelProvider() { |
| @Override |
| public void update(final ViewerCell cell) { |
| final IResourceMapping mapping= (IResourceMapping) cell.getElement(); |
| final IFileStore fileStore= mapping.getFileStore(); |
| cell.setText((fileStore != null) ? fileStore.toString() : "<invalid>"); |
| } |
| }); |
| } |
| { final TableViewerColumn column= new TableViewerColumn(composite.viewer, SWT.NONE); |
| composite.layout.setColumnData(column.getColumn(), new ColumnWeightData(1)); |
| column.getColumn().setText("Host"); |
| column.setLabelProvider(new CellLabelProvider() { |
| @Override |
| public void update(final ViewerCell cell) { |
| final IResourceMapping mapping= (IResourceMapping) cell.getElement(); |
| cell.setText(mapping.getHost()); |
| } |
| }); |
| } |
| { final TableViewerColumn column= new TableViewerColumn(composite.viewer, SWT.NONE); |
| composite.layout.setColumnData(column.getColumn(), new ColumnWeightData(1)); |
| column.getColumn().setText("Remote"); |
| column.setLabelProvider(new CellLabelProvider() { |
| @Override |
| public void update(final ViewerCell cell) { |
| final IResourceMapping mapping= (IResourceMapping) cell.getElement(); |
| final IPath path= mapping.getRemotePath(); |
| cell.setText((path != null) ? path.toString() : "<invalid>"); |
| } |
| }); |
| } |
| |
| composite.viewer.setContentProvider(new ArrayContentProvider()); |
| composite.viewer.setComparator(new ComparatorViewerComparator(ResourceMappingManager.DEFAULT_COMPARATOR)); |
| |
| return composite; |
| } |
| |
| protected void updateControls() { |
| this.listButtons.refresh(); |
| } |
| |
| @Override |
| public void performDefaults() { |
| if (this.list.isEmpty()) { |
| return; |
| } |
| final boolean deleteAll= MessageDialog.openQuestion(getShell(), |
| "Load Defaults", "Delete all mappings?"); |
| if (deleteAll) { |
| this.list.clear(); |
| updateControls(); |
| } |
| } |
| |
| @Override |
| public boolean performOk(final int flags) { |
| final ResourceMappingManager manager= this.manager; |
| if (manager != null) { |
| manager.setMappings(this.list); |
| } |
| return true; |
| } |
| |
| } |
| |
| @NonNullByDefault |
| class EditMappingDialog extends ExtStatusDialog { |
| |
| |
| private ResourceInputComposite localControl; |
| private Text hostControl; |
| private Text remoteControl; |
| |
| private final String mappingId; |
| private final IObservableValue<String> localValue; |
| private final IObservableValue<String> hostValue; |
| private final IObservableValue<String> remoteValue; |
| |
| |
| public EditMappingDialog(final Shell shell, final @Nullable ResourceMapping mapping, final boolean newMapping) { |
| super(shell, (newMapping) ? WITH_DATABINDING_CONTEXT : |
| (WITH_DATABINDING_CONTEXT | SHOW_INITIAL_STATUS)); |
| setTitle("Edit Resource Mapping"); |
| |
| this.mappingId= (!newMapping) ? mapping.getId() : null; |
| this.localValue= new WritableValue<>((mapping != null) ? mapping.getLocalText() : null, String.class); |
| this.hostValue= new WritableValue<>((mapping != null) ? mapping.getHost() : null, String.class); |
| this.remoteValue= new WritableValue<>((mapping != null) ? mapping.getRemotePath().toString() : null, String.class); |
| } |
| |
| @Override |
| protected IDialogSettings getDialogBoundsSettings() { |
| return DialogUtils.getDialogSettings(NicoUIPlugin.getInstance(), "ResourceMappingEditDialog"); //$NON-NLS-1$ |
| } |
| |
| @Override |
| protected Control createDialogArea(final Composite parent) { |
| final Composite area= new Composite(parent, SWT.NONE); |
| area.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true)); |
| area.setLayout(LayoutUtils.newDialogGrid(2)); |
| |
| final Composite composite= area; |
| { final Label label= new Label(composite, SWT.NONE); |
| label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); |
| label.setText("Path on &Local:"); |
| |
| this.localControl= new ResourceInputComposite(composite, ResourceInputComposite.STYLE_TEXT, |
| ResourceInputComposite.MODE_DIRECTORY | ResourceInputComposite.MODE_OPEN, |
| "local directory"); |
| this.localControl.getValidator().setOnNotExisting(IStatus.WARNING); |
| this.localControl.setShowInsertVariable(false, VariableFilterUtils.DEFAULT_NON_ITERACTIVE_FILTERS, null); |
| final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false); |
| gd.widthHint= LayoutUtils.hintWidth((Text) this.localControl.getTextControl(), 60); |
| this.localControl.setLayoutData(gd); |
| } |
| { final Label label= new Label(composite, SWT.NONE); |
| label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); |
| label.setText("Remote &Host:"); |
| |
| this.hostControl= new Text(composite, SWT.BORDER | SWT.SINGLE); |
| this.hostControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
| } |
| { final Label label= new Label(composite, SWT.NONE); |
| label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); |
| label.setText("Path on &Remote:"); |
| |
| this.remoteControl= new Text(composite, SWT.BORDER | SWT.SINGLE); |
| this.remoteControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
| } |
| |
| applyDialogFont(area); |
| |
| return area; |
| } |
| |
| @Override |
| protected void addBindings(final DataBindingSupport db) { |
| db.getContext().bindValue( |
| this.localControl.getObservable(), |
| this.localValue, |
| new UpdateValueStrategy<String, String>() |
| .setAfterGetValidator(this.localControl.getValidator()), |
| null ); |
| db.getContext().bindValue( |
| WidgetProperties.text(SWT.Modify) |
| .observe(this.hostControl), |
| this.hostValue, |
| new UpdateValueStrategy<String, String>() |
| .setAfterGetValidator(new NotEmptyValidator("Missing host; it must be specified by its hostname or IP number.")), |
| null ); |
| db.getContext().bindValue( |
| WidgetProperties.text(SWT.Modify) |
| .observe(this.remoteControl), |
| this.remoteValue, |
| new UpdateValueStrategy<String, String>() |
| .setAfterGetValidator(new NotEmptyValidator("Missing remote path.")), |
| null ); |
| } |
| |
| public @Nullable ResourceMapping getResult() { |
| try { |
| return new ResourceMapping(this.mappingId, |
| this.localValue.getValue(), |
| this.hostValue.getValue(), |
| this.remoteValue.getValue() ); |
| } |
| catch (final CoreException e) { |
| return null; |
| } |
| } |
| |
| } |