/*
* SonarLint for Eclipse
* Copyright (C) 2015-2017 SonarSource SA
* sonarlint@sonarsource.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonarlint.eclipse.ui.internal.properties;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
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.sonarlint.eclipse.core.internal.resources.SonarLintProperty;
import org.sonarlint.eclipse.ui.internal.SonarLintUiPlugin;
public class EditSonarPropertyDialog extends StatusDialog {
private SonarLintProperty sonarProperty;
private Text fNameText;
private Text fValueText;
private StatusInfo fValidationStatus;
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=4354
private boolean fSuppressError = true;
private boolean fIsNameModifiable;
/**
* Creates a new dialog.
*
* @param parent the shell parent of the dialog
* @param property the property to edit
* @param edit whether this is a new property or an existing being edited
* @param isNameModifiable whether the name of the property may be modified
*/
public EditSonarPropertyDialog(Shell parent, SonarLintProperty property, boolean edit, boolean isNameModifiable) {
super(parent);
String title = edit
? "Edit property"
: "New property";
setTitle(title);
sonarProperty = property;
fIsNameModifiable = isNameModifiable;
fValidationStatus = new StatusInfo();
}
@Override
protected boolean isResizable() {
return true;
}
@Override
public void create() {
super.create();
updateStatusAndButtons();
getButton(IDialogConstants.OK_ID).setEnabled(getStatus().isOK());
}
@Override
protected Control createDialogArea(Composite ancestor) {
Composite parent = new Composite(ancestor, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
parent.setLayout(layout);
parent.setLayoutData(new GridData(GridData.FILL_BOTH));
createLabel(parent, "Name:");
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
layout = new GridLayout();
layout.numColumns = 1;
layout.marginWidth = 0;
layout.marginHeight = 0;
composite.setLayout(layout);
fNameText = createNameText(composite);
if (fIsNameModifiable) {
fNameText.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
// Nothing to do
}
@Override
public void focusLost(FocusEvent e) {
if (fSuppressError) {
fSuppressError = false;
updateStatusAndButtons();
}
}
});
} else {
fNameText.setEditable(false);
}
createLabel(parent, "Value:");
fValueText = new Text(parent, SWT.BORDER);
fValueText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
fValueText.setText(sonarProperty.getValue());
fNameText.setText(sonarProperty.getName());
if (fIsNameModifiable) {
fNameText.addModifyListener(e -> {
fSuppressError = false;
updateStatusAndButtons();
});
}
applyDialogFont(parent);
return parent;
}
private static Label createLabel(Composite parent, String name) {
Label label = new Label(parent, SWT.NULL);
label.setText(name);
label.setLayoutData(new GridData());
return label;
}
private Text createNameText(Composite parent) {
int descFlags = fIsNameModifiable ? SWT.BORDER : (SWT.BORDER | SWT.READ_ONLY);
Text text = new Text(parent, descFlags);
final GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.widthHint = convertWidthInCharsToPixels(20);
text.setLayoutData(gd);
return text;
}
@Override
protected void okPressed() {
String name = fNameText == null ? sonarProperty.getName() : fNameText.getText();
sonarProperty = new SonarLintProperty(name, fValueText.getText());
super.okPressed();
}
private void updateStatusAndButtons() {
StatusInfo status = fValidationStatus;
boolean isEmpty = fNameText != null && fNameText.getText().length() == 0;
if (!fSuppressError && isEmpty) {
status = new StatusInfo();
status.setError("Please input a name");
} else if (fNameText != null && !isValidPropertyName(fNameText.getText())) {
status = new StatusInfo();
status.setError("Invalid property name");
}
updateStatus(status);
}
/**
* Checks whether the given string is a valid
* property name.
*
* @param name the string to test
* @return <code>true</code> if the name is valid
*/
private static boolean isValidPropertyName(String name) {
return !name.contains(" ");
}
/**
* Returns the created property.
*
* @return the created property
*/
public SonarLintProperty getSonarProperty() {
return sonarProperty;
}
@Override
protected Point getInitialSize() {
Point defaultSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
Point restoredSize = super.getInitialSize();
if (defaultSize.x > restoredSize.x) {
restoredSize.x = defaultSize.x;
}
return restoredSize;
}
@Override
protected IDialogSettings getDialogBoundsSettings() {
String sectionName = getClass().getName() + "_dialogBounds"; //$NON-NLS-1$
IDialogSettings settings = SonarLintUiPlugin.getDefault().getDialogSettings();
IDialogSettings section = settings.getSection(sectionName);
if (section == null) {
section = settings.addNewSection(sectionName);
}
return section;
}
}