/*******************************************************************************
* Copyright (c) 2012 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.wizard.template.util;
import java.net.URISyntaxException;
import java.util.List;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
/**
* @author Kaitlin Duck Sherwood
*/
// modified from ConfiguratorPreference, with some help from
// RuntimePreferencePage and SpringConfigPreferencePage
public abstract class AbstractNameUrlPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
protected Table table;
protected TableViewer tableViewer;
List<NameUrlPair> elements;
protected AbstractNameUrlPreferenceModel model;
private Button editButton;
private Button removeButton;
private Button optionalCheckbox;
protected abstract String preferencePageHeaderText();
protected abstract AbstractNameUrlPreferenceModel getModel();
protected abstract boolean shouldShowCheckbox();
protected abstract String checkboxLabel();
protected abstract String addDialogHeaderText();
protected abstract AddEditNameUrlDialog getAddEditDialog(NameUrlPair existingNameUrlPair);
public void init(IWorkbench workbench) {
setPreferenceStore(doGetPreferenceStore());
model = getModel();
}
@Override
public boolean performOk() {
boolean okay = super.performOk();
model.persist();
return okay;
}
@Override
public boolean performCancel() {
model.revert();
return true;
}
private NameUrlPair getSelectedNameUrlPair() {
StructuredSelection selectedTuple = (StructuredSelection) tableViewer.getSelection();
NameUrlPair pair = (NameUrlPair) selectedTuple.getFirstElement();
return pair;
}
@Override
protected Control createContents(Composite parent) {
initializeDialogUnits(parent);
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.horizontalSpacing = convertHorizontalDLUsToPixels(4);
layout.verticalSpacing = convertVerticalDLUsToPixels(3);
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.numColumns = 2;
composite.setLayout(layout);
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
composite.setLayoutData(data);
Label label = new Label(composite, SWT.WRAP);
data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
data.horizontalSpan = 2;
label.setLayoutData(data);
label.setText(preferencePageHeaderText());
table = new Table(composite, SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE);
GridLayoutFactory.fillDefaults().numColumns(2).applyTo(table);
GridDataFactory.fillDefaults().grab(true, true).applyTo(table);
table.setHeaderVisible(true);
tableViewer = new TableViewer(table); // was LockedTableViewer
tableViewer.setContentProvider(new NameUrlContentProvider());
tableViewer.setSorter(new NameUrlViewerSorter(true));
TableViewerColumn nameColumn = new TableViewerColumn(tableViewer, SWT.FILL);
TableColumn swtNameColumn = nameColumn.getColumn();
swtNameColumn.setText("name");
swtNameColumn.setWidth(50);
nameColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
org.springframework.ide.eclipse.wizard.template.util.NameUrlPair nameUrlPair = (NameUrlPair) element;
return nameUrlPair.getName();
}
});
nameColumn.getColumn().addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
tableViewer.setSorter(new NameUrlViewerSorter(true));
removeButton.setEnabled(false);
editButton.setEnabled(false);
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
});
TableViewerColumn urlColumn = new TableViewerColumn(tableViewer, SWT.FILL);
urlColumn.getColumn().setText("URL");
urlColumn.getColumn().setWidth(160);
urlColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
org.springframework.ide.eclipse.wizard.template.util.NameUrlPair nameUrlPair = (NameUrlPair) element;
return nameUrlPair.getUrlString();
}
});
urlColumn.getColumn().addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
tableViewer.setSorter(new NameUrlViewerSorter(false));
removeButton.setEnabled(false);
editButton.setEnabled(false);
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
});
tableViewer.setInput(model);
tableViewer.setColumnProperties(new String[] { "Name", "URL" });
tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
removeButton.setEnabled(true);
editButton.setEnabled(true);
}
});
// after adding an item do the packing of the table
if (table.getItemCount() > 0) {
TableColumn[] columns = table.getColumns();
for (TableColumn column : columns) {
column.pack();
}
table.pack();
}
Composite buttonComp = new Composite(composite, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).spacing(0, convertVerticalDLUsToPixels(3))
.applyTo(buttonComp);
GridDataFactory.fillDefaults().grab(false, true).applyTo(buttonComp);
Button addButton = new Button(buttonComp, SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, false).applyTo(addButton);
addButton.setText(NLS.bind("Add", null));
addButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent ev) {
AddEditNameUrlDialog dialog = getAddEditDialog(null);
if (dialog.open() == Dialog.OK) {
String urlString = dialog.getUrlString().trim().replaceAll("\\n", "");
if (urlString.endsWith("/")) {
urlString = urlString.substring(0, urlString.length() - 1);
}
// the validation of the URL is done in the dialog class
String name = dialog.getName();
if (name.length() > 0 && urlString.length() > 0) {
try {
model.addNameUrlPairInEncodedString(new NameUrlPair(name, urlString));
tableViewer.refresh();
}
catch (URISyntaxException e) {
// Errors in URL *should* be caught in the add/edit
// dialog, i.e. before getting to this point.
String message = NLS.bind(AddEditNameUrlDialogMessages.malformedUrlIgnoring, urlString);
MessageDialog.openError(getShell(), AddEditNameUrlDialogMessages.malformedUrl, message);
}
}
}
}
});
editButton = new Button(buttonComp, SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, false).applyTo(editButton);
editButton.setText(NLS.bind("Edit", null));
editButton.setEnabled(false);
editButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent ev) {
NameUrlPair oldNameUrl = getSelectedNameUrlPair();
AddEditNameUrlDialog dialog = getAddEditDialog(oldNameUrl);
if (dialog.open() == Dialog.OK) {
String urlString = dialog.getUrlString().trim().replaceAll("\\n", "");
if (urlString.endsWith("/")) {
urlString = urlString.substring(0, urlString.length() - 1);
}
String name = dialog.getName();
if (name.length() > 0 && urlString.length() > 0) {
try {
if (oldNameUrl != null) {
model.removeNameUrlPairInEncodedString(oldNameUrl);
}
model.addNameUrlPairInEncodedString(new NameUrlPair(name, urlString));
tableViewer.refresh();
// the tableViewer refresh deselects the line,
// so disable the buttons
editButton.setEnabled(false);
removeButton.setEnabled(false);
}
catch (URISyntaxException e) {
// Errors in URL *should* be caught in the add/edit
// dialog, i.e. before getting to this point.
String message = NLS.bind(AddEditNameUrlDialogMessages.malformedUrlIgnoring, urlString);
MessageDialog.openError(getShell(), AddEditNameUrlDialogMessages.malformedUrl, message);
}
}
}
}
});
removeButton = new Button(buttonComp, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, false).applyTo(removeButton);
removeButton.setText(NLS.bind("Remove", null));
removeButton.setEnabled(false);
removeButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
StructuredSelection selectedTuple = (StructuredSelection) tableViewer.getSelection();
NameUrlPair pair = (NameUrlPair) selectedTuple.getFirstElement(); // unencoded
NameUrlPair encodedPair;
try {
encodedPair = new NameUrlPair(pair.getName(), pair.getUrlString());
String title = NLS.bind("Are you sure?", null);
String message = NLS.bind(
"If you continue, {0} will be removed. Are you sure you want to remove {0}?",
pair.getName());
boolean answer = MessageDialog.openQuestion(getShell(), title, message);
if (answer) {
model.removeNameUrlPairInEncodedString(encodedPair);
tableViewer.remove(selectedTuple);
tableViewer.refresh();
editButton.setEnabled(false);
removeButton.setEnabled(false);
}
}
catch (URISyntaxException e1) {
// There should be no errors; checking happened on input
String errorTitle = NLS.bind("Internal error", null);
String errorMessage = NLS
.bind("This error was not expected. URL {0} was malformed when it was retrieved from the preferences properties",
pair.getUrlString());
;
MessageDialog.openError(getShell(), errorTitle, errorMessage);
}
}
});
if (shouldShowCheckbox()) {
optionalCheckbox = new Button(parent, SWT.CHECK | SWT.WRAP | SWT.BOTTOM);
GridDataFactory.fillDefaults().grab(true, false).applyTo(optionalCheckbox);
optionalCheckbox.setText(checkboxLabel());
optionalCheckbox.setEnabled(true);
optionalCheckbox.setSelection(model.getOptionalFlagValue());
optionalCheckbox.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
model.setOptionalFlagValue(optionalCheckbox.getSelection());
}
});
}
Dialog.applyDialogFont(composite);
return composite;
}
@Override
protected void performDefaults() {
model.clearNonDefaults();
tableViewer.refresh();
}
protected void updateSelection(ISelection selection) {
}
protected boolean getCheckboxValue() {
return optionalCheckbox.getSelection();
}
}