In progress: [ Issue 40 ] Add support for import resolution across multiple
folders
https://code.google.com/p/protobuf-dt/issues/detail?id=40
Replaced text field with list for names of directories to be included in URI resolution. Code cleanup.
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver_resolveUri_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver_resolveUri_Test.java
deleted file mode 100644
index 9a41d2e..0000000
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver_resolveUri_Test.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.scoping;
-
-import static com.google.eclipse.protobuf.ui.preferences.paths.PathResolutionType.SINGLE_DIRECTORY;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.*;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.junit.*;
-
-import com.google.eclipse.protobuf.junit.core.XtextRule;
-import com.google.eclipse.protobuf.junit.stubs.ResourceStub;
-import com.google.eclipse.protobuf.scoping.IFileUriResolver;
-import com.google.eclipse.protobuf.ui.preferences.paths.*;
-import com.google.inject.*;
-
-/**
- * Tests for <code>{@link FileUriResolver#resolveUri(String, Resource)}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class FileUriResolver_resolveUri_Test {
-
- @Rule public XtextRule xtext = new XtextRule();
-
- private Resource resource;
- private PathsPreferenceReader preferenceReader;
- private PathsPreferences preferences;
- private IProject project;
- private Resources resources;
-
- private FileUriResolver resolver;
-
- @Before public void setUp() {
- resource = new ResourceStub("platform:/resource/src/proto/person.proto");
- preferenceReader = mock(PathsPreferenceReader.class);
- preferences = mock(PathsPreferences.class);
- project = mock(IProject.class);
- resources = mock(Resources.class);
- Module module = new Module() {
- public void configure(Binder binder) {
- binder.bind(PathsPreferenceReader.class).toInstance(preferenceReader);
- binder.bind(Resources.class).toInstance(resources);
- binder.bind(IFileUriResolver.class).to(FileUriResolver.class);
- }
- };
- Injector injector = xtext.injector().createChildInjector(module);
- resolver = (FileUriResolver) injector.getInstance(IFileUriResolver.class);
- }
-
- @Test public void should_resolve_import_URI_if_missing_scheme() {
- callStubs(SINGLE_DIRECTORY, true);
- String resolved = resolver.resolveUri("folder1/address.proto", resource);
- assertThat(resolved, equalTo("platform:/resource/src/proto/folder1/address.proto"));
- }
-
- @Test public void should_not_resolve_import_URI_if_not_missing_scheme() {
- callStubs(SINGLE_DIRECTORY, true);
- String original = "platform:/resource/src/proto/folder1/address.proto";
- String resolved = resolver.resolveUri(original, resource);
- assertThat(resolved, equalTo(original));
- }
-
- @Test public void should_resolve_import_URI_even_if_overlapping_folders_with_resource_URI() {
- callStubs(SINGLE_DIRECTORY, true);
- String resolved = resolver.resolveUri("src/proto/folder1/address.proto", resource);
- assertThat(resolved, equalTo("platform:/resource/src/proto/folder1/address.proto"));
- }
-
- @Test public void should_resolve_import_URI_even_if_overlapping_one_folder_only_with_resource_URI() {
- callStubs(SINGLE_DIRECTORY, true);
- String resolved = resolver.resolveUri("src/proto/read-only/address.proto", resource);
- assertThat(resolved, equalTo("platform:/resource/src/proto/read-only/address.proto"));
- }
-
- private void callStubs(PathResolutionType type, boolean resolvedUriExists) {
- when(resources.project(resource.getURI())).thenReturn(project);
- when(preferenceReader.readFromPrefereceStore(project)).thenReturn(preferences);
- when(preferences.pathResolutionType()).thenReturn(type);
- when(resources.fileExists(any(URI.class))).thenReturn(resolvedUriExists);
- }
-}
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolver_resolveUri_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolver_resolveUri_Test.java
new file mode 100644
index 0000000..c1fc418
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/SingleDirectoryFileResolver_resolveUri_Test.java
@@ -0,0 +1,65 @@
+/*
+ * 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.scoping;
+
+import static org.eclipse.emf.common.util.URI.createURI;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.*;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.emf.common.util.URI;
+import org.junit.*;
+
+import com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferences;
+
+/**
+ * Tests for <code>{@link SingleDirectoryFileResolver#resolveUri(String, URI, PathsPreferences, IProject)}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class SingleDirectoryFileResolver_resolveUri_Test {
+
+ private static URI resourceUri;
+ private static PathsPreferences preferences;
+ private static IProject project;
+
+ @BeforeClass public static void setUpOnce() {
+ resourceUri = createURI("platform:/resource/src/proto/person.proto");
+ preferences = mock(PathsPreferences.class);
+ project = mock(IProject.class);
+ }
+
+ private Resources resources;
+ private SingleDirectoryFileResolver resolver;
+
+ @Before public void setUp() {
+ resources = mock(Resources.class);
+ resolver = new SingleDirectoryFileResolver(resources);
+ }
+
+ @Test public void should_resolve_import_URI_if_missing_scheme() {
+ when(resources.fileExists(any(URI.class))).thenReturn(true);
+ String resolved = resolver.resolveUri("folder1/address.proto", resourceUri, preferences, project);
+ assertThat(resolved, equalTo("platform:/resource/src/proto/folder1/address.proto"));
+ }
+
+ @Test public void should_resolve_import_URI_even_if_overlapping_folders_with_resource_URI() {
+ when(resources.fileExists(any(URI.class))).thenReturn(true);
+ String resolved = resolver.resolveUri("src/proto/folder1/address.proto", resourceUri, preferences, project);
+ assertThat(resolved, equalTo("platform:/resource/src/proto/folder1/address.proto"));
+ }
+
+ @Test public void should_resolve_import_URI_even_if_overlapping_one_folder_only_with_resource_URI() {
+ when(resources.fileExists(any(URI.class))).thenReturn(true);
+ String resolved = resolver.resolveUri("src/proto/read-only/address.proto", resourceUri, preferences, project);
+ assertThat(resolved, equalTo("platform:/resource/src/proto/read-only/address.proto"));
+ }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CompilerPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CompilerPreferencePage.java
index f8fd406..8f12479 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CompilerPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/compiler/CompilerPreferencePage.java
@@ -8,24 +8,21 @@
*/
package com.google.eclipse.protobuf.ui.preferences.compiler;
-import static com.google.eclipse.protobuf.ui.preferences.compiler.Messages.*;
import static com.google.eclipse.protobuf.ui.preferences.compiler.CompilerPreferenceNames.*;
-import static org.eclipse.core.runtime.IStatus.OK;
+import static com.google.eclipse.protobuf.ui.preferences.compiler.Messages.*;
import static org.eclipse.xtext.util.Strings.isEmpty;
import java.io.File;
-import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
import com.google.eclipse.protobuf.ui.preferences.PreferenceAndPropertyPage;
-import com.google.eclipse.protobuf.ui.util.FolderNameValidator;
+import com.google.eclipse.protobuf.ui.util.DirectoryNameValidator;
import com.google.inject.Inject;
/**
@@ -59,8 +56,8 @@
private Button btnRefreshOutputFolder;
private Label lblOutputFolderRelative;
- @Inject private FolderNameValidator folderNameValidator;
-
+ @Inject private DirectoryNameValidator directoryNameValidator;
+
@Inject public CompilerPreferencePage(IPreferenceStoreAccess preferenceStoreAccess) {
super(preferenceStoreAccess);
}
@@ -231,9 +228,9 @@
pageIsNowInvalid(errorNoOutputFolderName);
return;
}
- IStatus validFolderName = folderNameValidator.validateFolderName(folderName);
- if (validFolderName.getCode() != OK) {
- pageIsNowInvalid(validFolderName.getMessage());
+ String invalidDirectoryName = directoryNameValidator.validateDirectoryName(folderName);
+ if (invalidDirectoryName != null) {
+ pageIsNowInvalid(invalidDirectoryName);
return;
}
if (!customPathOptionSelectedAndEnabled()) {
@@ -278,7 +275,7 @@
enableCompilerOptions(enableCompilerOptions);
super.performDefaults();
}
-
+
/** {@inheritDoc} */
@Override protected void onProjectSettingsActivation(boolean active) {
enableProjectSpecificOptions(active);
@@ -358,7 +355,7 @@
store.setValue(REFRESH_PROJECT, btnRefreshProject.getSelection());
store.setValue(REFRESH_OUTPUT_FOLDER, btnRefreshOutputFolder.getSelection());
}
-
+
/** {@inheritDoc} */
@Override protected String preferencePageId() {
return PREFERENCE_PAGE_ID;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectoryNamesEditor.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectoryNamesEditor.java
new file mode 100644
index 0000000..f056d89
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/DirectoryNamesEditor.java
@@ -0,0 +1,176 @@
+/*
+ * 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.eclipse.protobuf.ui.preferences.paths.Messages.*;
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+import static org.eclipse.jface.window.Window.OK;
+import static org.eclipse.xtext.util.Strings.isEmpty;
+
+import java.util.Collection;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import com.google.eclipse.protobuf.ui.util.DirectoryNameValidator;
+
+/**
+ * Editor where users can add/remove the directories to be used for URI resolution.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class DirectoryNamesEditor extends Composite {
+
+ private final DirectoryNameValidator directoryNameValidator;
+
+ private List lstDirectoryNames;
+ private final Button btnAdd;
+ private final Button btnRemove;
+ private final Button btnUp;
+ private final Button btnDown;
+
+ private SelectionListener onRemoveListener;
+
+ /**
+ * Creates a new </code>{@link DirectoryNamesEditor}</code>.
+ * @param parent a widget which will be the parent of the new instance (cannot be {@code null}.)
+ * @param directoryNameValidator validates that a {@code String} is a valid directory name.
+ */
+ public DirectoryNamesEditor(Composite parent, DirectoryNameValidator directoryNameValidator) {
+ super(parent, SWT.NONE);
+ this.directoryNameValidator = directoryNameValidator;
+ setLayout(new GridLayout(3, false));
+
+ lstDirectoryNames = new List(this, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
+ lstDirectoryNames.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+
+ Composite composite = new Composite(this, SWT.NONE);
+ composite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
+ composite.setLayout(new GridLayout(1, false));
+
+ btnAdd = new Button(composite, SWT.NONE);
+ btnAdd.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ btnAdd.setText(add);
+
+ btnRemove = new Button(composite, SWT.NONE);
+ btnRemove.setEnabled(false);
+ btnRemove.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ btnRemove.setText(remove);
+
+ btnUp = new Button(composite, SWT.NONE);
+ btnUp.setEnabled(false);
+ btnUp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ btnUp.setText(up);
+
+ btnDown = new Button(composite, SWT.NONE);
+ btnDown.setEnabled(false);
+ btnDown.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ btnDown.setText(down);
+
+ addEventListeners();
+ }
+
+ private void addEventListeners() {
+ lstDirectoryNames.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ lstDirectoryNames = null;
+ }
+ });
+ lstDirectoryNames.addSelectionListener(new SelectionAdapter() {
+ @Override public void widgetSelected(SelectionEvent e) {
+ enableButtonsDependingOnListSelection();
+ }
+ });
+ btnAdd.addSelectionListener(new SelectionAdapter() {
+ @Override public void widgetSelected(SelectionEvent e) {
+ IInputValidator validator = new IInputValidator() {
+ public String isValid(String newText) {
+ if (isEmpty(newText)) return Messages.errorEmptyDirectoryName;
+ return directoryNameValidator.validateDirectoryName(newText);
+ }
+ };
+ InputDialog input = new InputDialog(getShell(), directoryNameInputTitle, directoryNameInputMessage, null, validator);
+ if (input.open() == OK) {
+ lstDirectoryNames.add(input.getValue());
+ }
+ }
+ });
+ btnRemove.addSelectionListener(new SelectionAdapter() {
+ @Override public void widgetSelected(SelectionEvent e) {
+ int index = lstDirectoryNames.getSelectionIndex();
+ if (index < 0) return;
+ lstDirectoryNames.remove(index);
+ enableButtonsDependingOnListSelection();
+ }
+ });
+ btnUp.addSelectionListener(new SelectionAdapter() {
+ @Override public void widgetSelected(SelectionEvent e) {
+ swap(true);
+ }
+ });
+ btnDown.addSelectionListener(new SelectionAdapter() {
+ @Override public void widgetSelected(SelectionEvent e) {
+ swap(false);
+ }
+ });
+ }
+
+ private void swap(boolean goUp) {
+ int index = lstDirectoryNames.getSelectionIndex();
+ if (index < 0) return;
+ int target = goUp ? index - 1 : index + 1;
+ String[] selection = lstDirectoryNames.getSelection();
+ lstDirectoryNames.remove(index);
+ lstDirectoryNames.add(selection[0], target);
+ lstDirectoryNames.setSelection(target);
+ enableButtonsDependingOnListSelection();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ lstDirectoryNames.setEnabled(enabled);
+ btnAdd.setEnabled(enabled);
+ if (enabled) {
+ enableButtonsDependingOnListSelection();
+ } else {
+ btnRemove.setEnabled(false);
+ btnUp.setEnabled(false);
+ btnDown.setEnabled(false);
+ }
+ }
+
+ private void enableButtonsDependingOnListSelection() {
+ int selectionIndex = lstDirectoryNames.getSelectionIndex();
+ int size = lstDirectoryNames.getItemCount();
+ boolean hasSelection = selectionIndex >= 0;
+ btnRemove.setEnabled(hasSelection);
+ boolean hasElements = size > 1;
+ btnUp.setEnabled(hasElements && selectionIndex > 0);
+ btnDown.setEnabled(hasElements && hasSelection && selectionIndex < size - 1);
+ }
+
+ public java.util.List<String> directoryNames() {
+ return unmodifiableList(asList(lstDirectoryNames.getItems()));
+ }
+
+ public void addDirectoryNames(Collection<String> directoryNames) {
+ for (String name : directoryNames) lstDirectoryNames.add(name);
+ }
+
+ public void onRemove(SelectionListener listener) {
+ if (onRemoveListener != null) lstDirectoryNames.removeSelectionListener(onRemoveListener);
+ onRemoveListener = listener;
+ lstDirectoryNames.addSelectionListener(onRemoveListener);
+ }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.java
index 83e2534..ef56359 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.java
@@ -14,12 +14,18 @@
* @author alruiz@google.com (Alex Ruiz)
*/
public class Messages extends NLS {
-
- public static String directoryNameHint;
+
+ public static String add;
+ public static String directoryNameInputMessage;
+ public static String directoryNameInputTitle;
+ public static String down;
+ public static String errorEmptyDirectoryName;
public static String errorNoDirectoryNames;
public static String filesInMultipleDirectories;
public static String filesInOneDirectoryOnly;
public static String importedFilesPathResolution;
+ public static String remove;
+ public static String up;
static {
Class<Messages> targetType = Messages.class;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.properties
index 8424e7e..0322aa3 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.properties
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/Messages.properties
@@ -1,5 +1,11 @@
-directoryNameHint=*comma-separated values (e.g. 'src, src-gen, src-readonly')
-errorNoDirectoryNames=Enter the name of the directories
-filesInMultipleDirectories=Look for imported files in directories:*
+add=&Add
+directoryNameInputMessage=Enter directory name:
+directoryNameInputTitle=Path Resolution
+down=&Down
+errorEmptyDirectoryName=The name of the directory should not be empty
+errorNoDirectoryNames=Enter the names of the directories
+filesInMultipleDirectories=Look for imported files in directories:
filesInOneDirectoryOnly=One directory for all .proto files
importedFilesPathResolution=Path resolution of imported files
+remove=&Remove
+up=&Up
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferencePage.java
index de99706..c2789e0 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/paths/PathsPreferencePage.java
@@ -10,38 +10,35 @@
import static com.google.eclipse.protobuf.ui.preferences.paths.Messages.*;
import static com.google.eclipse.protobuf.ui.preferences.paths.PathsPreferenceNames.*;
-import static com.google.eclipse.protobuf.ui.util.Strings.CSV_PATTERN;
-import static org.eclipse.core.runtime.IStatus.OK;
-import static org.eclipse.xtext.util.Strings.isEmpty;
+import static org.eclipse.xtext.util.Strings.*;
-import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
import com.google.eclipse.protobuf.ui.preferences.PreferenceAndPropertyPage;
-import com.google.eclipse.protobuf.ui.util.FolderNameValidator;
+import com.google.eclipse.protobuf.ui.util.DirectoryNameValidator;
import com.google.inject.Inject;
/**
* Preference page for import paths.
- *
+ *
* @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 btnOneFolderOnly;
private Button btnMultipleFolders;
- private Text txtFolderNames;
+ private DirectoryNamesEditor directoryNamesEditor;
- @Inject private FolderNameValidator folderNameValidator;
+ @Inject private DirectoryNameValidator directoryNameValidator;
@Inject public PathsPreferencePage(IPreferenceStoreAccess preferenceStoreAccess) {
super(preferenceStoreAccess);
@@ -51,30 +48,27 @@
@Override protected Control createContents(Composite parent) {
// generated by WindowBuilder
Composite contents = contentsComposite(parent);
-
+
grpResolutionOfImported = new Group(contents, SWT.NONE);
grpResolutionOfImported.setLayout(new GridLayout(1, false));
grpResolutionOfImported.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
grpResolutionOfImported.setText(importedFilesPathResolution);
-
+
btnOneFolderOnly = new Button(grpResolutionOfImported, SWT.RADIO);
btnOneFolderOnly.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
btnOneFolderOnly.setText(filesInOneDirectoryOnly);
-
+
btnMultipleFolders = new Button(grpResolutionOfImported, SWT.RADIO);
btnMultipleFolders.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
btnMultipleFolders.setText(filesInMultipleDirectories);
-
- txtFolderNames = new Text(grpResolutionOfImported, SWT.BORDER);
- txtFolderNames.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-
- Label label = new Label(grpResolutionOfImported, SWT.NONE);
- label.setText(directoryNameHint);
+
+ directoryNamesEditor = new DirectoryNamesEditor(grpResolutionOfImported, directoryNameValidator);
+ directoryNamesEditor.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
new Label(contents, SWT.NONE);
-
+
updateFromPreferenceStore();
addEventListeners();
-
+
return contents;
}
@@ -82,7 +76,7 @@
IPreferenceStore store = doGetPreferenceStore();
btnOneFolderOnly.setSelection(store.getBoolean(FILES_IN_ONE_DIRECTORY_ONLY));
btnMultipleFolders.setSelection(store.getBoolean(FILES_IN_MULTIPLE_DIRECTORIES));
- txtFolderNames.setText(store.getString(DIRECTORY_NAMES));
+ setDirectoryNames(store.getString(DIRECTORY_NAMES));
boolean shouldEnablePathsOptions = true;
if (isPropertyPage()) {
boolean useProjectSettings = store.getBoolean(ENABLE_PROJECT_SETTINGS);
@@ -96,35 +90,25 @@
addSelectionListener(new SelectionAdapter() {
@Override public void widgetSelected(SelectionEvent e) {
boolean selected = btnMultipleFolders.getSelection();
- txtFolderNames.setEnabled(selected);
+ directoryNamesEditor.setEnabled(selected);
checkState();
}
}, btnOneFolderOnly, btnMultipleFolders);
- txtFolderNames.addModifyListener(new ModifyListener() {
- public void modifyText(ModifyEvent e) {
+ directoryNamesEditor.onRemove(new SelectionAdapter() {
+ @Override public void widgetSelected(SelectionEvent e) {
checkState();
}
});
}
private void checkState() {
- if (txtFolderNames.isEnabled()) {
- String folderNames = txtFolderNames.getText().trim();
- if (isEmpty(folderNames)) {
- pageIsNowInvalid(errorNoDirectoryNames);
- return;
- }
- for (String folderName : folderNames.split(CSV_PATTERN)) {
- IStatus validFolderName = folderNameValidator.validateFolderName(folderName);
- if (validFolderName.getCode() != OK) {
- pageIsNowInvalid(validFolderName.getMessage());
- return;
- }
- }
+ if (directoryNamesEditor.isEnabled() && directoryNamesEditor.directoryNames().isEmpty()) {
+ pageIsNowInvalid(errorNoDirectoryNames);
+ return;
}
pageIsNowValid();
}
-
+
/** {@inheritDoc} */
@Override protected void onProjectSettingsActivation(boolean active) {
enableProjectOptions(active);
@@ -134,7 +118,7 @@
IPreferenceStore store = doGetPreferenceStore();
btnOneFolderOnly.setSelection(store.getDefaultBoolean(FILES_IN_ONE_DIRECTORY_ONLY));
btnMultipleFolders.setSelection(store.getDefaultBoolean(FILES_IN_MULTIPLE_DIRECTORIES));
- txtFolderNames.setText(store.getDefaultString(DIRECTORY_NAMES));
+ setDirectoryNames(store.getDefaultString(DIRECTORY_NAMES));
boolean shouldEnablePathsOptions = true;
if (isPropertyPage()) {
boolean useProjectSettings = store.getDefaultBoolean(ENABLE_PROJECT_SETTINGS);
@@ -144,21 +128,29 @@
enableProjectOptions(shouldEnablePathsOptions);
super.performDefaults();
}
-
+
+ private void setDirectoryNames(String directoryNames) {
+ directoryNamesEditor.addDirectoryNames(split(directoryNames, COMMA_DELIMITER));
+ }
+
private void enableProjectOptions(boolean enabled) {
grpResolutionOfImported.setEnabled(enabled);
btnOneFolderOnly.setEnabled(enabled);
btnMultipleFolders.setEnabled(enabled);
- txtFolderNames.setEnabled(btnMultipleFolders.getSelection() && enabled);
+ directoryNamesEditor.setEnabled(btnMultipleFolders.getSelection() && enabled);
}
-
+
/** {@inheritDoc} */
@Override protected void savePreferences() {
IPreferenceStore store = getPreferenceStore();
if (isPropertyPage()) store.setValue(ENABLE_PROJECT_SETTINGS, areProjectSettingsActive());
store.setValue(FILES_IN_ONE_DIRECTORY_ONLY, btnOneFolderOnly.getSelection());
store.setValue(FILES_IN_MULTIPLE_DIRECTORIES, btnMultipleFolders.getSelection());
- store.setValue(DIRECTORY_NAMES, txtFolderNames.getText().trim());
+ store.setValue(DIRECTORY_NAMES, directoryNames());
+ }
+
+ private String directoryNames() {
+ return concat(COMMA_DELIMITER, directoryNamesEditor.directoryNames());
}
/** {@inheritDoc} */
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/FolderNameValidator.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/DirectoryNameValidator.java
similarity index 66%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/FolderNameValidator.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/DirectoryNameValidator.java
index 752099b..bf5253d 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/FolderNameValidator.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/DirectoryNameValidator.java
@@ -9,23 +9,24 @@
package com.google.eclipse.protobuf.ui.util;
import static org.eclipse.core.resources.IResource.FOLDER;
+import static org.eclipse.core.runtime.IStatus.OK;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.IStatus;
import com.google.inject.Singleton;
/**
* Validates names of folders.
- *
+ *
* @author alruiz@google.com (Alex Ruiz)
*/
@Singleton
-public class FolderNameValidator {
+public class DirectoryNameValidator {
- public IStatus validateFolderName(String folderName) {
+ public String validateDirectoryName(String directoryName) {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
- return workspace.validateName(folderName, FOLDER);
+ IStatus isValid = workspace.validateName(directoryName, FOLDER);
+ return (isValid.getCode() == OK) ? null : isValid.getMessage();
}
}