/*
* Copyright 2015 Ritesh Kapoor
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ritesh.idea.plugin.ui.controls;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.spellchecker.ui.SpellCheckingEditorCustomization;
import com.intellij.ui.EditorCustomization;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.EditorTextFieldProvider;
import com.intellij.ui.SoftWrapsEditorCustomization;
import com.intellij.util.TextFieldCompletionProvider;
import org.apache.commons.lang.mutable.MutableBoolean;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author ritesh on 24/7/15.
*/
public class MultiValueAutoComplete {
final static Logger LOG = Logger.getInstance(MultiValueAutoComplete.class);
private static final char[] SEPARATORS = {','};
public static EditorTextField create(Project project, DataProvider dataProvider) {
List<EditorCustomization> customizations =
Arrays.<EditorCustomization>asList(SoftWrapsEditorCustomization.ENABLED, SpellCheckingEditorCustomization.DISABLED);
EditorTextField editorField = ServiceManager.getService(project, EditorTextFieldProvider.class)
.getEditorField(FileTypes.PLAIN_TEXT.getLanguage(), project, customizations);
new CommaSeparatedTextFieldCompletion(dataProvider).apply(editorField);
return editorField;
}
public interface DataProvider {
List<String> getValues(String prefix);
}
private static class CommaSeparatedTextFieldCompletion extends TextFieldCompletionProvider {
private DataProvider dataProvider;
public CommaSeparatedTextFieldCompletion(DataProvider dataProvider) {
this.dataProvider = dataProvider;
}
@NotNull
@Override
protected String getPrefix(@NotNull String currentTextPrefix) {
final int separatorPosition = lastSeparatorPosition(currentTextPrefix);
return separatorPosition == -1 ? currentTextPrefix : currentTextPrefix.substring(separatorPosition + 1).trim();
}
private static int lastSeparatorPosition(@NotNull String text) {
int lastPosition = -1;
for (char separator : SEPARATORS) {
int lio = text.lastIndexOf(separator);
if (lio > lastPosition) {
lastPosition = lio;
}
}
return lastPosition;
}
@Override
protected void addCompletionVariants(@NotNull String text, int offset, @NotNull final String prefix,
@NotNull CompletionResultSet result) {
final List<String> values = new ArrayList<>();
final MutableBoolean completed = new MutableBoolean(false);
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
List<String> values = dataProvider.getValues(prefix);
if(values!=null) {
values.addAll(values);
}
completed.setValue(true);
}
});
while (!completed.booleanValue()) {
ProgressManager.getInstance().checkCanceled();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
LOG.error(e);
}
}
result.addLookupAdvertisement("Select one or more users separated with comma, | or new lines");
for (String completionVariant : values) {
final LookupElementBuilder element = LookupElementBuilder.create(completionVariant);
result.addElement(element.withLookupString(completionVariant.toLowerCase()));
}
}
}
}