package com.redhat.ceylon.eclipse.code.style;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.swt.SWT;
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.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import ceylon.formatter.options.FormattingOptions;
import com.redhat.ceylon.eclipse.code.style.FormatterProfileManager.Profile;
import com.redhat.ceylon.eclipse.code.style.FormatterTabPage.ModificationListener;
import com.redhat.ceylon.eclipse.ui.CeylonPlugin;
public class FormatterModifyProfileDialog extends StatusDialog implements
ModificationListener {
private static final IStatus STATUS_OK = new Status(IStatus.OK, CeylonPlugin.PLUGIN_ID, null);
private final static String LAST_TAB_INDEX = CeylonPlugin.PLUGIN_ID
+ ".style.formatter_page.modify_dialog.last_focus_index";
private static final int APPLY_BUTTON_ID = IDialogConstants.CLIENT_ID;
private final boolean newProfile;
private final boolean projectSpecific;
private Profile profile;
private FormattingOptions workingValues;
private final List<FormatterTabPage> tabPages;
private TabFolder tabFolder;
private final FormatterProfileManager profileManager;
private Button applyButton;
private Button saveButton;
private StringDialogField profileNameField;
private int tabIndex;
public FormatterModifyProfileDialog(Shell parentShell, Profile profile,
FormatterProfileManager profileManager, boolean newProfile,
boolean projectSpecific) {
super(parentShell);
this.profileManager = profileManager;
this.newProfile = newProfile;
this.projectSpecific = projectSpecific;
this.profile = profile;
setTitle("Modify Formatter Profile \u2014 " + profile.getName());
this.workingValues = profile.getSettings();
setStatusLineAboveButtons(false);
this.tabPages = new ArrayList<FormatterTabPage>();
}
@Override
protected boolean isResizable() {
return true;
}
protected boolean isProjectSpecific() {
return this.projectSpecific;
}
protected void addPages(FormatterPreferences workingValues) {
addTabPage("Indentation", new FormatterTabIndent(this, workingValues));
addTabPage("Spacing", new FormatterTabSpace(this, workingValues));
addTabPage("Line and Line Breaks", new FormatterTabLine(this,
workingValues));
addTabPage("Miscellaneous", new FormatterTabMisc(this, workingValues));
}
@Override
public void create() {
super.create();
int lastFocusNr = 0;
try {
lastFocusNr = CeylonPlugin.getInstance().getDialogSettings()
.getInt(LAST_TAB_INDEX);
} catch (NumberFormatException e) {
// may not exist
}
if (!newProfile) {
tabFolder.setSelection(lastFocusNr);
}
}
@Override
protected Control createDialogArea(Composite parent) {
final Composite composite = (Composite) super.createDialogArea(parent);
Composite nameComposite = new Composite(composite, SWT.NONE);
nameComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
false));
nameComposite.setLayout(new GridLayout(3, false));
profileNameField = new StringDialogField();
profileNameField.setLabelText("Profile Name");
profileNameField.setText(profile.getName());
profileNameField.getLabelControl(nameComposite).setLayoutData(
new GridData(SWT.LEFT, SWT.CENTER, false, false));
profileNameField.getTextControl(nameComposite).setLayoutData(
new GridData(SWT.FILL, SWT.CENTER, true, false));
profileNameField.setDialogFieldListener(new IDialogFieldListener() {
public void dialogFieldChanged(DialogField field) {
doValidate();
}
});
profileNameField.setEnabled(false); // do not edit name when modifying
tabFolder = new TabFolder(composite, SWT.NONE);
tabFolder.setFont(composite.getFont());
tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
addPages(new FormatterPreferences(workingValues));
applyDialogFont(composite);
tabFolder.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
}
public void widgetSelected(SelectionEvent e) {
final TabItem tabItem = (TabItem) e.item;
final FormatterTabPage page = (FormatterTabPage) tabItem
.getData();
page.makeVisible();
tabIndex = tabPages.indexOf(page);
}
});
doValidate();
return composite;
}
@Override
public void updateStatus(IStatus status) {
if (status == null) {
doValidate();
} else {
super.updateStatus(status);
}
}
@Override
public boolean close() {
CeylonPlugin.getInstance().getDialogSettings()
.put(LAST_TAB_INDEX, tabIndex);
return super.close();
}
@Override
protected void okPressed() {
applyPressed();
super.okPressed();
}
@Override
protected void buttonPressed(int buttonId) {
if (buttonId == APPLY_BUTTON_ID) {
applyPressed();
setTitle("Modify Formatter Profile \u2014 " + profile.getName());
} else {
super.buttonPressed(buttonId);
}
}
private void applyPressed() {
if (!profile.getName().equals(profileNameField.getText())) {
profile = profile.rename(profileNameField.getText(),
this.profileManager);
}
profile.setSettings(workingValues, this.profileManager);
this.profileManager.setSelected(profile);
doValidate();
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
applyButton = createButton(parent, APPLY_BUTTON_ID, "Apply", false);
applyButton.setEnabled(false);
GridLayout layout = (GridLayout) parent.getLayout();
layout.numColumns++;
layout.makeColumnsEqualWidth = false;
Label label = new Label(parent, SWT.NONE);
GridData data = new GridData();
data.widthHint = layout.horizontalSpacing;
label.setLayoutData(data);
super.createButtonsForButtonBar(parent);
}
protected final void addTabPage(String title, FormatterTabPage tabPage) {
final TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
applyDialogFont(tabItem.getControl());
tabItem.setText(title);
tabItem.setData(tabPage);
tabItem.setControl(tabPage.createContents(tabFolder));
tabPages.add(tabPage);
}
public void valuesModified(FormatterPreferences prefs) {
doValidate();
this.workingValues = prefs.getOptions();
}
@Override
protected void updateButtonsEnableState(IStatus status) {
super.updateButtonsEnableState(status);
if (applyButton != null && !applyButton.isDisposed()) {
applyButton.setEnabled(hasChanges()
&& !status.matches(IStatus.ERROR));
}
if (this.saveButton != null && !this.saveButton.isDisposed()) {
this.saveButton.setEnabled(!validateProfileName().matches(
IStatus.ERROR));
}
}
private void doValidate() {
String name = profileNameField.getText().trim();
if (name.equals(profile.getName())
&& profile.hasEqualSettings(workingValues)) {
updateStatus(STATUS_OK);
return;
}
IStatus status = validateProfileName();
if (status.matches(IStatus.ERROR)) {
updateStatus(status);
return;
}
if (!name.equals(profile.getName())
&& this.profileManager.containsName(name)) {
updateStatus(new Status(IStatus.ERROR, CeylonPlugin.PLUGIN_ID,
"Duplicate"));
return;
}
if (profile.isBuiltInProfile()) {
updateStatus(new Status(IStatus.INFO, CeylonPlugin.PLUGIN_ID,
"New Created"));
return;
}
updateStatus(STATUS_OK);
}
private IStatus validateProfileName() {
final String name = profileNameField.getText().trim();
if (profile.isBuiltInProfile()) {
if (profile.getName().equals(name)) {
return new Status(IStatus.ERROR, CeylonPlugin.PLUGIN_ID,
"Built-in");
}
}
if (name.length() == 0) {
return new Status(IStatus.ERROR, CeylonPlugin.PLUGIN_ID,
"Empty Name");
}
return STATUS_OK;
}
private boolean hasChanges() {
if (!profileNameField.getText().trim().equals(profile.getName())) {
return true;
}
if (!workingValues.equals(profile.getSettings())) {
return true;
}
return false;
}
}