blob: 1a7a7b2efe91188c13b4033c66e3c605f25a316b [file] [log] [blame]
/*
* Copyright (c) 2011 Google 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
*/
package com.google.eclipse.protobuf.ui.preferences.paths;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.eclipse.protobuf.ui.preferences.pages.ButtonGroup.with;
import static com.google.eclipse.protobuf.ui.preferences.pages.binding.BindingToButtonSelection.bindSelectionOf;
import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.errorNoDirectoryNames;
import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.filesInMultipleDirectories;
import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.filesInOneDirectoryOnly;
import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.importedFilesPathResolution;
import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.rebuildProjectNow;
import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.settingsChanged;
import static com.google.eclipse.protobuf.ui.preferences.paths.PreferenceNames.DIRECTORY_PATHS;
import static com.google.eclipse.protobuf.ui.preferences.paths.PreferenceNames.FILES_IN_MULTIPLE_DIRECTORIES;
import static com.google.eclipse.protobuf.ui.preferences.paths.PreferenceNames.FILES_IN_ONE_DIRECTORY_ONLY;
import static com.google.eclipse.protobuf.ui.util.IStatusFactory.error;
import static java.util.Collections.unmodifiableList;
import static org.eclipse.core.resources.IncrementalProjectBuilder.FULL_BUILD;
import static org.eclipse.core.runtime.Status.OK_STATUS;
import static org.eclipse.core.runtime.jobs.Job.BUILD;
import static org.eclipse.xtext.util.Strings.concat;
import static org.eclipse.xtext.util.Strings.isEmpty;
import static org.eclipse.xtext.util.Strings.split;
import com.google.eclipse.protobuf.ui.preferences.pages.DataChangedListener;
import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage;
import com.google.eclipse.protobuf.ui.preferences.pages.binding.Binding;
import com.google.eclipse.protobuf.ui.preferences.pages.binding.Preference;
import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceBinder;
import com.google.eclipse.protobuf.ui.preferences.pages.binding.PreferenceFactory;
import com.google.eclipse.protobuf.ui.validation.ValidationTrigger;
import com.google.inject.Inject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Group;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.xtext.ui.PluginImageHelper;
import java.util.List;
/**
* Preference page for locations of import paths and descriptor.proto.
*
* @author alruiz@google.com (Alex Ruiz)
*/
public class PathsPreferencePage extends PreferenceAndPropertyPage {
private static final String COMMA_DELIMITER = ",";
private static final String PREFERENCE_PAGE_ID = PathsPreferencePage.class.getName();
private Group grpResolutionOfImported;
private Button btnOneDirectoryOnly;
private Button btnMultipleDirectories;
private DirectoryPathsEditor directoryPathsEditor;
@Inject private PluginImageHelper imageHelper;
@Inject private ValidationTrigger validation;
private boolean stateChanged;
@Override protected Composite contentParent(Composite parent) {
Composite contents = new Composite(parent, SWT.NONE);
contents.setLayout(new GridLayout(2, false));
return contents;
}
@Override protected void doCreateContents(Composite parent) {
// generated by WindowBuilder
grpResolutionOfImported = new Group(parent, SWT.NONE);
grpResolutionOfImported.setLayout(new GridLayout(1, false));
grpResolutionOfImported.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
grpResolutionOfImported.setText(importedFilesPathResolution);
btnOneDirectoryOnly = new Button(grpResolutionOfImported, SWT.RADIO);
btnOneDirectoryOnly.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
btnOneDirectoryOnly.setText(filesInOneDirectoryOnly);
btnMultipleDirectories = new Button(grpResolutionOfImported, SWT.RADIO);
btnMultipleDirectories.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
btnMultipleDirectories.setText(filesInMultipleDirectories);
directoryPathsEditor = new DirectoryPathsEditor(grpResolutionOfImported, project(), imageHelper);
directoryPathsEditor.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
addEventListeners();
}
private void addEventListeners() {
with(btnOneDirectoryOnly, btnMultipleDirectories).add(new SelectionAdapter() {
@Override public void widgetSelected(SelectionEvent e) {
boolean selected = btnMultipleDirectories.getSelection();
directoryPathsEditor.setEnabled(selected);
checkState();
}
});
directoryPathsEditor.setDataChangedListener(new DataChangedListener() {
@Override public void dataChanged() {
checkState();
}
});
}
private void checkState() {
stateChanged = true;
if (directoryPathsEditor.isEnabled() && directoryPathsEditor.directoryPaths().isEmpty()) {
pageIsNowInvalid(errorNoDirectoryNames);
return;
}
pageIsNowValid();
}
@Override protected String enableProjectSettingsPreferenceName() {
return null; // this page is always a "Project Properties" page
}
@Override protected void setupBinding(PreferenceBinder binder, PreferenceFactory factory) {
binder.addAll(
bindSelectionOf(btnOneDirectoryOnly).to(factory.newBooleanPreference(FILES_IN_ONE_DIRECTORY_ONLY)),
bindSelectionOf(btnMultipleDirectories).to(factory.newBooleanPreference(FILES_IN_MULTIPLE_DIRECTORIES))
);
final Preference<String> directoryPaths = factory.newStringPreference(DIRECTORY_PATHS);
binder.add(new Binding() {
@Override public void applyPreferenceValueToTarget() {
setDirectoryPaths(directoryPaths.value());
}
@Override public void applyDefaultPreferenceValueToTarget() {
setDirectoryPaths(directoryPaths.defaultValue());
}
@Override public void savePreferenceValue() {
directoryPaths.updateValue(directoryNames());
}
});
}
private String directoryNames() {
List<String> paths = directoryPathsEditor.directoryPaths();
if (paths.isEmpty())
{
return "";
}
return concat(COMMA_DELIMITER, paths);
}
private void setDirectoryPaths(String directoryPaths) {
List<String> paths = newArrayList();
for (String path : split(directoryPaths, COMMA_DELIMITER)) {
if (!isEmpty(path)) {
paths.add(path);
}
}
directoryPathsEditor.directoryPaths(unmodifiableList(paths));
}
/** {@inheritDoc} */
@Override protected void onProjectSettingsActivation(boolean active) {
enableProjectOptions(active);
}
@Override protected void updateContents() {
enableProjectOptions(true);
}
private void enableProjectOptions(boolean enabled) {
grpResolutionOfImported.setEnabled(enabled);
btnOneDirectoryOnly.setEnabled(enabled);
btnMultipleDirectories.setEnabled(enabled);
directoryPathsEditor.setEnabled(btnMultipleDirectories.getSelection() && enabled);
}
@Override protected String preferencePageId() {
return PREFERENCE_PAGE_ID;
}
@Override protected void okPerformed() {
// TODO check threading
if (!stateChanged) {
return;
}
stateChanged = false;
if (shouldRebuild()) {
rebuildProject();
return;
}
validation.validateOpenEditors(project());
}
private boolean shouldRebuild() {
MessageBox messageBox = new MessageBox(getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
messageBox.setText(settingsChanged);
messageBox.setMessage(rebuildProjectNow);
return messageBox.open() == SWT.YES;
}
private void rebuildProject() {
Job job = new Job("Rebuilding project") {
@Override protected IStatus run(IProgressMonitor monitor) {
try {
project().build(FULL_BUILD, monitor);
} catch (CoreException e) {
return error(e);
}
return OK_STATUS;
}
};
job.setPriority(BUILD);
job.schedule(); // start as soon as possible
}
}