Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
irengrig
2010-10-21 20:27:10 +04:00
218 changed files with 3192 additions and 1977 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

+1
View File
@@ -196,6 +196,7 @@ def layoutLinux(Map args, String home, Paths paths) {
fileset(dir: "$home/bin") { include(name: "*.*") }
fileset(dir: "$home/bin/linux") { include(name: "*.*") }
fileset(dir: "$home/bin/nix") { include(name: "*.*") }
fileset(dir: "$home/build/images")
}
}
+11
View File
@@ -269,6 +269,17 @@ def layoutFull(String home, String targetDirectory) {
}
dir("xpath") {
dir("lib") {
jar("xpath.jar") {noResources("xpath")}
resources("xpath")
dir("rt") {
jar("xslt-rt.jar") {module("xslt-rt")}
}
}
}
dir("Groovy") {
dir("lib") {
jar("Groovy.jar") {
+1
View File
@@ -76,6 +76,7 @@
<orderEntry type="module" module-name="IntelliLang-java" />
<orderEntry type="module" module-name="IntelliLang-javaee" />
<orderEntry type="module" module-name="IntelliLang-xml" />
<orderEntry type="module" module-name="xpath" />
</component>
</module>
+1 -1
View File
@@ -27,7 +27,7 @@
</application-components>
<actions>
<action class="org.intellij.images.actions.EditExternalyAction"
<action class="org.intellij.images.actions.EditExternallyAction"
id="Images.EditExternaly"
icon="/org/intellij/images/icons/EditExternaly.png"
text="Open image in external editor">
@@ -0,0 +1,124 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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 org.intellij.images.actions;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.EnvironmentUtil;
import org.intellij.images.ImagesBundle;
import org.intellij.images.fileTypes.ImageFileTypeManager;
import org.intellij.images.options.Options;
import org.intellij.images.options.OptionsManager;
import org.intellij.images.options.impl.OptionsConfigurabe;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* Open image file externally.
*
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public final class EditExternallyAction extends AnAction {
public void actionPerformed(AnActionEvent e) {
Project project = e.getData(PlatformDataKeys.PROJECT);
VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
Options options = OptionsManager.getInstance().getOptions();
String executablePath = options.getExternalEditorOptions().getExecutablePath();
if (StringUtil.isEmpty(executablePath)) {
Messages.showErrorDialog(project,
ImagesBundle.message("error.empty.external.editor.path"),
ImagesBundle.message("error.title.empty.external.editor.path"));
OptionsConfigurabe.show(project);
}
else {
if (files != null) {
Map<String, String> env = EnvironmentUtil.getEnviromentProperties();
Set<String> varNames = env.keySet();
for (String varName : varNames) {
if (SystemInfo.isWindows) {
executablePath = StringUtil.replace(executablePath, "%" + varName + "%", env.get(varName), true);
}
else {
executablePath = StringUtil.replace(executablePath, "${" + varName + "}", env.get(varName), false);
}
}
executablePath = FileUtil.toSystemDependentName(executablePath);
File executable = new File(executablePath);
GeneralCommandLine commandLine = new GeneralCommandLine();
commandLine.setExePath(executable.exists() ? executable.getAbsolutePath() : executablePath);
ImageFileTypeManager typeManager = ImageFileTypeManager.getInstance();
for (VirtualFile file : files) {
if (file.isInLocalFileSystem() && typeManager.isImage(file)) {
commandLine.addParameter(VfsUtil.virtualToIoFile(file).getAbsolutePath());
}
}
commandLine.setWorkingDirectory(new File(executablePath).getParentFile());
try {
commandLine.createProcess();
}
catch (ExecutionException ex) {
Messages.showErrorDialog(project,
ex.getLocalizedMessage(),
ImagesBundle.message("error.title.launching.external.editor"));
OptionsConfigurabe.show(project);
}
}
}
}
public void update(AnActionEvent e) {
super.update(e);
VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
final boolean isEnabled = isImages(files);
if (e.getPlace().equals(ActionPlaces.PROJECT_VIEW_POPUP)) {
e.getPresentation().setVisible(isEnabled);
}
else {
e.getPresentation().setEnabled(isEnabled);
}
}
private static boolean isImages(VirtualFile[] files) {
boolean isImagesFound = false;
if (files != null) {
ImageFileTypeManager typeManager = ImageFileTypeManager.getInstance();
for (VirtualFile file : files) {
boolean isImage = typeManager.isImage(file);
isImagesFound |= isImage;
if (!file.isInLocalFileSystem() || !isImage) {
return false;
}
}
}
return isImagesFound;
}
}
@@ -1,123 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
/** $Id$ */
package org.intellij.images.actions;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.EnvironmentUtil;
import org.intellij.images.ImagesBundle;
import org.intellij.images.fileTypes.ImageFileTypeManager;
import org.intellij.images.options.Options;
import org.intellij.images.options.OptionsManager;
import org.intellij.images.options.impl.OptionsConfigurabe;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
/**
* Open image file externaly.
*
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public final class EditExternalyAction extends AnAction {
public void actionPerformed(AnActionEvent e) {
Project project = e.getData(PlatformDataKeys.PROJECT);
VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
Options options = OptionsManager.getInstance().getOptions();
String executablePath = options.getExternalEditorOptions().getExecutablePath();
if (StringUtil.isEmpty(executablePath)) {
Messages.showErrorDialog(project,
ImagesBundle.message("error.empty.external.editor.path"),
ImagesBundle.message("error.title.empty.external.editor.path"));
OptionsConfigurabe.show(project);
} else {
if (files != null) {
Map<String, String> env = EnvironmentUtil.getEnviromentProperties();
Set<String> varNames = env.keySet();
for (String varName : varNames) {
if (SystemInfo.isWindows) {
executablePath = StringUtil.replace(executablePath, "%" + varName + "%", env.get(varName), true);
} else {
executablePath = StringUtil.replace(executablePath, "${" + varName + "}", env.get(varName), false);
}
}
executablePath = FileUtil.toSystemDependentName(executablePath);
File executable = new File(executablePath);
StringBuffer commandLine = new StringBuffer(executable.exists() ? executable.getAbsolutePath() : executablePath);
ImageFileTypeManager typeManager = ImageFileTypeManager.getInstance();
for (VirtualFile file : files) {
if (file.isInLocalFileSystem() && typeManager.isImage(file)) {
commandLine.append(" \"");
commandLine.append(VfsUtil.virtualToIoFile(file).getAbsolutePath());
commandLine.append('\"');
}
}
try {
File executableFile = new File(executablePath);
Runtime.getRuntime().exec(commandLine.toString(), null, executableFile.getParentFile());
} catch (IOException ex) {
Messages.showErrorDialog(project,
ex.getLocalizedMessage(),
ImagesBundle.message("error.title.launching.external.editor"));
OptionsConfigurabe.show(project);
}
}
}
}
public void update(AnActionEvent e) {
super.update(e);
VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
final boolean isEnabled = isImages(files);
if (e.getPlace().equals(ActionPlaces.PROJECT_VIEW_POPUP)) {
e.getPresentation().setVisible(isEnabled);
}
else {
e.getPresentation().setEnabled(isEnabled);
}
}
private static boolean isImages(VirtualFile[] files) {
boolean isImagesFound = false;
if (files != null) {
ImageFileTypeManager typeManager = ImageFileTypeManager.getInstance();
for (VirtualFile file : files) {
boolean isImage = typeManager.isImage(file);
isImagesFound |= isImage;
if (!file.isInLocalFileSystem() || !isImage) {
return false;
}
}
}
return isImagesFound;
}
}
@@ -180,7 +180,7 @@ public class BuildPropertiesImpl extends BuildProperties {
}
}
final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectJdk();
final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
add(new Property(PROPERTY_PROJECT_JDK_HOME, projectJdk != null ? propertyRef(getJdkHomeProperty(projectJdk.getName())) : ""), 1);
add(new Property(PROPERTY_PROJECT_JDK_BIN, projectJdk != null ? propertyRef(getJdkBinProperty(projectJdk.getName())) : ""));
add(new Property(PROPERTY_PROJECT_JDK_CLASSPATH, projectJdk != null ? getJdkPathId(projectJdk.getName()) : ""));
@@ -736,7 +736,7 @@ public class CompileDriver {
boolean didSomething = false;
final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
GenericCompilerRunner runner = new GenericCompilerRunner(context, compilerManager, isRebuild, onlyCheckStatus);
GenericCompilerRunner runner = new GenericCompilerRunner(context, myCompilerFilter, compilerManager, isRebuild, onlyCheckStatus);
try {
didSomething |= generateSources(compilerManager, context, forceCompile, onlyCheckStatus);
@@ -963,6 +963,7 @@ public class CompileDriver {
final DumbService dumbService = DumbService.getInstance(myProject);
try {
final Set<Module> processedModules = new HashSet<Module>();
VirtualFile[] snapshot = null;
final Map<Chunk<Module>, Collection<VirtualFile>> chunkMap = new HashMap<Chunk<Module>, Collection<VirtualFile>>();
int total = 0;
@@ -1054,7 +1055,16 @@ public class CompileDriver {
filesToRecompile.addAll(compiledWithErrors);
dependentFiles = CacheUtils.findDependentFiles(context, compiledWithSuccess, dependencyFilter);
if (!processedModules.isEmpty()) {
for (Iterator<VirtualFile> it = dependentFiles.iterator(); it.hasNext();) {
final VirtualFile next = it.next();
final Module module = context.getModuleByFile(next);
if (module != null && processedModules.contains(module)) {
it.remove();
}
}
}
if (ourDebugMode) {
if (!dependentFiles.isEmpty()) {
for (VirtualFile dependentFile : dependentFiles) {
@@ -1102,7 +1112,7 @@ public class CompileDriver {
indicator.setText(CompilerBundle.message("progress.saving.caches"));
cache.resetState();
processedModules.addAll(currentChunk.getNodes());
indicator.popState();
}
}
@@ -52,11 +52,15 @@ public class GenericCompilerRunner {
private final GenericCompiler<?,?,?>[] myCompilers;
private final Project myProject;
public GenericCompilerRunner(CompileContext context, CompilerManager compilerManager, boolean forceCompile, boolean onlyCheckStatus) {
public GenericCompilerRunner(CompileContext context,
CompilerFilter compilerFilter,
CompilerManager compilerManager,
boolean forceCompile,
boolean onlyCheckStatus) {
myContext = context;
myForceCompile = forceCompile;
myOnlyCheckStatus = onlyCheckStatus;
myCompilers = compilerManager.getCompilers(GenericCompiler.class);
myCompilers = compilerManager.getCompilers(GenericCompiler.class, compilerFilter);
myProject = myContext.getProject();
}
@@ -18,6 +18,7 @@ package com.intellij.compiler.options;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerConfigurationImpl;
import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
import com.intellij.ide.ui.ListCellRendererWrapper;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
@@ -63,12 +64,10 @@ public class JavaCompilersTab implements SearchableConfigurable {
myContentPanel.add(configurable.createComponent(), compiler.getId());
}
myCompiler.setModel(new DefaultComboBoxModel(new Vector(compilers)));
myCompiler.setRenderer(new DefaultListCellRenderer(){
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel component = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
final String presentableName = value != null? ((BackendCompiler)value).getPresentableName() : "";
component.setText(presentableName);
return component;
myCompiler.setRenderer(new ListCellRendererWrapper<BackendCompiler>(myCompiler.getRenderer()) {
@Override
public void customize(final JList list, final BackendCompiler value, final int index, final boolean selected, final boolean hasFocus) {
setText(value != null ? value.getPresentableName() : "");
}
});
myCompiler.addActionListener(new ActionListener() {
@@ -49,7 +49,7 @@ public class JreVersionDetector {
return isJre50(jdk);
}
final Sdk projectJdk = ProjectRootManager.getInstance(configuration.getProject()).getProjectJdk();
final Sdk projectJdk = ProjectRootManager.getInstance(configuration.getProject()).getProjectSdk();
return isJre50(projectJdk);
}
}
@@ -19,6 +19,7 @@
*/
package com.intellij.ide.impl;
import com.intellij.ide.GeneralSettings;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
import com.intellij.ide.util.projectWizard.ProjectBuilder;
@@ -177,7 +178,7 @@ public class NewProjectUtil {
if (versionString == null) return;
ProjectRootManagerEx rootManager = ProjectRootManagerEx.getInstanceEx(project);
rootManager.setProjectJdk(jdk);
rootManager.setProjectSdk(jdk);
LanguageLevel level = LanguageLevelUtil.getDefaultLanguageLevel(versionString);
LanguageLevelProjectExtension ext = LanguageLevelProjectExtension.getInstance(project);
if (level.compareTo(ext.getLanguageLevel()) < 0) {
@@ -188,13 +189,16 @@ public class NewProjectUtil {
public static void closePreviousProject(final Project projectToClose) {
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
if (openProjects.length > 0) {
int exitCode = Messages.showDialog(IdeBundle.message("prompt.open.project.in.new.frame"), IdeBundle.message("title.new.project"),
new String[]{IdeBundle.message("button.newframe"), IdeBundle.message("button.existingframe")}, 1, 0,
Messages.getQuestionIcon());
final GeneralSettings settings = GeneralSettings.getInstance();
int exitCode = settings.getConfirmOpenNewProject();
if (exitCode < 0) {
exitCode = Messages.showDialog(IdeBundle.message("prompt.open.project.in.new.frame"), IdeBundle.message("title.new.project"),
new String[]{IdeBundle.message("button.newframe"), IdeBundle.message("button.existingframe")}, 1, 0,
Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
}
if (exitCode == 1) { // "No" option
ProjectUtil.closeProject(projectToClose != null ? projectToClose : openProjects[openProjects.length - 1]);
}
}
}
}
@@ -301,7 +301,7 @@ public class AddModuleWizard extends AbstractWizard<ModuleWizardStep> {
return context.getProjectJdk();
}
final Project project = context.getProject() == null ? ProjectManager.getInstance().getDefaultProject() : context.getProject();
final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectJdk();
final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
if (projectJdk != null) {
return projectJdk;
}
@@ -223,14 +223,14 @@ public class JdkChooserPanel extends JPanel {
}
public static Sdk chooseAndSetJDK(final Project project) {
final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectJdk();
final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
final Sdk jdk = showDialog(project, ProjectBundle.message("module.libraries.target.jdk.select.title"), WindowManagerEx.getInstanceEx().getFrame(project), projectJdk);
if (jdk == null) {
return null;
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
ProjectRootManager.getInstance(project).setProjectJdk(jdk);
ProjectRootManager.getInstance(project).setProjectSdk(jdk);
}
});
return jdk;
@@ -149,7 +149,7 @@ public class ProjectJdkForModuleStep extends ModuleWizardStep {
@Nullable
private static Sdk getDefaultJdk() {
Project defaultProject = ProjectManagerEx.getInstanceEx().getDefaultProject();
return ProjectRootManagerEx.getInstanceEx(defaultProject).getProjectJdk();
return ProjectRootManagerEx.getInstanceEx(defaultProject).getProjectSdk();
}
@@ -86,7 +86,7 @@ public class ProjectJdkConfigurable implements UnnamedConfigurable {
myFreeze = true;
final Sdk projectJdk = myJdksModel.getProjectSdk();
myCbProjectJdk.reloadModel(new JdkComboBox.NoneJdkComboBoxItem(), myProject);
final String sdkName = projectJdk == null ? ProjectRootManager.getInstance(myProject).getProjectJdkName() : projectJdk.getName();
final String sdkName = projectJdk == null ? ProjectRootManager.getInstance(myProject).getProjectSdkName() : projectJdk.getName();
if (sdkName != null) {
final Sdk jdk = myJdksModel.findSdk(sdkName);
if (jdk != null) {
@@ -135,18 +135,18 @@ public class ProjectJdkConfigurable implements UnnamedConfigurable {
}
public boolean isModified() {
final Sdk projectJdk = ProjectRootManager.getInstance(myProject).getProjectJdk();
final Sdk projectJdk = ProjectRootManager.getInstance(myProject).getProjectSdk();
return !Comparing.equal(projectJdk, getSelectedProjectJdk());
}
public void apply() throws ConfigurationException {
ProjectRootManager.getInstance(myProject).setProjectJdk(getSelectedProjectJdk());
ProjectRootManager.getInstance(myProject).setProjectSdk(getSelectedProjectJdk());
}
public void reset() {
reloadModel();
final String sdkName = ProjectRootManager.getInstance(myProject).getProjectJdkName();
final String sdkName = ProjectRootManager.getInstance(myProject).getProjectSdkName();
if (sdkName != null) {
final Sdk jdk = myJdksModel.findSdk(sdkName);
if (jdk != null) {
@@ -72,7 +72,7 @@ public class UIRootConfigurationAccessor extends RootConfigurationAccessor {
@Nullable
public String getProjectSdkName(final Project project) {
final String projectJdkName = ProjectRootManager.getInstance(project).getProjectJdkName();
final String projectJdkName = ProjectRootManager.getInstance(project).getProjectSdkName();
final Sdk projectJdk = getProjectSdk(project);
if (projectJdk != null) {
return projectJdk.getName();
@@ -25,6 +25,7 @@ import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.CreateNewLibraryDialog;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import javax.swing.*;
@@ -61,13 +62,13 @@ class NewLibraryChooser implements ClasspathElementChooser<Library> {
List<LibraryTable> tables = Arrays.asList(myRootModel.getModuleLibraryTable(),
registrar.getLibraryTable(myProject),
registrar.getLibraryTable());
CreateNewLibraryDialog dialog = CreateNewLibraryDialog.createDialog(myParentComponent, myProject, tables, 1);
CreateNewLibraryDialog dialog = new CreateNewLibraryDialog(myParentComponent, myContext, new NewLibraryEditor(), tables, 1);
final Module contextModule = DataKeys.MODULE_CONTEXT.getData(DataManager.getInstance().getDataContext(myParentComponent));
dialog.addFileChooserContext(LangDataKeys.MODULE_CONTEXT, contextModule);
dialog.show();
myIsOk = dialog.isOK();
if (myIsOk) {
myChosenLibrary = dialog.createLibrary(myContext.getModifiableLibraryTable(dialog.getSelectedTable()));
myChosenLibrary = dialog.createLibrary();
}
else {
myChosenLibrary = null;
@@ -64,10 +64,10 @@ public class CreateCustomLibraryAction extends CustomLibraryActionBase {
LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance();
final Project project = myContext.getProject();
final List<LibraryTable> tables = Arrays.asList(registrar.getLibraryTable(project), registrar.getLibraryTable());
final CreateNewLibraryDialog dialog = new CreateNewLibraryDialog(myModuleStructureConfigurable.getTree(), project, libraryEditor, tables, 0);
final CreateNewLibraryDialog dialog = new CreateNewLibraryDialog(myModuleStructureConfigurable.getTree(), myContext, libraryEditor, tables, 0);
dialog.show();
if (dialog.isOK()) {
final Library library = dialog.createLibrary(myContext.getModifiableLibraryTable(dialog.getSelectedTable()));
final Library library = dialog.createLibrary();
final ModifiableRootModel rootModel = myContext.getModulesConfigurator().getOrCreateModuleEditor(myModule).getModifiableRootModelProxy();
if (!askAndRemoveDuplicatedLibraryEntry(myCreator.getDescription(), rootModel)) {
return;
@@ -17,13 +17,12 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.util.ui.FormBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -33,18 +32,14 @@ import java.util.List;
* @author nik
*/
public class CreateNewLibraryDialog extends LibraryEditorDialogBase {
private final StructureConfigurableContext myContext;
private NewLibraryEditor myLibraryEditor;
private ComboBox myLibraryLevelCombobox;
public static CreateNewLibraryDialog createDialog(JComponent parent, @Nullable Project project,
@NotNull List<LibraryTable> libraryTables,
int selectedTable) {
return new CreateNewLibraryDialog(parent, project, new NewLibraryEditor(), libraryTables, selectedTable);
}
public CreateNewLibraryDialog(@NotNull JComponent parent, @Nullable Project project, @NotNull NewLibraryEditor libraryEditor,
public CreateNewLibraryDialog(@NotNull JComponent parent, @NotNull StructureConfigurableContext context, @NotNull NewLibraryEditor libraryEditor,
@NotNull List<LibraryTable> libraryTables, int selectedTable) {
super(parent, new LibraryRootsComponent(project, libraryEditor));
super(parent, new LibraryRootsComponent(context.getProject(), libraryEditor));
myContext = context;
myLibraryEditor = libraryEditor;
final DefaultComboBoxModel model = new DefaultComboBoxModel();
for (LibraryTable table : libraryTables) {
@@ -65,11 +60,14 @@ public class CreateNewLibraryDialog extends LibraryEditorDialogBase {
init();
}
public LibraryTable getSelectedTable() {
return (LibraryTable)myLibraryLevelCombobox.getSelectedItem();
@NotNull @Override
protected LibraryTable.ModifiableModel getTableModifiableModel() {
final LibraryTable selectedTable = (LibraryTable)myLibraryLevelCombobox.getSelectedItem();
return myContext.getModifiableLibraryTable(selectedTable);
}
public Library createLibrary(final @NotNull LibraryTable.ModifiableModel modifiableModel) {
public Library createLibrary() {
final LibraryTable.ModifiableModel modifiableModel = getTableModifiableModel();
final Library library = modifiableModel.createLibrary(myLibraryEditor.getName());
final Library.ModifiableModel model = library.getModifiableModel();
myLibraryEditor.apply(model);
@@ -85,4 +83,8 @@ public class CreateNewLibraryDialog extends LibraryEditorDialogBase {
protected void addNorthComponents(FormBuilder formBuilder) {
formBuilder.addLabeledComponent("Level:", myLibraryLevelCombobox);
}
protected boolean shouldCheckName(String newName) {
return true;
}
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.Nullable;
@@ -79,4 +80,8 @@ public class EditExistingLibraryDialog extends LibraryEditorDialogBase {
protected LibraryTable.ModifiableModel getTableModifiableModel() {
return myTableModifiableModel;
}
protected boolean shouldCheckName(String newName) {
return !Comparing.equal(newName, getLibraryRootsComponent().getLibraryEditor().getName());
}
}
@@ -22,7 +22,6 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.ui.FormBuilder;
import org.jetbrains.annotations.Nullable;
@@ -65,12 +64,11 @@ public abstract class LibraryEditorDialogBase extends DialogWrapper {
}
protected boolean validateAndApply() {
final String currentName = myLibraryRootsComponent.getLibraryEditor().getName();
String newName = myNameField.getText().trim();
if (newName.length() == 0) {
newName = null;
}
if (!Comparing.equal(newName, currentName)) {
if (shouldCheckName(newName)) {
final LibraryTable.ModifiableModel tableModifiableModel = getTableModifiableModel();
if (tableModifiableModel != null && !(tableModifiableModel instanceof ModuleLibraryTable)) {
if (newName == null) {
@@ -88,11 +86,17 @@ public abstract class LibraryEditorDialogBase extends DialogWrapper {
return true;
}
protected abstract boolean shouldCheckName(String newName);
@Nullable
protected LibraryTable.ModifiableModel getTableModifiableModel() {
return null;
}
protected LibraryRootsComponent getLibraryRootsComponent() {
return myLibraryRootsComponent;
}
protected JComponent createNorthPanel() {
FormBuilder formBuilder = new FormBuilder();
String currentName = myLibraryRootsComponent.getLibraryEditor().getName();
@@ -168,7 +168,7 @@ public class JdkListConfigurable extends BaseStructureConfigurable {
}
if (myJdksTreeModel.isModified() || modifiedJdks) myJdksTreeModel.apply(this);
myJdksTreeModel.setProjectSdk(ProjectRootManager.getInstance(myProject).getProjectJdk());
myJdksTreeModel.setProjectSdk(ProjectRootManager.getInstance(myProject).getProjectSdk());
}
public boolean isModified() {
@@ -124,7 +124,7 @@ public abstract class ProjectOpenProcessorBase extends ProjectOpenProcessor {
wizardContext.setProjectFileDirectory(virtualFile.getParent().getPath());
Project defaultProject = ProjectManager.getInstance().getDefaultProject();
Sdk jdk = ProjectRootManager.getInstance(defaultProject).getProjectJdk();
Sdk jdk = ProjectRootManager.getInstance(defaultProject).getProjectSdk();
if (jdk == null) {
jdk = ProjectJdkTable.getInstance().findMostRecentSdkOfType(JavaSdk.getInstance());
}
@@ -110,7 +110,7 @@ public class IncreaseLanguageLevelFix implements IntentionAction {
@Nullable
private static Sdk getRelevantJdk(final Project project, @Nullable Module module) {
Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectJdk();
Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
Sdk moduleJdk = module == null ? null : ModuleRootManager.getInstance(module).getSdk();
return moduleJdk == null ? projectJdk : moduleJdk;
}
@@ -120,7 +120,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext
if (isBadSdk(project, modules)) {
System.err.println(InspectionsBundle.message("inspection.no.jdk.error.message"));
System.err.println(
InspectionsBundle.message("offline.inspections.jdk.not.found", ProjectRootManager.getInstance(project).getProjectJdkName()));
InspectionsBundle.message("offline.inspections.jdk.not.found", ProjectRootManager.getInstance(project).getProjectSdkName()));
return false;
}
for (Module module : modules) {
@@ -152,7 +152,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext
private static boolean isBadSdk(final Project project, final Module[] modules) {
boolean anyModuleAcceptsSdk = false;
boolean anyModuleUsesProjectSdk = false;
Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectJdk();
Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();
for (Module module : modules) {
if (ModuleRootManager.getInstance(module).isSdkInherited()) {
anyModuleUsesProjectSdk = true;
@@ -15,15 +15,14 @@
*/
package com.intellij.codeInspection.internal;
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.*;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import javax.swing.DefaultListCellRenderer;
import javax.swing.*;
public class GtkPreferredJComboBoxRendererInspection extends BaseJavaLocalInspectionTool {
public class GtkPreferredJComboBoxRendererInspection extends InternalInspection {
private static final String RENDERER_CLASS_NAME = DefaultListCellRenderer.class.getName();
private static final String MESSAGE = "Please use ListCellRendererWrapper instead to prevent artifacts under GTK+ Look and Feel.";
@@ -0,0 +1,52 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* 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.intellij.codeInspection.internal;
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.components.JBList;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
public abstract class InternalInspection extends BaseJavaLocalInspectionTool {
@Nls
@NotNull
@Override
public String getGroupDisplayName() {
return InternalInspectionToolsProvider.GROUP_NAME;
}
public boolean isEnabledByDefault() {
return true;
}
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder,
boolean isOnTheFly,
LocalInspectionToolSession session) {
if (JavaPsiFacade.getInstance(holder.getProject()).findClass(JBList.class.getName(),
GlobalSearchScope.allScope(holder.getProject())) == null) {
return new PsiElementVisitor() {
};
}
return super.buildVisitor(holder, isOnTheFly, session);
}
}
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInspection.internal;
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.openapi.application.QueryExecutorBase;
@@ -32,7 +31,7 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.Map;
public class UndesirableClassUsageInspection extends BaseJavaLocalInspectionTool {
public class UndesirableClassUsageInspection extends InternalInspection {
private static final Map<String, String> CLASSES = new THashMap<String, String>();
static {
@@ -43,13 +42,6 @@ public class UndesirableClassUsageInspection extends BaseJavaLocalInspectionTool
CLASSES.put(QueryExecutor.class.getName(), QueryExecutorBase.class.getName());
}
@Nls
@NotNull
@Override
public String getGroupDisplayName() {
return InternalInspectionToolsProvider.GROUP_NAME;
}
@Nls
@NotNull
@Override
@@ -63,10 +55,6 @@ public class UndesirableClassUsageInspection extends BaseJavaLocalInspectionTool
return "UndesirableClassUsage";
}
public boolean isEnabledByDefault() {
return true;
}
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new JavaElementVisitor() {
@@ -40,7 +40,7 @@ import org.jetbrains.annotations.NotNull;
* @author max
*/
public class JavaParserDefinition implements ParserDefinition {
public static boolean USE_NEW_PARSER = false;
public static boolean USE_NEW_PARSER = true;
@NotNull
public Lexer createLexer(final Project project) {
@@ -931,10 +931,20 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
}
@NotNull
public SuggestedNameInfo suggestUniqueVariableName(@NotNull final SuggestedNameInfo baseNameInfo, PsiElement place, boolean lookForward) {
public SuggestedNameInfo suggestUniqueVariableName(@NotNull final SuggestedNameInfo baseNameInfo,
PsiElement place,
boolean ignorePlaceName,
boolean lookForward) {
final String[] names = baseNameInfo.names;
final LinkedHashSet<String> uniqueNames = new LinkedHashSet<String>(names.length);
for (String name : names) {
if (ignorePlaceName && place instanceof PsiNamedElement) {
final String placeName = ((PsiNamedElement)place).getName();
if (Comparing.strEqual(placeName, name)) {
uniqueNames.add(name);
continue;
}
}
uniqueNames.add(suggestUniqueVariableName(name, place, lookForward));
}
@@ -46,6 +46,12 @@ public class JavaChangeSignatureHandler implements ChangeSignatureHandler {
private static void invokeOnElement(Project project, Editor editor, PsiElement element) {
if (element instanceof PsiMethod) {
final ChangeSignatureGestureDetector detector = ChangeSignatureGestureDetector.getInstance(project);
final PsiIdentifier nameIdentifier = ((PsiMethod)element).getNameIdentifier();
if (nameIdentifier != null && detector.isChangeSignatureAvailable(nameIdentifier)) {
detector.changeSignature(element.getContainingFile());
return;
}
invoke((PsiMethod) element, project, editor);
}
else if (element instanceof PsiClass) {
@@ -462,6 +462,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
final IntroduceVariableSettings settings =
getSettings(project, editor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, choice);
if (!settings.isOK()) return;
final SuggestedNameInfo suggestedName = getSuggestedName(typeSelectorManager.getDefaultType(), expr);
final Runnable runnable =
introduce(project, expr, editor, anchorStatement, tempContainer, occurrences, anchorStatementIfAll, settings, variable);
CommandProcessor.getInstance().executeCommand(
@@ -473,7 +474,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
PsiVariable elementToRename = variable.get().getElement();
if (elementToRename != null) {
editor.getCaretModel().moveToOffset(elementToRename.getTextOffset());
new VariableInplaceRenamer(elementToRename, editor).performInplaceRename(false);
new VariableInplaceRenamer(elementToRename, editor).performInplaceRename(false, new LinkedHashSet<String>(Arrays.asList(suggestedName.names)));
}
}
}
@@ -170,11 +170,7 @@ class IntroduceVariableDialog extends DialogWrapper implements IntroduceVariable
myNameSuggestionsManager = new NameSuggestionsManager(myTypeSelector, myNameField,
new NameSuggestionsGenerator() {
public SuggestedNameInfo getSuggestedNameInfo(PsiType type) {
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject);
final SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, myExpression, type);
final String[] strings = JavaCompletionUtil.completeVariableNameForRefactoring(codeStyleManager, type, VariableKind.LOCAL_VARIABLE, nameInfo);
final SuggestedNameInfo.Delegate delegate = new SuggestedNameInfo.Delegate(strings, nameInfo);
return codeStyleManager.suggestUniqueVariableName(delegate, myExpression, true);
return IntroduceVariableBase.getSuggestedName(type, myExpression);
}
});
myNameSuggestionsManager.setLabelsFor(type, namePrompt);
@@ -38,7 +38,7 @@ public class JavaNameSuggestionProvider implements NameSuggestionProvider {
String initialName = UsageViewUtil.getShortName(element);
SuggestedNameInfo info = suggestNamesForElement(element);
if (info != null) {
info = JavaCodeStyleManager.getInstance(element.getProject()).suggestUniqueVariableName(info, element, true);
info = JavaCodeStyleManager.getInstance(element.getProject()).suggestUniqueVariableName(info, element, true, true);
}
String parameterName = null;
@@ -4,7 +4,7 @@ class TestInvertIf {
void invertIf(Object object) {
if (object != "adf") {
System.out.println("1");
} // comment
} // comment
else {
System.out.println("2");
}
@@ -34,7 +34,7 @@ public class InheritedJdkTest extends ModuleTestCase {
@Override
public void run() {
final ProjectRootManagerEx rootManagerEx = ProjectRootManagerEx.getInstanceEx(myProject);
rootManagerEx.setProjectJdkName(jdk.getName());
rootManagerEx.setProjectSdkName(jdk.getName());
final ModifiableRootModel rootModel = rootManager.getModifiableModel();
rootModel.inheritSdk();
rootModel.commit();
@@ -102,7 +102,7 @@ public class InheritedJdkTest extends ModuleTestCase {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
projectRootManager.setProjectJdk(mockJdk);
projectRootManager.setProjectSdk(mockJdk);
}
});
@@ -112,7 +112,7 @@ public class InheritedJdkTest extends ModuleTestCase {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
projectRootManager.setProjectJdkName("jdk1");
projectRootManager.setProjectSdkName("jdk1");
}
});
@@ -99,7 +99,7 @@ public class RootsChangedTest extends ModuleTestCase {
ProjectJdkTable.getInstance().addJdk(jdk);
assertEventsCount(0);
ProjectRootManager.getInstance(myProject).setProjectJdk(jdkBBB);
ProjectRootManager.getInstance(myProject).setProjectSdk(jdkBBB);
assertEventsCount(0);
final ModifiableRootModel rootModelA = ModuleRootManager.getInstance(moduleA).getModifiableModel();
@@ -109,7 +109,7 @@ public class RootsChangedTest extends ModuleTestCase {
ProjectRootManager.getInstance(myProject).multiCommit(new ModifiableRootModel[]{rootModelA, rootModelB});
assertEventsCount(1);
ProjectRootManager.getInstance(myProject).setProjectJdk(jdk);
ProjectRootManager.getInstance(myProject).setProjectSdk(jdk);
assertEventsCount(1);
final SdkModificator sdkModificator = jdk.getSdkModificator();
@@ -15,8 +15,8 @@
*/
package com.intellij.psi;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
@@ -148,7 +148,26 @@ public abstract class JavaCodeStyleManager {
* @param lookForward if true, the existing variables are searched in both directions; if false - only backward
* @return the generated unique name,
*/
@NotNull public abstract SuggestedNameInfo suggestUniqueVariableName(@NotNull SuggestedNameInfo baseNameInfo, PsiElement place, boolean lookForward);
@NotNull
public SuggestedNameInfo suggestUniqueVariableName(@NotNull SuggestedNameInfo baseNameInfo,
PsiElement place,
boolean lookForward) {
return suggestUniqueVariableName(baseNameInfo, place, false, lookForward);
}
/**
* Suggests a unique name for the variable used at the specified location.
*
*
* @param baseNameInfo the base name info for the variable.
* @param place the location where the variable will be used.
* @param ignorePlaceName if true and place is PsiNamedElement, place.getName() would be still treated as unique name
* @param lookForward if true, the existing variables are searched in both directions; if false - only backward @return the generated unique name,
*/
@NotNull public abstract SuggestedNameInfo suggestUniqueVariableName(@NotNull SuggestedNameInfo baseNameInfo,
PsiElement place,
boolean ignorePlaceName,
boolean lookForward);
/**
* Replaces all references to Java classes in the contents of the specified element,
@@ -172,4 +191,4 @@ public abstract class JavaCodeStyleManager {
@Nullable
public abstract Collection<PsiImportStatementBase> findRedundantImports(PsiJavaFile file);
}
}
@@ -146,5 +146,10 @@ public abstract class LocalInspectionTool extends InspectionProfileEntry {
public void inspectionStarted(LocalInspectionToolSession session) {}
public void inspectionFinished(LocalInspectionToolSession session, ProblemsHolder problemsHolder) {
inspectionFinished(session);
}
@Deprecated()
public void inspectionFinished(LocalInspectionToolSession session) {}
}
@@ -56,7 +56,7 @@ public class WizardContext {
public WizardContext(Project project) {
myProject = project;
if (myProject != null){
myProjectJdk = ProjectRootManager.getInstance(myProject).getProjectJdk();
myProjectJdk = ProjectRootManager.getInstance(myProject).getProjectSdk();
}
}
@@ -65,8 +65,8 @@ public interface ModuleRootModel {
* Returns <code>true</code> if JDK for this module is inherited from a project.
*
* @return true if the JDK is inherited, false otherwise
* @see ProjectRootManager#getProjectJdk()
* @see ProjectRootManager#setProjectJdk(com.intellij.openapi.projectRoots.Sdk)
* @see ProjectRootManager#getProjectSdk()
* @see ProjectRootManager#setProjectSdk(com.intellij.openapi.projectRoots.Sdk)
*/
boolean isSdkInherited();
@@ -124,28 +124,28 @@ public abstract class ProjectRootManager implements ModificationTracker {
* to any existing JDK instance.
*/
@Nullable
public abstract Sdk getProjectJdk();
public abstract Sdk getProjectSdk();
/**
* Returns the name of the JDK selected for the project.
*
* @return the JDK name.
*/
public abstract String getProjectJdkName();
public abstract String getProjectSdkName();
/**
* Sets the JDK to be used for the project.
*
* @param jdk the JDK instance.
*/
public abstract void setProjectJdk(@Nullable Sdk jdk);
public abstract void setProjectSdk(@Nullable Sdk jdk);
/**
* Sets the name of the JDK to be used for the project.
*
* @param name the name of the JDK.
*/
public abstract void setProjectJdkName(String name);
public abstract void setProjectSdkName(String name);
/**
* Commits the change to the lists of roots for the specified modules.
@@ -177,14 +177,14 @@ public class OrderEntryCellAppearanceUtils {
public static CellAppearance forProjectJdk(final Project project) {
final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(project);
final Sdk projectJdk = projectRootManager.getProjectJdk();
final Sdk projectJdk = projectRootManager.getProjectSdk();
final CellAppearance appearance;
if (projectJdk != null) {
appearance = forJdk(projectJdk, false, false);
}
else {
// probably invalid JDK
final String projectJdkName = projectRootManager.getProjectJdkName();
final String projectJdkName = projectRootManager.getProjectSdkName();
if (projectJdkName != null) {
appearance = SimpleTextCellAppearance.invalid(ProjectBundle.message("jdk.combo.box.invalid.item", projectJdkName),
CellAppearanceUtils.INVALID_ICON);
@@ -199,7 +199,6 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
LookupImpl lookup = (LookupImpl)LookupManager.getInstance(editor.getProject()).createLookup(editor, LookupElement.EMPTY_ARRAY, "", LookupArranger.DEFAULT);
if (editor.isOneLineMode()) {
lookup.setForceShowAsPopup(true);
lookup.setCancelOnClickOutside(true);
lookup.setCancelOnOtherWindowOpen(true);
lookup.setResizable(false);
@@ -31,8 +31,7 @@ public class ComboEditorCompletionContributor extends CompletionContributor{
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion();
if (process != null && process.isAutopopupCompletion()) {
if (parameters.getInvocationCount() == 0) {
return;
}
@@ -30,7 +30,6 @@ import com.intellij.psi.statistics.StatisticsManager;
import gnu.trove.THashMap;
import gnu.trove.TObjectHashingStrategy;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
@@ -48,13 +47,13 @@ public class CompletionLookupArranger extends LookupArranger {
}
@Override
public void sortItems(List<LookupElement> items) {
Collections.sort(items, new Comparator<LookupElement>() {
public Comparator<LookupElement> getItemComparator() {
return new Comparator<LookupElement>() {
public int compare(LookupElement o1, LookupElement o2) {
//noinspection unchecked
return getSortingWeight(o1).compareTo(getSortingWeight(o2));
}
});
};
}
public void itemSelected(LookupElement item, final Lookup lookup) {
@@ -76,7 +76,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
private final LookupImpl myLookup;
private final MergingUpdateQueue myQueue;
private boolean myDisposed;
private boolean myInitialized;
private boolean myShownLookup;
private int myCount;
private final Update myUpdate = new Update("update") {
public void run() {
@@ -124,6 +124,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
myLookup = lookup;
myLookup.setArranger(new CompletionLookupArranger(parameters));
myShownLookup = lookup.isShown();
myLookup.addLookupListener(myLookupListener);
myLookup.setCalculating(true);
@@ -133,7 +134,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
ApplicationManager.getApplication().assertIsDispatchThread();
registerItself();
if (!ApplicationManager.getApplication().isUnitTestMode()) {
if (!ApplicationManager.getApplication().isUnitTestMode() && !lookup.isShown()) {
scheduleAdvertising();
}
@@ -194,7 +195,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if (isOutdated()) {
return;
}
if (isAutopopupCompletion() && !myInitialized) {
if (isAutopopupCompletion() && !myShownLookup) {
return;
}
if (!isBackgrounded()) {
@@ -307,8 +308,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
ApplicationManager.getApplication().assertIsDispatchThread();
if (isOutdated()) return;
if (!myInitialized) {
myInitialized = true;
if (!myShownLookup) {
myShownLookup = true;
if (StringUtil.isEmpty(myLookup.getAdvertisementText()) && !isAutopopupCompletion()) {
final String text = DefaultCompletionContributor.getDefaultAdvertisementText(myParameters);
@@ -536,10 +537,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
return aBoolean.booleanValue();
}
public boolean isInitialized() {
return myInitialized;
}
public void restorePrefix() {
setMergeCommand();
@@ -128,7 +128,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
MarkupModel model = myDocument.getMarkupModel(myProject);
UpdateHighlightersUtil.cleanFileLevelHighlights(myProject, Pass.UPDATE_ALL,myFile);
final EditorColorsScheme colorsScheme = getColorsScheme();
UpdateHighlightersUtil.setHighlightersInRange(range, myHighlights, colorsScheme, (MarkupModelEx)model, Pass.UPDATE_ALL, myDocument, myProject);
UpdateHighlightersUtil.setHighlightersInRange(myProject, myDocument, range, colorsScheme, myHighlights, (MarkupModelEx)model, Pass.UPDATE_ALL);
}
};
@@ -192,16 +192,8 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
public void run() {
if (!addInjectedPsiHighlights(injectedInside, progress, Collections.synchronizedSet(result))) throw new ProcessCanceledException();
// set editor's color scheme
//final EditorColorsScheme colorsScheme = getColorsScheme();
//if (colorsScheme != null) {
// for (HighlightInfo info : result) {
// info.setCustomColorScheme(colorsScheme);
// }
//}
if (!outside.isEmpty() || !injectedOutside.isEmpty()) {
if (!inside.isEmpty()) { // do not apply when there were no elements to highlight
if (!inside.isEmpty() || !injectedInside.isEmpty()) { // do not apply when there were no elements to highlight
// clear infos found in visible area to avoid applying them twice
final List<HighlightInfo> toApply = new ArrayList<HighlightInfo>(result.size());
for (HighlightInfo info : result) {
@@ -219,18 +211,19 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
if (progress.isCanceled()) return;
if (myProject.isDisposed()) return;
MarkupModel markupModel = myDocument.getMarkupModel(myProject);
ProperTextRange range = myPriorityRange.intersection(new TextRange(myStartOffset, myEndOffset));
final EditorColorsScheme colorsScheme = getColorsScheme();
UpdateHighlightersUtil.setHighlightersInRange(range, toApply, colorsScheme, (MarkupModelEx)markupModel, Pass.UPDATE_ALL, myDocument, myProject);
UpdateHighlightersUtil.setHighlightersInRange(myProject, myDocument, range, colorsScheme, toApply,
(MarkupModelEx)markupModel, Pass.UPDATE_ALL);
}
});
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
if (progress.isCanceled() || myEditor == null) return;
if (myProject.isDisposed() || myEditor == null) return;
new ShowAutoImportPass(myProject, myFile, myEditor).applyInformationToEditor();
}
});
@@ -268,7 +261,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
}
*/
UpdateHighlightersUtil.setHighlightersToEditorOutsideRange(myProject, myDocument, toApply, getColorsScheme(),
UpdateHighlightersUtil.setHighlightersOutsideRange(myProject, myDocument, toApply, getColorsScheme(),
myStartOffset, myEndOffset, myPriorityRange, Pass.UPDATE_ALL);
}
};
@@ -269,22 +269,23 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
List<Trinity<LocalInspectionTool, ProblemsHolder, PsiElementVisitor>> init) {
boolean result = JobUtil.invokeConcurrentlyUnderMyProgress(init, new Processor<Trinity<LocalInspectionTool, ProblemsHolder, PsiElementVisitor>>() {
@Override
public boolean process(Trinity<LocalInspectionTool, ProblemsHolder, PsiElementVisitor> i) {
LocalInspectionTool tool = i.first;
public boolean process(Trinity<LocalInspectionTool, ProblemsHolder, PsiElementVisitor> trinity) {
LocalInspectionTool tool = trinity.first;
indicator.checkCanceled();
ApplicationManager.getApplication().assertReadAccessAllowed();
ProblemsHolder holder = i.second;
PsiElementVisitor elementVisitor = i.third;
for (PsiElement element : elements) {
ProblemsHolder holder = trinity.second;
PsiElementVisitor elementVisitor = trinity.third;
for (int i = 0, elementsSize = elements.size(); i < elementsSize; i++) {
PsiElement element = elements.get(i);
indicator.checkCanceled();
element.accept(elementVisitor);
}
advanceProgress(1);
tool.inspectionFinished(session);
tool.inspectionFinished(session, holder);
if (holder.hasResults()) {
appendDescriptors(myFile, holder.getResults(), tool);
@@ -115,26 +115,6 @@ public class UpdateHighlightersUtil {
}
}
public static void setHighlightersToEditor(@NotNull Project project,
@NotNull Document document,
int startOffset,
int endOffset,
@NotNull Collection<HighlightInfo> highlights,
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
int group) {
setHighlightersToEditor(project, document, Collections.singletonMap(new TextRange(startOffset, endOffset), highlights), colorsScheme, group);
}
@Deprecated
public static void setHighlightersToEditor(Project project,
Document document,
int startOffset,
int endOffset,
Collection<HighlightInfo> highlights, int group) {
setHighlightersToEditor(project, document, startOffset, endOffset, highlights, null, group);
}
static boolean hasInfo(Collection<HighlightInfo> infos, int start, int end, String desc) {
if (infos == null) return false;
for (HighlightInfo info : infos) {
@@ -177,13 +157,13 @@ public class UpdateHighlightersUtil {
}
static void addHighlighterToEditorIncrementally(@NotNull Project project,
@NotNull Document document,
@NotNull PsiFile file,
int startOffset,
int endOffset,
@NotNull final HighlightInfo info,
@NotNull Document document,
@NotNull PsiFile file,
int startOffset,
int endOffset,
@NotNull final HighlightInfo info,
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
final int group) {
final int group) {
ApplicationManager.getApplication().assertIsDispatchThread();
if (info.isFileLevelAnnotation || info.getGutterIconRenderer() != null) return;
@@ -204,100 +184,68 @@ public class UpdateHighlightersUtil {
createOrReuseHighlighterFor(info, colorsScheme, document, group, file, (MarkupModelEx)markup, null, null,
SeverityRegistrar.getInstance(project));
DaemonCodeAnalyzerImpl.addHighlight(markup, project, info);
clearWhiteSpaceOptimizationFlag(document);
assertMarkupConsistent(markup, project);
}
@Deprecated
static void setHighlightersToEditor(@NotNull final Project project,
@NotNull final Document document,
@NotNull final Map<TextRange, Collection<HighlightInfo>> infos,
final int group) {
// For backward compatibility with TeamCity plugin, duplicates searcher.
setHighlightersToEditor(project, document, infos, null, group);
}
static void setHighlightersToEditor(@NotNull Project project,
@NotNull Document document,
@NotNull Map<TextRange, Collection<HighlightInfo>> infos,
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
final int group) {
public static void setHighlightersToEditor(@NotNull Project project,
@NotNull Document document,
int startOffset,
int endOffset,
@NotNull Collection<HighlightInfo> highlights,
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
int group) {
TextRange range = new TextRange(startOffset, endOffset);
ApplicationManager.getApplication().assertIsDispatchThread();
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
cleanFileLevelHighlights(project, group, psiFile);
final List<TextRange> ranges = new ArrayList<TextRange>(infos.keySet());
Collections.sort(ranges, BY_START_OFFSET);
//merge intersecting
for (int i = 1; i < ranges.size(); i++) {
TextRange range = ranges.get(i);
TextRange prev = ranges.get(i-1);
if (prev.intersects(range)) {
ranges.remove(i);
TextRange union = prev.union(range);
Collection<HighlightInfo> collection = infos.get(prev);
collection.addAll(infos.get(range));
infos.remove(prev);
infos.remove(range);
infos.put(union, collection);
ranges.set(i - 1, union);
i--;
}
}
MarkupModel markup = document.getMarkupModel(project);
assertMarkupConsistent(markup, project);
for (Map.Entry<TextRange, Collection<HighlightInfo>> entry : infos.entrySet()) {
TextRange range = entry.getKey();
Collection<HighlightInfo> highlights = entry.getValue();
setHighlightersInRange(range, highlights, colorsScheme, (MarkupModelEx)markup, group, document, project);
}
setHighlightersInRange(project, document, range, colorsScheme, highlights, (MarkupModelEx)markup, group);
}
@Deprecated //for teamcity
public static void setHighlightersToEditor(@NotNull Project project,
@NotNull Document document,
int startOffset,
int endOffset,
@NotNull Collection<HighlightInfo> highlights,
int group) {
setHighlightersToEditor(project, document, startOffset, endOffset, highlights, null, group);
}
// set highlights inside startOffset,endOffset but outside range
static void setHighlightersToEditorOutsideRange(@NotNull Project project,
@NotNull Document document,
@NotNull Collection<HighlightInfo> infos,
static void setHighlightersOutsideRange(@NotNull final Project project,
@NotNull final Document document,
@NotNull Collection<HighlightInfo> infos,
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
int startOffset, int endOffset,
@NotNull ProperTextRange range,
final int group) {
int startOffset, int endOffset,
@NotNull final ProperTextRange range,
final int group) {
ApplicationManager.getApplication().assertIsDispatchThread();
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
cleanFileLevelHighlights(project, group, psiFile);
MarkupModel markup = document.getMarkupModel(project);
final MarkupModel markup = document.getMarkupModel(project);
assertMarkupConsistent(markup, project);
setHighlightersOutsideRange(startOffset, endOffset, range, infos, colorsScheme, (MarkupModelEx)markup, group, document, project);
}
static void setHighlightersInRange(final TextRange range,
Collection<HighlightInfo> highlightsCo,
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
final MarkupModelEx markup,
final int group,
final Document document,
final Project project) {
final List<HighlightInfo> highlights = new ArrayList<HighlightInfo>(highlightsCo);
final List<HighlightInfo> highlights = new ArrayList<HighlightInfo>(infos);
final SeverityRegistrar severityRegistrar = SeverityRegistrar.getInstance(project);
final HighlightersRecycler infosToRemove = new HighlightersRecycler();
DaemonCodeAnalyzerImpl.processHighlights(document, project, null, range.getStartOffset(), range.getEndOffset(), new Processor<HighlightInfo>() {
DaemonCodeAnalyzerImpl.processHighlights(document, project, null, startOffset, endOffset, new Processor<HighlightInfo>() {
@Override
public boolean process(HighlightInfo info) {
if (info.group == group) {
RangeHighlighter highlighter = info.highlighter;
int endOffset = highlighter.getEndOffset();
int startOffset = highlighter.getStartOffset();
boolean willBeRemoved = endOffset == document.getTextLength() && range.getEndOffset() == document.getTextLength()
|| range.contains(startOffset)
|| range.containsRange(startOffset, endOffset);
int hiStart = highlighter.getStartOffset();
int hiEnd = highlighter.getEndOffset();
boolean willBeRemoved = hiEnd == document.getTextLength() && range.getEndOffset() == document.getTextLength()
|| !range.containsRange(hiStart, hiEnd);
if (willBeRemoved) {
infosToRemove.recycleHighlighter(highlighter);
info.highlighter = null;
@@ -309,7 +257,6 @@ public class UpdateHighlightersUtil {
Collections.sort(highlights, BY_START_OFFSET_NODUPS);
final Map<TextRange, RangeMarker> ranges2markersCache = new THashMap<TextRange, RangeMarker>(10);
final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
final boolean[] changed = {false};
RangeMarkerTree.sweep(new RangeMarkerTree.Generator<HighlightInfo>(){
@Override
@@ -330,10 +277,8 @@ public class UpdateHighlightersUtil {
if (isWarningCoveredByError(info, overlappingIntervals, severityRegistrar)) {
return true;
}
if (info.getStartOffset() >= range.getStartOffset() && info.getEndOffset() <= range.getEndOffset()) {
createOrReuseHighlighterFor(info, colorsScheme, document, group, psiFile, markup, infosToRemove,
ranges2markersCache,
severityRegistrar);
if (info.getStartOffset() < range.getStartOffset() || info.getEndOffset() > range.getEndOffset()) {
createOrReuseHighlighterFor(info, colorsScheme, document, group, psiFile, (MarkupModelEx)markup, infosToRemove, ranges2markersCache, severityRegistrar);
changed[0] = true;
}
return true;
@@ -350,27 +295,27 @@ public class UpdateHighlightersUtil {
assertMarkupConsistent(markup, project);
}
private static void setHighlightersOutsideRange(final int startOffset, final int endOffset, final TextRange range,
Collection<HighlightInfo> highlightsCo,
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
final MarkupModelEx markup,
final int group,
final Document document,
final Project project) {
static void setHighlightersInRange(@NotNull final Project project,
@NotNull final Document document,
@NotNull final TextRange range,
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
@NotNull Collection<HighlightInfo> highlightsCo,
@NotNull final MarkupModelEx markup,
final int group) {
ApplicationManager.getApplication().assertIsDispatchThread();
final List<HighlightInfo> highlights = new ArrayList<HighlightInfo>(highlightsCo);
final SeverityRegistrar severityRegistrar = SeverityRegistrar.getInstance(project);
final HighlightersRecycler infosToRemove = new HighlightersRecycler();
DaemonCodeAnalyzerImpl.processHighlights(document, project, null, startOffset, endOffset, new Processor<HighlightInfo>() {
DaemonCodeAnalyzerImpl.processHighlights(document, project, null, range.getStartOffset(), range.getEndOffset(), new Processor<HighlightInfo>() {
@Override
public boolean process(HighlightInfo info) {
if (info.group == group) {
RangeHighlighter highlighter = info.highlighter;
int endOffset = highlighter.getEndOffset();
int startOffset = highlighter.getStartOffset();
boolean willBeRemoved = endOffset == document.getTextLength() && range.getEndOffset() != document.getTextLength()
|| !range.contains(startOffset)
&& !range.containsRange(startOffset, endOffset);
int hiEnd = highlighter.getEndOffset();
int hiStart = highlighter.getStartOffset();
boolean willBeRemoved = hiEnd == document.getTextLength() && range.getEndOffset() == document.getTextLength()
|| range.intersects(hiStart, hiEnd);
if (willBeRemoved) {
infosToRemove.recycleHighlighter(highlighter);
info.highlighter = null;
@@ -403,10 +348,8 @@ public class UpdateHighlightersUtil {
if (isWarningCoveredByError(info, overlappingIntervals, severityRegistrar)) {
return true;
}
if (info.getStartOffset() < range.getStartOffset() || info.getEndOffset() > range.getEndOffset()) {
createOrReuseHighlighterFor(info, colorsScheme, document, group, psiFile, markup, infosToRemove,
ranges2markersCache,
severityRegistrar);
if (info.getStartOffset() >= range.getStartOffset() && info.getEndOffset() <= range.getEndOffset()) {
createOrReuseHighlighterFor(info, colorsScheme, document, group, psiFile, markup, infosToRemove, ranges2markersCache, severityRegistrar);
changed[0] = true;
}
return true;
@@ -35,8 +35,10 @@ import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiFile;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.Nullable;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -45,9 +47,8 @@ import java.beans.PropertyChangeListener;
* @author peter
*/
public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
private static final Key<AutoPopupState> STATE_KEY = Key.create("AutopopupSTATE_KEY");
public static boolean ourTestingAutopopup = false;
private boolean myAutopopupShown;
private boolean myGuard;
@Override
public Result beforeCharTyped(char c,
@@ -55,13 +56,14 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
Editor editor,
PsiFile file,
FileType fileType) {
if (myAutopopupShown && LookupManager.getActiveLookup(editor) == null) {
myGuard = true;
final AutoPopupState state = getAutoPopupState(editor);
if (state != null && LookupManager.getActiveLookup(editor) == null) {
state.changeGuard = true;
try {
EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, String.valueOf(c), true);
}
finally {
myGuard = false;
state.changeGuard = false;
}
return Result.STOP;
}
@@ -78,7 +80,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
return Result.CONTINUE;
}
if (myAutopopupShown || LookupManager.getActiveLookup(editor) != null) {
if (getAutoPopupState(editor) != null || LookupManager.getActiveLookup(editor) != null) {
return Result.CONTINUE;
}
@@ -98,21 +100,25 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
new CodeCompletionHandlerBase(CompletionType.BASIC, false, false).invoke(project, editor);
myAutopopupShown = true;
trackUserActivity(project, editor);
final AutoPopupState state = new AutoPopupState(project, editor);
editor.putUserData(STATE_KEY, state);
final Lookup lookup = LookupManager.getActiveLookup(editor);
if (lookup != null) {
lookup.addLookupListener(new LookupAdapter() {
@Override
public void itemSelected(LookupEvent event) {
myAutopopupShown = false;
final AutoPopupState state = getAutoPopupState(editor);
if (state != null) {
state.stopAutoPopup();
}
}
@Override
public void lookupCanceled(LookupEvent event) {
if (event.isCanceledExplicitly()) {
myAutopopupShown = false;
final AutoPopupState state = getAutoPopupState(editor);
if (event.isCanceledExplicitly() && state != null) {
state.stopAutoPopup();
}
}
});
@@ -127,82 +133,99 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
return Result.STOP;
}
private void trackUserActivity(Project project, final Editor editor) {
final MessageBusConnection connection = project.getMessageBus().connect();
connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() {
@Override
public void selectionChanged(FileEditorManagerEvent event) {
if (finishAutopopupCompletion(editor, false)) {
connection.disconnect();
}
}
});
editor.addEditorMouseListener(new EditorMouseAdapter() {
@Override
public void mouseClicked(EditorMouseEvent e) {
if (finishAutopopupCompletion(editor, false)) {
editor.removeEditorMouseListener(this);
}
}
});
editor.getCaretModel().addCaretListener(new CaretListener() {
@Override
public void caretPositionChanged(CaretEvent e) {
if (finishAutopopupCompletion(editor, false)) {
editor.getCaretModel().removeCaretListener(this);
}
}
});
editor.getSelectionModel().addSelectionListener(new SelectionListener() {
@Override
public void selectionChanged(SelectionEvent e) {
if (finishAutopopupCompletion(editor, false)) {
editor.getSelectionModel().removeSelectionListener(this);
}
}
});
editor.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
if (finishAutopopupCompletion(editor, false)) {
editor.getDocument().removeDocumentListener(this);
}
}
});
final LookupManager lookupManager = LookupManager.getInstance(project);
lookupManager.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() != null && finishAutopopupCompletion(editor, true)) {
lookupManager.removePropertyChangeListener(this);
}
}
});
@Nullable
private static AutoPopupState getAutoPopupState(Editor editor) {
return editor.getUserData(STATE_KEY);
}
private boolean finishAutopopupCompletion(Editor editor, boolean neglectLookup) {
if (!myAutopopupShown) {
return true; //to disconnect all the listeners
}
if (myGuard) {
return false;
private static void finishAutopopupCompletion(Editor editor, boolean neglectLookup) {
final AutoPopupState state = getAutoPopupState(editor);
if (state == null || state.changeGuard) {
return;
}
if (!neglectLookup && LookupManager.getActiveLookup(editor) != null) { //the events during visible lookup period are handled separately
return false;
return;
}
myAutopopupShown = false;
final CompletionProgressIndicator currentCompletion = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
if (currentCompletion != null) {
currentCompletion.closeAndFinish(true);
}
return true;
state.stopAutoPopup();
}
private static class AutoPopupState {
final Editor editor;
final Project project;
final MessageBusConnection connection;
final EditorMouseAdapter mouseListener;
final CaretListener caretListener;
final DocumentAdapter documentListener;
final PropertyChangeListener lookupListener;
boolean changeGuard = false;
private AutoPopupState(final Project project, final Editor editor) {
this.editor = editor;
this.project = project;
connection = project.getMessageBus().connect();
connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() {
@Override
public void selectionChanged(FileEditorManagerEvent event) {
finishAutopopupCompletion(editor, false);
}
});
mouseListener = new EditorMouseAdapter() {
@Override
public void mouseClicked(EditorMouseEvent e) {
finishAutopopupCompletion(editor, false);
}
};
caretListener = new CaretListener() {
@Override
public void caretPositionChanged(CaretEvent e) {
finishAutopopupCompletion(editor, false);
}
};
editor.getSelectionModel().addSelectionListener(new SelectionListener() {
@Override
public void selectionChanged(SelectionEvent e) {
finishAutopopupCompletion(editor, false);
}
});
documentListener = new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
finishAutopopupCompletion(editor, false);
}
};
lookupListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() != null) {
finishAutopopupCompletion(editor, true);
}
}
};
editor.addEditorMouseListener(mouseListener);
editor.getCaretModel().addCaretListener(caretListener);
editor.getDocument().addDocumentListener(documentListener);
LookupManager.getInstance(project).addPropertyChangeListener(lookupListener);
}
void stopAutoPopup() {
connection.disconnect();
editor.removeEditorMouseListener(mouseListener);
editor.getCaretModel().removeCaretListener(caretListener);
editor.getDocument().removeDocumentListener(documentListener);
LookupManager.getInstance(project).removePropertyChangeListener(lookupListener);
editor.putUserData(STATE_KEY, null);
}
}
}
@@ -321,7 +321,7 @@ class IntentionListStep implements ListPopupStep<IntentionActionWithTextCaching>
final IntentionAction action = value.getAction();
Object iconable = null;
Object iconable = action;
//custom icon
if (action instanceof QuickFixWrapper) {
iconable = ((QuickFixWrapper)action).getFix();
@@ -16,6 +16,9 @@
package com.intellij.codeInsight.lookup;
import org.jetbrains.annotations.Nullable;
import java.util.Comparator;
import java.util.List;
/**
@@ -28,9 +31,6 @@ public abstract class LookupArranger {
return 0;
}
@Override
public void sortItems(List<LookupElement> items) {
}
};
public abstract Comparable getRelevance(LookupElement element);
@@ -42,5 +42,8 @@ public abstract class LookupArranger {
return 0;
}
public abstract void sortItems(List<LookupElement> items);
@Nullable
public Comparator<LookupElement> getItemComparator() {
return null; //don't sort
}
}
@@ -38,15 +38,6 @@ public class BackspaceHandler extends EditorActionHandler {
return;
}
boolean toRestart = false;
final String prefix = lookup.getAdditionalPrefix();
if (prefix.length() > 0) {
lookup.setAdditionalPrefix(prefix.substring(0, prefix.length() - 1));
}
else {
toRestart = lookup.getLookupStart() < editor.getCaretModel().getOffset();
}
lookup.performGuardedChange(new Runnable() {
@Override
public void run() {
@@ -54,11 +45,13 @@ public class BackspaceHandler extends EditorActionHandler {
}
});
final String prefix = lookup.getAdditionalPrefix();
if (prefix.length() > 0) {
lookup.setAdditionalPrefix(prefix.substring(0, prefix.length() - 1));
return;
}
if (toRestart) {
if (lookup.getLookupStart() < editor.getCaretModel().getOffset()) {
final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion();
if (process instanceof CompletionProgressIndicator) {
((CompletionProgressIndicator)process).restartCompletion();
@@ -33,6 +33,7 @@ import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
@@ -82,12 +83,9 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
private final LookupCellRenderer myCellRenderer;
private Boolean myPositionedAbove = null;
private CaretListener myEditorCaretListener;
private SelectionListener myEditorSelectionListener;
private EditorMouseListener myEditorMouseListener;
private final ArrayList<LookupListener> myListeners = new ArrayList<LookupListener>();
private boolean myShown = false;
private boolean myDisposed = false;
private boolean myHidden = false;
private LookupElement myPreselectedItem = EMPTY_LOOKUP_ITEM;
@@ -103,7 +101,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
private static final int LOOKUP_HEIGHT = Integer.getInteger("idea.lookup.height", 11).intValue();
private boolean myReused;
private boolean myChangeGuard;
private LookupModel myModel = new LookupModel(this);
private LookupModel myModel = new LookupModel();
public LookupImpl(Project project, Editor editor, @NotNull LookupArranger arranger){
super(new JPanel(new BorderLayout()));
@@ -139,10 +137,13 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
updateListHeight(model);
setArranger(arranger);
addListeners();
}
public void setArranger(LookupArranger arranger) {
myArranger = arranger;
myModel.setArranger(arranger);
}
public boolean isFocused() {
@@ -265,29 +266,15 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
ApplicationManager.getApplication().assertIsDispatchThread();
}
final List<LookupElement> items = myModel.getSortedItems();
SortedMap<Comparable, List<LookupElement>> itemsMap = new TreeMap<Comparable, List<LookupElement>>();
int minPrefixLength = items.isEmpty() ? 0 : Integer.MAX_VALUE;
for (final LookupElement item : items) {
minPrefixLength = Math.min(item.getPrefixMatcher().getPrefix().length(), minPrefixLength);
final Comparable relevance = myArranger.getRelevance(item);
List<LookupElement> list = itemsMap.get(relevance);
if (list == null) {
itemsMap.put(relevance, list = new ArrayList<LookupElement>());
}
list.add(item);
}
if (myReused) {
myModel.collectGarbage();
myReused = false;
}
if (myMinPrefixLength != minPrefixLength) {
myLookupStartMarker = null;
}
myMinPrefixLength = minPrefixLength;
final Pair<List<LookupElement>,List<List<LookupElement>>> snapshot = myModel.getModelSnapshot();
final List<LookupElement> items = snapshot.first;
checkMinPrefixLengthChanges(items);
LookupElement oldSelected = mySelectionTouched ? (LookupElement)myList.getSelectedValue() : null;
String oldInvariant = mySelectionInvariant;
@@ -302,7 +289,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
Set<LookupElement> firstItems = new THashSet<LookupElement>();
hasExactPrefixes = addExactPrefixItems(model, firstItems, items);
addMostRelevantItems(model, firstItems, itemsMap.values());
addMostRelevantItems(model, firstItems, snapshot.second);
hasPreselectedItem = addPreselectedItem(model, firstItems, preselectedItem);
myPreferredItemsCount = firstItems.size();
@@ -334,6 +321,18 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
}
}
private void checkMinPrefixLengthChanges(List<LookupElement> items) {
int minPrefixLength = items.isEmpty() ? 0 : Integer.MAX_VALUE;
for (final LookupElement item : items) {
minPrefixLength = Math.min(item.getPrefixMatcher().getPrefix().length(), minPrefixLength);
}
if (myMinPrefixLength != minPrefixLength) {
myLookupStartMarker = null;
}
myMinPrefixLength = minPrefixLength;
}
private void restoreSelection(@Nullable LookupElement oldSelected, boolean choosePreselectedItem, @Nullable String oldInvariant) {
if (oldSelected != null) {
if (oldSelected.isValid() && ListScrollingUtil.selectItem(myList, oldSelected)) {
@@ -549,13 +548,6 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
return myLookupStartMarker.getStartOffset();
}
@Override
protected void beforeShow() {
if (isRealPopup()) {
getComponent().setBorder(null);
}
}
public void performGuardedChange(Runnable change) {
assert !myChangeGuard;
myChangeGuard = true;
@@ -567,10 +559,28 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
}
}
public boolean isShown() {
return myShown;
}
public void show(){
ApplicationManager.getApplication().assertIsDispatchThread();
assert !myDisposed;
LOG.assertTrue(!myDisposed);
LOG.assertTrue(!myShown);
myShown = true;
if (ApplicationManager.getApplication().isUnitTestMode()) return;
getComponent().setBorder(null);
Point p = calculatePosition();
HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl();
hintManager.showEditorHint(this, myEditor, p, HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false);
myShownStamp = System.currentTimeMillis();
}
private void addListeners() {
myEditor.getDocument().addDocumentListener(new DocumentAdapter() {
public void documentChanged(DocumentEvent e) {
if (!myChangeGuard) {
@@ -579,29 +589,41 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
}
}, this);
myEditorCaretListener = new CaretListener() {
final CaretListener caretListener = new CaretListener() {
public void caretPositionChanged(CaretEvent e){
caretOrSelectionChanged();
if (!myChangeGuard) {
hide();
}
}
};
myEditorSelectionListener = new SelectionListener() {
final SelectionListener selectionListener = new SelectionListener() {
public void selectionChanged(final SelectionEvent e) {
caretOrSelectionChanged();
if (!myChangeGuard) {
hide();
}
}
};
myEditor.getCaretModel().addCaretListener(myEditorCaretListener);
myEditor.getSelectionModel().addSelectionListener(myEditorSelectionListener);
myEditorMouseListener = new EditorMouseAdapter() {
final EditorMouseListener mouseListener = new EditorMouseAdapter() {
public void mouseClicked(EditorMouseEvent e){
e.consume();
hide();
}
};
myEditor.addEditorMouseListener(myEditorMouseListener);
myEditor.getCaretModel().addCaretListener(caretListener);
myEditor.getSelectionModel().addSelectionListener(selectionListener);
myEditor.addEditorMouseListener(mouseListener);
Disposer.register(this, new Disposable() {
@Override
public void dispose() {
myEditor.getCaretModel().removeCaretListener(caretListener);
myEditor.getSelectionModel().removeSelectionListener(selectionListener);
myEditor.removeEditorMouseListener(mouseListener);
}
});
myList.addListSelectionListener(new ListSelectionListener() {
private LookupElement oldItem = null;
private LookupElement oldItem = null;
public void valueChanged(ListSelectionEvent e){
LookupElement item = getCurrentItem();
@@ -621,7 +643,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
final int i = myList.locationToIndex(point);
if (i >= 0) {
final LookupElement selected = (LookupElement)myList.getModel().getElementAt(i);
if (selected != null &&
if (selected != null &&
e.getClickCount() == 1 &&
point.x >= myList.getCellBounds(i, i).width - PopupIcons.EMPTY_ICON.getIconWidth() &&
ShowLookupActionsHandler.showItemActions(LookupImpl.this, selected)) {
@@ -638,20 +660,6 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
}
}
});
if (ApplicationManager.getApplication().isUnitTestMode()) return;
Point p = calculatePosition();
HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl();
hintManager.showEditorHint(this, myEditor, p, HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false);
myShownStamp = System.currentTimeMillis();
}
private void caretOrSelectionChanged() {
if (!myChangeGuard) {
hide();
}
}
private int calcLookupStart() {
@@ -920,16 +928,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
assert !myDisposed;
Disposer.dispose(myProcessIcon);
if (myEditorCaretListener != null) {
myEditor.getCaretModel().removeCaretListener(myEditorCaretListener);
myEditor.getSelectionModel().removeSelectionListener(myEditorSelectionListener);
myEditorCaretListener = null;
myEditorSelectionListener = null;
}
if (myEditorMouseListener != null) {
myEditor.removeEditorMouseListener(myEditorMouseListener);
myEditorMouseListener = null;
}
myDisposed = true;
}
@@ -15,13 +15,18 @@
*/
package com.intellij.codeInsight.lookup.impl;
import com.intellij.codeInsight.lookup.LookupArranger;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementAction;
import com.intellij.codeInsight.lookup.LookupElementPresentation;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.SortedList;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
@@ -30,16 +35,20 @@ import java.util.*;
* @author peter
*/
public class LookupModel {
private static final Comparator<LookupElement> COMMUNISM = new Comparator<LookupElement>() {
@SuppressWarnings({"ComparatorMethodParameterNotUsed"})
@Override
public int compare(LookupElement o1, LookupElement o2) {
return 0;
}
};
private final Object lock = new Object();
@SuppressWarnings({"unchecked"}) private final Map<LookupElement, Collection<LookupElementAction>> myItemActions = new THashMap<LookupElement, Collection<LookupElementAction>>(TObjectHashingStrategy.IDENTITY);
@SuppressWarnings({"unchecked"}) private final Map<LookupElement, String> myItemPresentations = new THashMap<LookupElement, String>(TObjectHashingStrategy.IDENTITY);
private final List<LookupElement> myItems = new ArrayList<LookupElement>();
@Nullable private List<LookupElement> mySortedItems;
private final LookupImpl myLookup;
public LookupModel(LookupImpl lookup) {
myLookup = lookup;
}
private SortedList<LookupElement> mySortedItems;
private TreeMap<Comparable, SortedList<LookupElement>> myRelevanceGroups;
private LookupArranger myArranger;
@TestOnly
public List<LookupElement> getItems() {
@@ -49,14 +58,22 @@ public class LookupModel {
public void clearItems() {
synchronized (lock) {
myItems.clear();
mySortedItems = null;
mySortedItems.clear();
myRelevanceGroups.clear();
}
}
public void addItem(LookupElement item) {
synchronized (lock) {
myItems.add(item);
mySortedItems = null;
mySortedItems.add(item);
final Comparable relevance = myArranger.getRelevance(item);
SortedList<LookupElement> group = myRelevanceGroups.get(relevance);
if (group == null) {
myRelevanceGroups.put(relevance, group = new SortedList<LookupElement>(mySortedItems.getComparator()));
}
group.add(item);
}
}
@@ -87,36 +104,54 @@ public class LookupModel {
}
}
@NotNull
public List<LookupElement> getSortedItems() {
public Pair<List<LookupElement>, List<List<LookupElement>>> getModelSnapshot() {
synchronized (lock) {
List<LookupElement> sortedItems = mySortedItems;
if (sortedItems == null) {
myLookup.getArranger().sortItems(sortedItems = new ArrayList<LookupElement>(myItems));
mySortedItems = sortedItems;
}
return sortedItems;
final List<LookupElement> sorted = new ArrayList<LookupElement>(mySortedItems);
final List<List<LookupElement>> relevanceGroups = ContainerUtil.map(myRelevanceGroups.values(), new Function<SortedList<LookupElement>, List<LookupElement>>() {
@Override
public List<LookupElement> fun(SortedList<LookupElement> lookupElements) {
return new ArrayList<LookupElement>(lookupElements);
}
});
return Pair.create(sorted, relevanceGroups);
}
}
public void collectGarbage() {
synchronized (lock) {
myItemActions.keySet().retainAll(myItems);
myItemPresentations.keySet().retainAll(myItems);
Set<LookupElement> itemSet = new THashSet<LookupElement>(myItems, TObjectHashingStrategy.IDENTITY);
myItemActions.keySet().retainAll(itemSet);
myItemPresentations.keySet().retainAll(itemSet);
}
}
void retainMatchingItems(String newPrefix) {
void retainMatchingItems(final String newPrefix) {
synchronized (lock) {
for (Iterator<LookupElement> iterator = myItems.iterator(); iterator.hasNext();) {
LookupElement item = iterator.next();
if (!item.setPrefixMatcher(item.getPrefixMatcher().cloneWithPrefix(newPrefix))) {
iterator.remove();
mySortedItems = null;
final List<LookupElement> newItems = ContainerUtil.findAll(myItems, new Condition<LookupElement>() {
@Override
public boolean value(LookupElement item) {
return item.isValid() && item.setPrefixMatcher(item.getPrefixMatcher().cloneWithPrefix(newPrefix));
}
});
if (newItems.size() == myItems.size()) {
return;
}
clearItems();
for (LookupElement newItem : newItems) {
addItem(newItem);
}
}
}
public void setArranger(final LookupArranger arranger) {
synchronized (lock) {
myArranger = arranger;
final Comparator<LookupElement> comparator = arranger.getItemComparator();
mySortedItems = new SortedList<LookupElement>(comparator == null ? COMMUNISM : comparator);
myRelevanceGroups = new TreeMap<Comparable, SortedList<LookupElement>>();
}
}
}
@@ -58,7 +58,6 @@ public class TypedHandler implements TypedActionHandler {
}
});
if (result == CharFilter.Result.ADD_TO_PREFIX) {
lookup.setAdditionalPrefix(lookup.getAdditionalPrefix() + charTyped);
Document document = editor.getDocument();
long modificationStamp = document.getModificationStamp();
@@ -67,6 +66,7 @@ public class TypedHandler implements TypedActionHandler {
EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, String.valueOf(charTyped), true);
}
});
lookup.setAdditionalPrefix(lookup.getAdditionalPrefix() + charTyped);
AutoHardWrapHandler.getInstance().wrapLineIfNecessary(editor, dataContext, modificationStamp);
@@ -125,7 +125,17 @@ public class TemplateState implements Disposable {
public void beforeCommandFinished(CommandEvent event) {
if (started) {
afterChangedUpdate();
Runnable runnable = new Runnable() {
public void run() {
afterChangedUpdate();
}
};
final LookupImpl lookup = myEditor != null ? (LookupImpl)LookupManager.getActiveLookup(myEditor) : null;
if (lookup != null) {
lookup.performGuardedChange(runnable);
} else {
runnable.run();
}
}
}
};
@@ -73,7 +73,7 @@ public final class LocalInspectionToolWrapper extends DescriptorProviderInspecti
}
});
myTool.inspectionFinished(session);
myTool.inspectionFinished(session, holder);
addProblemDescriptors(holder.getResults(), filterSuppressed);
}
@@ -85,7 +85,7 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode {
for (PsiElement el : elementsInRange) {
el.accept(visitor);
}
localInspectionTool.inspectionFinished(session);
localInspectionTool.inspectionFinished(session, holder);
if (holder.hasResults()) {
final List<ProblemDescriptor> list = holder.getResults();
final int idx = offlineProblemDescriptor.getProblemIndex();
@@ -127,6 +127,9 @@ public class ProjectRunConfigurationManager implements ProjectComponent, Persist
}
}
}
// IDEA-60004: configs may never be sorted before write, so call it manually after shared configs read
myManager.getSortedConfigurations();
}
public void writeExternal(Element element) throws WriteExternalException {
@@ -201,7 +201,7 @@ public class PsiCopyPasteManager {
return getDataAsText();
}
if (DataFlavor.javaFileListFlavor.equals(flavor)) {
ApplicationManager.getApplication().runReadAction(new Computable<List<File>>() {
return ApplicationManager.getApplication().runReadAction(new Computable<List<File>>() {
@Override
public List<File> compute() {
return asFileList(myDataProxy.getElements());
@@ -18,9 +18,7 @@ package com.intellij.ide.actions;
import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.util.gotoByName.ChooseByNamePopup;
import com.intellij.ide.util.gotoByName.ChooseByNamePopupComponent;
import com.intellij.ide.util.gotoByName.GotoClassModel2;
import com.intellij.ide.util.gotoByName.*;
import com.intellij.navigation.ChooseByNameRegistry;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -48,13 +46,16 @@ public class GotoClassAction extends GotoActionBase implements DumbAware {
FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.class");
PsiDocumentManager.getInstance(project).commitAllDocuments();
final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, new GotoClassModel2(project), getPsiContext(e));
final GotoClassModel2 model = new GotoClassModel2(project);
final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, model, getPsiContext(e));
final ChooseByNameFilter filterUI = new ChooseByNameLanguageFilter(popup, model, GotoClassSymbolConfiguration.getInstance(project), project);
popup.invoke(new ChooseByNamePopupComponent.Callback() {
public void onClose() {
if (GotoClassAction.class.equals(myInAction)) {
myInAction = null;
}
filterUI.close();
}
public void elementChosen(Object element) {
@@ -17,11 +17,9 @@
package com.intellij.ide.actions;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.ide.util.gotoByName.ChooseByNamePopup;
import com.intellij.ide.util.gotoByName.ChooseByNamePopupComponent;
import com.intellij.ide.util.gotoByName.GotoFileModel;
import com.intellij.openapi.actionSystem.*;
import com.intellij.ide.util.gotoByName.*;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -29,21 +27,11 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.IconLoader;
import com.intellij.psi.PsiFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -63,7 +51,7 @@ public class GotoFileAction extends GotoActionBase implements DumbAware {
final Project project = e.getData(PlatformDataKeys.PROJECT);
final GotoFileModel gotoFileModel = new GotoFileModel(project);
final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, gotoFileModel, getPsiContext(e));
final FilterUI filterUI = new FilterUI(popup, gotoFileModel, project);
final ChooseByNameFilter filterUI = new GotoFileFilter(popup, gotoFileModel, project);
popup.invoke(new ChooseByNamePopupComponent.Callback() {
public void onClose() {
if (GotoFileAction.class.equals(myInAction)) {
@@ -88,227 +76,61 @@ public class GotoFileAction extends GotoActionBase implements DumbAware {
}, ModalityState.current(), true);
}
/**
* This class contains UI related to filtering functionality.
*/
private static class FilterUI {
/**
* an icon to use
*/
private static final Icon FILTER_ICON = IconLoader.getIcon("/icons/inspector/useFilter.png");
/**
* a parent popup
*/
final ChooseByNamePopup myParentPopup;
/**
* action toolbar
*/
final ActionToolbar myToolbar;
/**
* a file type chooser, only one instance is used
*/
final ElementsChooser<FileType> myChooser;
/**
* A panel that contains chooser
*/
final JPanel myChooserPanel;
/**
* a file type popup, the value is non-null if popup is active
*/
JBPopup myPopup;
/**
* a project to use. The project is used for dimension service.
*/
final Project myProject;
/**
* A constuctor
*
* @param popup a parent popup
* @param gotoFileModel a model for popup
* @param project a context project
*/
FilterUI(final ChooseByNamePopup popup, final GotoFileModel gotoFileModel, final Project project) {
myParentPopup = popup;
DefaultActionGroup actionGroup = new DefaultActionGroup("go.to.file.filter", false);
ToggleAction action = new ToggleAction("Filter", "Filter files by type", FILTER_ICON) {
public boolean isSelected(final AnActionEvent e) {
return myPopup != null;
}
public void setSelected(final AnActionEvent e, final boolean state) {
if (state) {
createPopup();
}
else {
close();
}
}
};
actionGroup.add(action);
myToolbar = ActionManager.getInstance().createActionToolbar("gotfile.filter", actionGroup, true);
myToolbar.setLayoutPolicy(ActionToolbar.NOWRAP_LAYOUT_POLICY);
myToolbar.updateActionsImmediately();
myToolbar.getComponent().setFocusable(false);
myToolbar.getComponent().setBorder(null);
myProject = project;
myChooser = createFileTypeChooser(gotoFileModel);
myChooserPanel = createChooserPanel();
popup.setToolArea(myToolbar.getComponent());
protected static class GotoFileFilter extends ChooseByNameFilter<FileType> {
GotoFileFilter(final ChooseByNamePopup popup, GotoFileModel model, final Project project) {
super(popup, model, GotoFileConfiguration.getInstance(project), project);
}
/**
* @return a panel with chooser and buttons
*/
private JPanel createChooserPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(myChooser);
JPanel buttons = new JPanel();
JButton all = new JButton("All");
all.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
myChooser.setAllElementsMarked(true);
}
});
buttons.add(all);
JButton none = new JButton("None");
none.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
myChooser.setAllElementsMarked(false);
}
});
buttons.add(none);
JButton invert = new JButton("Invert");
invert.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final int count = myChooser.getElementCount();
for (int i = 0; i < count; i++) {
FileType type = myChooser.getElementAt(i);
myChooser.setElementMarked(type, !myChooser.isElementMarked(type));
}
}
});
buttons.add(invert);
panel.add(buttons);
return panel;
}
/**
* Create a file type chooser
*
* @param gotoFileModel a model to update
* @return a created file chooser
*/
private ElementsChooser<FileType> createFileTypeChooser(final GotoFileModel gotoFileModel) {
protected List<FileType> getAllFilterValues() {
List<FileType> elements = new ArrayList<FileType>();
ContainerUtil.addAll(elements, FileTypeManager.getInstance().getRegisteredFileTypes());
Collections.sort(elements, FileTypeComparator.INSTANCE);
final ElementsChooser<FileType> chooser = new ElementsChooser<FileType>(elements, true) {
@Override
protected String getItemText(@NotNull final FileType value) {
return value.getName();
}
@Override
protected Icon getItemIcon(final FileType value) {
return value.getIcon();
}
};
chooser.setFocusable(false);
final GotoFileConfiguration config = GotoFileConfiguration.getInstance(myProject);
final int count = chooser.getElementCount();
for (int i = 0; i < count; i++) {
FileType type = chooser.getElementAt(i);
if (!DumbService.getInstance(myProject).isDumb() && !config.isFileTypeVisible(type)) {
chooser.setElementMarked(type, false);
}
}
updateModel(gotoFileModel, chooser);
chooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener<FileType>() {
public void elementMarkChanged(final FileType element, final boolean isMarked) {
config.setFileTypeVisible(element, isMarked);
updateModel(gotoFileModel, chooser);
}
});
return chooser;
return elements;
}
/**
* Update model basing on the chooser state
*
* @param gotoFileModel a model
* @param chooser a file type chooser
*/
private void updateModel(final GotoFileModel gotoFileModel, ElementsChooser<FileType> chooser) {
final List<FileType> markedElements = chooser.getMarkedElements();
gotoFileModel.setFileTypes(markedElements.toArray(new FileType[markedElements.size()]));
myParentPopup.rebuildList();
protected String textForFilterValue(FileType value) {
return value.getName();
}
/**
* Create and show popup
*/
private void createPopup() {
if (myPopup != null) {
return;
}
myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(myChooserPanel, myChooser).setModalContext(false).setFocusable(false)
.setResizable(true).setCancelOnClickOutside(false).setMinSize(new Dimension(200, 200))
.setDimensionServiceKey(myProject, "GotoFile_FileTypePopup", false).createPopup();
myPopup.addListener(new JBPopupListener.Adapter() {
public void onClosed(LightweightWindowEvent event) {
myPopup = null;
}
});
myPopup.showUnderneathOf(myToolbar.getComponent());
protected Icon iconForFilterValue(FileType value) {
return value.getIcon();
}
}
/**
* A file type comparator. The comparison rules are applied in the following order.
* <ol>
* <li>Unknown file type is greatest.</li>
* <li>Text files are less then binary ones.</li>
* <li>File type with greater name is greater (case is ignored).</li>
* </ol>
*/
static class FileTypeComparator implements Comparator<FileType> {
/**
* an instance of comparator
*/
static final Comparator<FileType> INSTANCE = new FileTypeComparator();
/**
* close the file type filter
* {@inheritDoc}
*/
public void close() {
if (myPopup != null) {
myPopup.dispose();
public int compare(final FileType o1, final FileType o2) {
if (o1 == o2) {
return 0;
}
}
/**
* A file type comparator. The comparison rules are applied in the following order.
* <ol>
* <li>Unknown file type is greatest.</li>
* <li>Text files are less then binary ones.</li>
* <li>File type with greater name is greater (case is ignored).</li>
* </ol>
*/
static class FileTypeComparator implements Comparator<FileType> {
/**
* an instance of comparator
*/
static final Comparator<FileType> INSTANCE = new FileTypeComparator();
/**
* {@inheritDoc}
*/
public int compare(final FileType o1, final FileType o2) {
if (o1 == o2) {
return 0;
}
if (o1 == FileTypes.UNKNOWN) {
return 1;
}
if (o2 == FileTypes.UNKNOWN) {
return -1;
}
if (o1.isBinary() && !o2.isBinary()) {
return 1;
}
if (!o1.isBinary() && o2.isBinary()) {
return -1;
}
return o1.getName().compareToIgnoreCase(o2.getName());
if (o1 == FileTypes.UNKNOWN) {
return 1;
}
if (o2 == FileTypes.UNKNOWN) {
return -1;
}
if (o1.isBinary() && !o2.isBinary()) {
return 1;
}
if (!o1.isBinary() && o2.isBinary()) {
return -1;
}
return o1.getName().compareToIgnoreCase(o2.getName());
}
}
}
@@ -17,9 +17,7 @@
package com.intellij.ide.actions;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.util.gotoByName.ChooseByNamePopup;
import com.intellij.ide.util.gotoByName.ChooseByNamePopupComponent;
import com.intellij.ide.util.gotoByName.GotoSymbolModel2;
import com.intellij.ide.util.gotoByName.*;
import com.intellij.navigation.NavigationItem;
import com.intellij.navigation.ChooseByNameRegistry;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -37,14 +35,18 @@ public class GotoSymbolAction extends GotoActionBase {
PsiDocumentManager.getInstance(project).commitAllDocuments();
final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, new GotoSymbolModel2(project), getPsiContext(e));
final GotoSymbolModel2 model = new GotoSymbolModel2(project);
final ChooseByNamePopup popup = ChooseByNamePopup.createPopup(project, model, getPsiContext(e));
final ChooseByNameFilter filterUI = new ChooseByNameLanguageFilter(popup, model, GotoClassSymbolConfiguration.getInstance(project),
project);
popup.invoke(new ChooseByNamePopupComponent.Callback() {
public void onClose ()
{
if (GotoSymbolAction.class.equals (myInAction)) {
public void onClose() {
if (GotoSymbolAction.class.equals(myInAction)) {
myInAction = null;
}
filterUI.close();
}
public void elementChosen(Object element) {
((NavigationItem)element).navigate(true);
}
@@ -18,6 +18,7 @@ package com.intellij.ide.scriptingContext;
import com.intellij.lang.Language;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.roots.libraries.LibraryType;
import org.jetbrains.annotations.NotNull;
/**
@@ -31,6 +32,8 @@ public abstract class LangScriptingContextProvider {
@NotNull
public abstract Language getLanguage();
public abstract LibraryType getLibraryType();
public abstract boolean acceptsExtension(String fileExt);
@NotNull
@@ -16,6 +16,7 @@
package com.intellij.ide.scriptingContext.ui;
import com.intellij.ide.scriptingContext.LangScriptingContextProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
@@ -44,7 +45,7 @@ public class ScriptingLibrariesPanel {
public ScriptingLibrariesPanel(LangScriptingContextProvider provider, Project project, LibraryTable libTable) {
myProvider = provider;
myLibTableModel = new ScriptingLibraryTableModel(libTable);
myLibTableModel = new ScriptingLibraryTableModel(libTable, provider.getLibraryType());
myLibraryTable.setModel(myLibTableModel);
myAddLibraryButton.addActionListener(new ActionListener(){
@Override
@@ -56,7 +57,7 @@ public class ScriptingLibrariesPanel {
@Override
public void actionPerformed(ActionEvent e) {
if (mySelectedLibName != null) {
myLibTableModel.removeLibrary(mySelectedLibName);
removeLibrary(mySelectedLibName);
}
}
});
@@ -85,11 +86,20 @@ public class ScriptingLibrariesPanel {
return myTopPanel;
}
private void removeLibrary(final String libName) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myLibTableModel.removeLibrary(libName);
}
});
}
private void addLibrary() {
EditLibraryDialog editLibDialog = new EditLibraryDialog("New Library", myProvider, myProject);
editLibDialog.show();
if (editLibDialog.isOK()) {
myLibTableModel.createLibrary(editLibDialog.getLibName(), editLibDialog.getFiles());
myLibTableModel.createLibrary(editLibDialog.getLibName(), myProvider.getLibraryType(), editLibDialog.getFiles());
}
}
@@ -121,8 +131,8 @@ public class ScriptingLibrariesPanel {
EditLibraryDialog editLibDialog = new EditLibraryDialog("Edit Library", myProvider, myProject, lib);
editLibDialog.show();
if (editLibDialog.isOK()) {
myLibTableModel.removeLibrary(lib.getName());
myLibTableModel.createLibrary(editLibDialog.getLibName(), editLibDialog.getFiles());
removeLibrary(lib.getName());
myLibTableModel.createLibrary(editLibDialog.getLibName(), myProvider.getLibraryType(), editLibDialog.getFiles());
}
}
}
@@ -15,9 +15,12 @@
*/
package com.intellij.ide.scriptingContext.ui;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.impl.libraries.LibraryTableBase;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryType;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
@@ -31,26 +34,29 @@ public class ScriptingLibraryTableModel extends AbstractTableModel {
private static final int LIB_NAME_COL = 0;
private LibraryTable myLibTable;
private LibraryTable.ModifiableModel myLibTableModel;
private boolean myTableChanged;
//private LibraryTable myLibTable;
private TypedLibraryTableWrapper myTableWrapper;
private LibraryTableBase.ModifiableModelEx myLibTableModel;
private LibraryType myLibraryType;
public ScriptingLibraryTableModel(LibraryTable libTable) {
myLibTable = libTable;
myLibTableModel = libTable.getModifiableModel();
myTableChanged = false;
public ScriptingLibraryTableModel(LibraryTable libTable, LibraryType libraryType) {
LibraryTable.ModifiableModel model = libTable.getModifiableModel();
if (model instanceof LibraryTableBase.ModifiableModelEx) {
myTableWrapper = new TypedLibraryTableWrapper(libTable, libraryType);
myLibTableModel = (LibraryTableBase.ModifiableModelEx)model;
myLibraryType = libraryType;
}
}
public void resetTable(LibraryTable libTable) {
myLibTable = libTable;
myTableChanged = false;
myTableWrapper = new TypedLibraryTableWrapper(libTable, myLibraryType);
fireTableDataChanged();
}
@Override
public int getRowCount() {
if (myLibTable != null) {
return myLibTable.getLibraries().length;
if (myTableWrapper != null) {
return myTableWrapper.getLibCount();
}
return 0;
}
@@ -62,8 +68,10 @@ public class ScriptingLibraryTableModel extends AbstractTableModel {
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Library lib = myTableWrapper.getLibraryAt(rowIndex);
assert lib != null;
if (columnIndex == LIB_NAME_COL) {
return myLibTable.getLibraries()[rowIndex].getName();
return lib.getName();
}
return "?";
}
@@ -76,44 +84,48 @@ public class ScriptingLibraryTableModel extends AbstractTableModel {
return "?";
}
public void createLibrary(String name, VirtualFile[] files) {
Library lib = myLibTable.createLibrary(name);
Library.ModifiableModel libModel = lib.getModifiableModel();
for (VirtualFile file : files) {
libModel.addRoot(file, OrderRootType.CLASSES);
}
libModel.commit();
myLibTableModel.commit();
fireLibTableChanged();
public void createLibrary(final String name, final LibraryType libType, final VirtualFile[] files) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
Library lib = myLibTableModel.createLibrary(name, libType);
Library.ModifiableModel libModel = lib.getModifiableModel();
for (VirtualFile file : files) {
libModel.addRoot(file, OrderRootType.CLASSES);
}
libModel.commit();
myLibTableModel.commit();
fireLibTableChanged();
}
});
}
@Nullable
public Library getLibrary(String name) {
return myLibTable == null ? null : myLibTable.getLibraryByName(name);
return myTableWrapper == null ? null : myTableWrapper.getLibraryByName(name);
}
public void removeLibrary(String name) {
Library libToRemove = myLibTable.getLibraryByName(name);
Library libToRemove = myTableWrapper.getLibraryByName(name);
if (libToRemove != null) {
myLibTable.removeLibrary(libToRemove);
myTableWrapper.removeLibrary(libToRemove);
fireLibTableChanged();
}
}
public void fireLibTableChanged() {
myTableChanged = true;
myTableWrapper.update();
fireTableDataChanged();
}
@Nullable
public String getLibNameAt(int row) {
Library[] libs = myLibTable.getLibraries();
if (row < 0 || row > libs.length - 1) return null;
return libs[row].getName();
Library lib = myTableWrapper.getLibraryAt(row);
return lib != null ? lib.getName() : null;
}
public boolean isChanged() {
return myTableChanged;
return myTableWrapper.isUpdated();
}
}
@@ -0,0 +1,90 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* 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.intellij.ide.scriptingContext.ui;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryType;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* @author Rustam Vishnyakov
*/
public class TypedLibraryTableWrapper {
private LibraryTable myLibraryTable;
private LibraryType myLibraryType;
private Library[] myLibs;
private boolean myIsUpdated;
public TypedLibraryTableWrapper(LibraryTable libraryTable, LibraryType libraryType) {
myLibraryTable = libraryTable;
myLibraryType = libraryType;
myLibs = getLibraries();
myIsUpdated = false;
}
private Library[] getLibraries() {
List<Library> libs = new ArrayList<Library>();
for (Library library : myLibraryTable.getLibraries()) {
if (library instanceof LibraryEx) {
LibraryType libraryType = ((LibraryEx)library).getType();
if (libraryType != null && libraryType.equals(myLibraryType)) {
libs.add(library);
}
}
}
return libs.toArray(new Library[libs.size()]);
}
public void update() {
myLibs = getLibraries();
myIsUpdated = true;
}
public int getLibCount() {
return myLibs.length;
}
@Nullable
public Library getLibraryAt(int index) {
if (index >= 0 && index < myLibs.length) {
return myLibs[index];
}
return null;
}
@Nullable
public Library getLibraryByName(String name) {
Library library = myLibraryTable.getLibraryByName(name);
if (library instanceof LibraryEx && ((LibraryEx)library).getType().equals(myLibraryType)) {
return library;
}
return null;
}
public void removeLibrary(Library libToRemove) {
myLibraryTable.removeLibrary(libToRemove);
}
public boolean isUpdated() {
return myIsUpdated;
}
}
@@ -19,7 +19,6 @@ package com.intellij.ide.structureView.newStructureView;
import com.intellij.ide.CopyPasteDelegator;
import com.intellij.ide.DataManager;
import com.intellij.ide.PsiCopyPasteManager;
import com.intellij.ide.actions.ContextHelpAction;
import com.intellij.ide.structureView.*;
import com.intellij.ide.structureView.impl.StructureViewFactoryImpl;
import com.intellij.ide.structureView.impl.StructureViewState;
@@ -50,6 +49,8 @@ import com.intellij.ui.AutoScrollToSourceHandler;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.ui.treeStructure.actions.CollapseAllAction;
import com.intellij.ui.treeStructure.actions.ExpandAllAction;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import com.intellij.util.EditSourceOnDoubleClickHandler;
@@ -384,14 +385,14 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
result.add(new TreeActionWrapper(filter, this));
}
result.add(new ExpandAllAction(getTree()));
result.add(new CollapseAllAction(getTree()));
if (showScrollToFromSourceActions()) {
result.addSeparator();
result.add(myAutoScrollToSourceHandler.createToggleAction());
result.add(myAutoScrollFromSourceHandler.createToggleAction());
}
result.addSeparator();
result.add(new ContextHelpAction(getHelpID()));
return result;
}
@@ -707,7 +708,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
public void doUpdate() {
assert ApplicationManager.getApplication().isUnitTestMode();
((StructureTreeBuilder)myAbstractTreeBuilder).addRootToUpdate();
myAbstractTreeBuilder.addRootToUpdate();
}
//todo [kirillk] dirty hack for discovering invalid psi elements, to delegate it to a proper place after 8.1
@@ -0,0 +1,232 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* 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.intellij.ide.util.gotoByName;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* This class contains UI related to filtering functionality.
*/
public abstract class ChooseByNameFilter<T> {
/**
* an icon to use
*/
private static final Icon FILTER_ICON = IconLoader.getIcon("/icons/inspector/useFilter.png");
/**
* a parent popup
*/
final ChooseByNamePopup myParentPopup;
/**
* action toolbar
*/
final ActionToolbar myToolbar;
/**
* a file type chooser, only one instance is used
*/
final ElementsChooser<T> myChooser;
/**
* A panel that contains chooser
*/
final JPanel myChooserPanel;
/**
* a file type popup, the value is non-null if popup is active
*/
JBPopup myPopup;
/**
* a project to use. The project is used for dimension service.
*/
final Project myProject;
/**
* A constuctor
*
* @param popup a parent popup
* @param model a model for popup
* @param filterConfiguration storage for selected filter values
* @param project a context project
*/
public ChooseByNameFilter(final ChooseByNamePopup popup, FilteringGotoByModel<T> model, ChooseByNameFilterConfiguration<T> filterConfiguration,
final Project project) {
myParentPopup = popup;
DefaultActionGroup actionGroup = new DefaultActionGroup("go.to.file.filter", false);
ToggleAction action = new ToggleAction("Filter", "Filter files by type", FILTER_ICON) {
public boolean isSelected(final AnActionEvent e) {
return myPopup != null;
}
public void setSelected(final AnActionEvent e, final boolean state) {
if (state) {
createPopup();
}
else {
close();
}
}
};
actionGroup.add(action);
myToolbar = ActionManager.getInstance().createActionToolbar("gotfile.filter", actionGroup, true);
myToolbar.setLayoutPolicy(ActionToolbar.NOWRAP_LAYOUT_POLICY);
myToolbar.updateActionsImmediately();
myToolbar.getComponent().setFocusable(false);
myToolbar.getComponent().setBorder(null);
myProject = project;
myChooser = createChooser(model, filterConfiguration);
myChooserPanel = createChooserPanel();
popup.setToolArea(myToolbar.getComponent());
}
/**
* @return a panel with chooser and buttons
*/
private JPanel createChooserPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(myChooser);
JPanel buttons = new JPanel();
JButton all = new JButton("All");
all.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
myChooser.setAllElementsMarked(true);
}
});
buttons.add(all);
JButton none = new JButton("None");
none.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
myChooser.setAllElementsMarked(false);
}
});
buttons.add(none);
JButton invert = new JButton("Invert");
invert.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final int count = myChooser.getElementCount();
for (int i = 0; i < count; i++) {
T type = myChooser.getElementAt(i);
myChooser.setElementMarked(type, !myChooser.isElementMarked(type));
}
}
});
buttons.add(invert);
panel.add(buttons);
return panel;
}
/**
* Create a file type chooser
*
*
* @param model a model to update
* @param filterConfiguration
* @return a created file chooser
*/
protected ElementsChooser<T> createChooser(final FilteringGotoByModel<T> model, final ChooseByNameFilterConfiguration<T> filterConfiguration) {
List<T> elements = new ArrayList<T>(getAllFilterValues());
final ElementsChooser<T> chooser = new ElementsChooser<T>(elements, true) {
@Override
protected String getItemText(@NotNull final T value) {
return textForFilterValue(value);
}
@Override
protected Icon getItemIcon(final T value) {
return iconForFilterValue(value);
}
};
chooser.setFocusable(false);
final int count = chooser.getElementCount();
for (int i = 0; i < count; i++) {
T type = chooser.getElementAt(i);
if (!DumbService.getInstance(myProject).isDumb() && !filterConfiguration.isFileTypeVisible(type)) {
chooser.setElementMarked(type, false);
}
}
updateModel(model, chooser);
chooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener<T>() {
public void elementMarkChanged(final T element, final boolean isMarked) {
filterConfiguration.setVisible(element, isMarked);
updateModel(model, chooser);
}
});
return chooser;
}
protected abstract String textForFilterValue(T value);
@Nullable
protected abstract Icon iconForFilterValue(T value);
protected abstract Collection<T> getAllFilterValues();
/**
* Update model basing on the chooser state
*
* @param gotoFileModel a model
* @param chooser a file type chooser
*/
protected void updateModel(final FilteringGotoByModel<T> gotoFileModel, ElementsChooser<T> chooser) {
final List<T> markedElements = chooser.getMarkedElements();
gotoFileModel.setFilterItems(markedElements);
myParentPopup.rebuildList();
}
/**
* Create and show popup
*/
private void createPopup() {
if (myPopup != null) {
return;
}
myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(myChooserPanel, myChooser).setModalContext(false).setFocusable(false)
.setResizable(true).setCancelOnClickOutside(false).setMinSize(new Dimension(200, 200))
.setDimensionServiceKey(myProject, "GotoFile_FileTypePopup", false).createPopup();
myPopup.addListener(new JBPopupListener.Adapter() {
public void onClosed(LightweightWindowEvent event) {
myPopup = null;
}
});
myPopup.showUnderneathOf(myToolbar.getComponent());
}
/**
* close the file type filter
*/
public void close() {
if (myPopup != null) {
Disposer.dispose(myPopup);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,15 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.actions;
package com.intellij.ide.util.gotoByName;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Tag;
@@ -29,33 +23,26 @@ import java.util.LinkedHashSet;
import java.util.Set;
/**
* Configuration for file type filtering popup in "Go to | File" action.
*
* @author Constantine.Plotnikov
* @author yole
*/
@State(
name = "GotoFileConfiguration",
storages = {@Storage(
id = "other",
file = "$WORKSPACE_FILE$")})
public class GotoFileConfiguration implements PersistentStateComponent<GotoFileConfiguration.FileTypes> {
public abstract class ChooseByNameFilterConfiguration<T> implements PersistentStateComponent<ChooseByNameFilterConfiguration.Items> {
/**
* state object for the configuration
*/
private FileTypes fileTypes = new FileTypes();
private Items items = new Items();
/**
* {@inheritDoc}
*/
public FileTypes getState() {
return fileTypes;
public Items getState() {
return items;
}
/**
* {@inheritDoc}
*/
public void loadState(final FileTypes state) {
fileTypes = state;
public void loadState(final Items state) {
items = state;
}
/**
@@ -64,39 +51,31 @@ public class GotoFileConfiguration implements PersistentStateComponent<GotoFileC
* @param type a type of the file to duptate
* @param value if false, a file type will be filtered out
*/
public void setFileTypeVisible(FileType type, boolean value) {
public void setVisible(T type, boolean value) {
if (value) {
fileTypes.getFilteredOutFileTypeNames().remove(type.getName());
items.getFilteredOutFileTypeNames().remove(nameForElement(type));
}
else {
fileTypes.getFilteredOutFileTypeNames().add(type.getName());
items.getFilteredOutFileTypeNames().add(nameForElement(type));
}
}
protected abstract String nameForElement(T type);
/**
* Check if file type should be filtered out
*
* @param type a file type to check
* @return false if file of the sepecified type should be filtered out
*/
public boolean isFileTypeVisible(FileType type) {
return !fileTypes.getFilteredOutFileTypeNames().contains(type.getName());
}
/**
* Get configuration instance
*
* @param project a project instance
* @return a configuration instance
*/
public static GotoFileConfiguration getInstance(Project project) {
return ServiceManager.getService(project, GotoFileConfiguration.class);
public boolean isFileTypeVisible(T type) {
return !items.getFilteredOutFileTypeNames().contains(nameForElement(type));
}
/**
* A state for this configuraiton
*/
public static class FileTypes {
public static class Items {
/**
* a set of file types
*/
@@ -0,0 +1,67 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* 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.intellij.ide.util.gotoByName;
import com.intellij.lang.DependentLanguage;
import com.intellij.lang.Language;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.*;
/**
* @author yole
*/
public class ChooseByNameLanguageFilter extends ChooseByNameFilter<Language> {
public ChooseByNameLanguageFilter(final ChooseByNamePopup popup,
FilteringGotoByModel<Language> languageFilteringGotoByModel,
ChooseByNameFilterConfiguration<Language> languageChooseByNameFilterConfiguration,
final Project project) {
super(popup, languageFilteringGotoByModel, languageChooseByNameFilterConfiguration, project);
}
@Override
protected String textForFilterValue(Language value) {
return value.getDisplayName();
}
@Nullable
@Override
protected Icon iconForFilterValue(Language value) {
final LanguageFileType fileType = value.getAssociatedFileType();
return fileType != null ? fileType.getIcon() : null;
}
@Override
protected Collection<Language> getAllFilterValues() {
final Collection<Language> registeredLanguages = Language.getRegisteredLanguages();
List<Language> accepted = new ArrayList<Language>();
for (Language language : registeredLanguages) {
if (language != Language.ANY && !(language instanceof DependentLanguage)) {
accepted.add(language);
}
}
Collections.sort(accepted, new Comparator<Language>() {
@Override
public int compare(Language o1, Language o2) {
return o1.getDisplayName().compareTo(o2.getDisplayName());
}
});
return accepted;
}
}
@@ -136,8 +136,9 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModel
}
/**
* This method allows exetending classes to introduce additional filtering criteria to model
* beyoud pattern and project/non-project files. The default implementation just returns true.
* This method allows extending classes to introduce additional filtering criteria to model
* beyond pattern and project/non-project files. The default implementation just returns true.
*
* @param item an item to filter
* @return true if the item is acceptable according to additional filtering criteria.
*/
@@ -0,0 +1,67 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* 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.intellij.ide.util.gotoByName;
import com.intellij.navigation.ChooseByNameContributor;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* @author yole
*/
public abstract class FilteringGotoByModel<T> extends ContributorsBasedGotoByModel {
/** current file types */
private Set<T> myFilterItems;
protected FilteringGotoByModel(Project project, ChooseByNameContributor[] contributors) {
super(project, contributors);
}
/**
* Set file types
* @param filterItems a file types to set
*/
public synchronized void setFilterItems(Collection<T> filterItems) {
// get and set method are called from different threads
myFilterItems = new HashSet<T>(filterItems);
}
/**
* @return get file types
*/
protected synchronized Collection<T> getFilterItems() {
// get and set method are called from different threads
return myFilterItems;
}
@Override
protected boolean acceptItem(final NavigationItem item) {
T filterValue = filterValueFor(item);
if (filterValue != null) {
final Collection<T> types = getFilterItems();
return types == null || types.contains(filterValue);
}
return true;
}
@Nullable
protected abstract T filterValueFor(NavigationItem item);
}
@@ -17,20 +17,27 @@ package com.intellij.ide.util.gotoByName;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.lang.Language;
import com.intellij.navigation.ChooseByNameContributor;
import com.intellij.navigation.ChooseByNameRegistry;
import com.intellij.navigation.GotoClassContributor;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class GotoClassModel2 extends ContributorsBasedGotoByModel {
public class GotoClassModel2 extends FilteringGotoByModel<Language> {
public GotoClassModel2(Project project) {
super(project, ChooseByNameRegistry.getInstance().getClassModelContributors());
}
@Override
protected Language filterValueFor(NavigationItem item) {
return item instanceof PsiElement ? ((PsiElement) item).getLanguage() : null;
}
@Nullable
public String getPromptText() {
return IdeBundle.message("prompt.gotoclass.enter.class.name");
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* 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.intellij.ide.util.gotoByName;
import com.intellij.lang.Language;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.project.Project;
/**
* @author yole
*/
@State(
name = "GotoFileConfiguration",
storages = {@Storage(
id = "other",
file = "$WORKSPACE_FILE$")})
public class GotoClassSymbolConfiguration extends ChooseByNameFilterConfiguration<Language> {
public static GotoClassSymbolConfiguration getInstance(Project project) {
return ServiceManager.getService(project, GotoClassSymbolConfiguration.class);
}
@Override
protected String nameForElement(Language type) {
return type.getID();
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.intellij.ide.util.gotoByName;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
/**
* Configuration for file type filtering popup in "Go to | File" action.
*
* @author Constantine.Plotnikov
*/
@State(
name = "GotoFileConfiguration",
storages = {@Storage(
id = "other",
file = "$WORKSPACE_FILE$")})
public class GotoFileConfiguration extends ChooseByNameFilterConfiguration<FileType> {
/**
* Get configuration instance
*
* @param project a project instance
* @return a configuration instance
*/
public static GotoFileConfiguration getInstance(Project project) {
return ServiceManager.getService(project, GotoFileConfiguration.class);
}
@Override
protected String nameForElement(FileType type) {
return type.getName();
}
}
@@ -31,45 +31,24 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.Collection;
/**
* Model for "Go to | File" action
*/
public class GotoFileModel extends ContributorsBasedGotoByModel{
public class GotoFileModel extends FilteringGotoByModel<FileType> {
private final int myMaxSize;
/** current file types */
private HashSet<FileType> myFileTypes;
public GotoFileModel(Project project) {
super(project, Extensions.getExtensions(ChooseByNameContributor.FILE_EP_NAME));
myMaxSize = WindowManagerEx.getInstanceEx().getFrame(project).getSize().width;
}
/**
* Set file types
* @param fileTypes a file types to set
*/
public synchronized void setFileTypes(FileType[] fileTypes) {
// get and set method are called from different threads
myFileTypes = new HashSet<FileType>(Arrays.asList(fileTypes));
}
/**
* @return get file types
*/
private synchronized Set<FileType> getFileTypes() {
// get and set method are called from different threads
return myFileTypes;
}
@Override
protected boolean acceptItem(final NavigationItem item) {
if (item instanceof PsiFile) {
final PsiFile file = (PsiFile)item;
final Set<FileType> types = getFileTypes();
final Collection<FileType> types = getFilterItems();
// if language substitutors are used, PsiFile.getFileType() can be different from
// PsiFile.getVirtualFile().getFileType()
if (types != null) {
@@ -85,6 +64,12 @@ public class GotoFileModel extends ContributorsBasedGotoByModel{
}
}
@Nullable
@Override
protected FileType filterValueFor(NavigationItem item) {
return item instanceof PsiFile ? ((PsiFile) item).getFileType() : null;
}
public String getPromptText() {
return IdeBundle.message("prompt.gotofile.enter.file.name");
}
@@ -16,18 +16,25 @@
package com.intellij.ide.util.gotoByName;
import com.intellij.ide.IdeBundle;
import com.intellij.lang.Language;
import com.intellij.navigation.ChooseByNameRegistry;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.psi.PsiElement;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import org.jetbrains.annotations.NotNull;
public class GotoSymbolModel2 extends ContributorsBasedGotoByModel {
public class GotoSymbolModel2 extends FilteringGotoByModel<Language> {
public GotoSymbolModel2(Project project) {
super(project, ChooseByNameRegistry.getInstance().getSymbolModelContributors());
}
@Override
protected Language filterValueFor(NavigationItem item) {
return item instanceof PsiElement ? ((PsiElement) item).getLanguage() : null;
}
public String getPromptText() {
return IdeBundle.message("prompt.gotosymbol.enter.symbol.name");
}
@@ -55,7 +55,7 @@ public class PathUtilEx {
}
public static Sdk chooseJdk(Project project, Collection<Module> modules) {
Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectJdk();
Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
if (projectJdk != null) {
return projectJdk;
}
@@ -159,7 +159,7 @@ public class SdkConfigurationUtil {
public static void setDirectoryProjectSdk(final Project project, final Sdk sdk) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
ProjectRootManager.getInstance(project).setProjectJdk(sdk);
ProjectRootManager.getInstance(project).setProjectSdk(sdk);
final Module[] modules = ModuleManager.getInstance(project).getModules();
if (modules.length > 0) {
final ModifiableRootModel model = ModuleRootManager.getInstance(modules[0]).getModifiableModel();
@@ -171,7 +171,7 @@ public class SdkConfigurationUtil {
}
public static void configureDirectoryProjectSdk(final Project project, final SdkType... sdkTypes) {
Sdk existingSdk = ProjectRootManager.getInstance(project).getProjectJdk();
Sdk existingSdk = ProjectRootManager.getInstance(project).getProjectSdk();
if (existingSdk != null && ArrayUtil.contains(existingSdk.getSdkType(), sdkTypes)) {
return;
}
@@ -185,7 +185,7 @@ public class SdkConfigurationUtil {
@Nullable
public static Sdk findOrCreateSdk(final SdkType... sdkTypes) {
final Project defaultProject = ProjectManager.getInstance().getDefaultProject();
final Sdk sdk = ProjectRootManager.getInstance(defaultProject).getProjectJdk();
final Sdk sdk = ProjectRootManager.getInstance(defaultProject).getProjectSdk();
if (sdk != null) {
for (SdkType type : sdkTypes) {
if (sdk.getSdkType() == type) {
@@ -89,7 +89,7 @@ public class InheritedJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implem
}
protected RootProvider getRootProvider() {
final Sdk projectJdk = myProjectRootManagerImpl.getProjectJdk();
final Sdk projectJdk = myProjectRootManagerImpl.getProjectSdk();
return projectJdk == null ? null : projectJdk.getRootProvider();
}
@@ -82,8 +82,8 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
private AppListener myApplicationListener;
private String myProjectJdkName;
private String myProjectJdkType;
private String myProjectSdkName;
private String myProjectSdkType;
private final List<CacheUpdater> myRootsChangeUpdaters = new ArrayList<CacheUpdater>();
private final List<CacheUpdater> myRefreshCacheUpdaters = new ArrayList<CacheUpdater>();
@@ -327,28 +327,28 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
return VfsUtil.toVirtualFileArray(result);
}
public Sdk getProjectJdk() {
if (myProjectJdkName != null) {
return ProjectJdkTable.getInstance().findJdk(myProjectJdkName, myProjectJdkType);
public Sdk getProjectSdk() {
if (myProjectSdkName != null) {
return ProjectJdkTable.getInstance().findJdk(myProjectSdkName, myProjectSdkType);
}
else {
return null;
}
}
public String getProjectJdkName() {
return myProjectJdkName;
public String getProjectSdkName() {
return myProjectSdkName;
}
public void setProjectJdk(Sdk projectJdk) {
public void setProjectSdk(Sdk projectSdk) {
ApplicationManager.getApplication().assertWriteAccessAllowed();
if (projectJdk != null) {
myProjectJdkName = projectJdk.getName();
myProjectJdkType = projectJdk.getSdkType().getName();
if (projectSdk != null) {
myProjectSdkName = projectSdk.getName();
myProjectSdkType = projectSdk.getSdkType().getName();
}
else {
myProjectJdkName = null;
myProjectJdkType = null;
myProjectSdkName = null;
myProjectSdkType = null;
}
mergeRootsChangesDuring(new Runnable() {
public void run() {
@@ -357,9 +357,9 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
});
}
public void setProjectJdkName(String name) {
public void setProjectSdkName(String name) {
ApplicationManager.getApplication().assertWriteAccessAllowed();
myProjectJdkName = name;
myProjectSdkName = name;
mergeRootsChangesDuring(new Runnable() {
public void run() {
@@ -409,8 +409,8 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
for (ProjectExtension extension : Extensions.getExtensions(ProjectExtension.EP_NAME, myProject)) {
extension.readExternal(element);
}
myProjectJdkName = element.getAttributeValue(PROJECT_JDK_NAME_ATTR);
myProjectJdkType = element.getAttributeValue(PROJECT_JDK_TYPE_ATTR);
myProjectSdkName = element.getAttributeValue(PROJECT_JDK_NAME_ATTR);
myProjectSdkType = element.getAttributeValue(PROJECT_JDK_TYPE_ATTR);
}
public void writeExternal(Element element) throws WriteExternalException {
@@ -418,11 +418,11 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
for (ProjectExtension extension : Extensions.getExtensions(ProjectExtension.EP_NAME, myProject)) {
extension.writeExternal(element);
}
if (myProjectJdkName != null) {
element.setAttribute(PROJECT_JDK_NAME_ATTR, myProjectJdkName);
if (myProjectSdkName != null) {
element.setAttribute(PROJECT_JDK_NAME_ATTR, myProjectSdkName);
}
if (myProjectJdkType != null) {
element.setAttribute(PROJECT_JDK_TYPE_ATTR, myProjectJdkType);
if (myProjectSdkType != null) {
element.setAttribute(PROJECT_JDK_TYPE_ATTR, myProjectSdkType);
}
}
@@ -946,11 +946,11 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
myDispatcher.getMulticaster().jdkNameChanged(jdk, previousName);
}
});
String currentName = getProjectJdkName();
String currentName = getProjectSdkName();
if (previousName != null && previousName.equals(currentName)) {
// if already had jdk name and that name was the name of the jdk just changed
myProjectJdkName = jdk.getName();
myProjectJdkType = jdk.getSdkType().getName();
myProjectSdkName = jdk.getName();
myProjectSdkType = jdk.getSdkType().getName();
}
}
@@ -42,11 +42,11 @@ public class RootConfigurationAccessor {
}
public Sdk getProjectSdk(Project project) {
return ProjectRootManager.getInstance(project).getProjectJdk();
return ProjectRootManager.getInstance(project).getProjectSdk();
}
@Nullable
public String getProjectSdkName(final Project project) {
return ProjectRootManager.getInstance(project).getProjectJdkName();
return ProjectRootManager.getInstance(project).getProjectSdkName();
}
}
@@ -15,7 +15,6 @@
*/
package com.intellij.openapi.roots.libraries.scripting;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
@@ -46,16 +45,15 @@ public abstract class ScriptingIndexableSetContributor extends IndexableSetContr
final THashSet<VirtualFile> libFiles = new THashSet<VirtualFile>();
if (project != null) {
ScriptingLibraryManager manager = new ScriptingLibraryManager(project);
LibraryTable libTable = manager.getLibraryTable();
LibraryTable libTable = manager.getLibraryTable(true);
if (libTable != null) {
for (Library lib : libTable.getLibraries()) {
for (VirtualFile libFile : lib.getFiles(OrderRootType.CLASSES)) {
for (VirtualFile libFile : lib.getFiles(OrderRootType.SOURCES)) {
libFile.putUserData(getIndexKey(), "");
libFiles.add(libFile);
}
}
}
manager.disposeModel();
}
return libFiles;
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import org.jetbrains.annotations.Nullable;
/**
@@ -28,22 +29,36 @@ import org.jetbrains.annotations.Nullable;
*/
public class ScriptingLibraryManager {
public enum LibraryLevel {GLOBAL, PROJECT}
public static final String WEB_MODULE_TYPE = "WEB_MODULE";
private ModifiableRootModel myRootModel;
private Project myProject;
private LibraryLevel myLibLevel = LibraryLevel.PROJECT;
public ScriptingLibraryManager(Project project) {
this(LibraryLevel.GLOBAL, project);
}
public ScriptingLibraryManager(LibraryLevel libLevel, Project project) {
myProject = project;
myRootModel = getRootModel(project);
myLibLevel = libLevel;
myRootModel = getRootModel(libLevel, project);
}
@Nullable
private static ModifiableRootModel getRootModel(Project project) {
for (Module module : ModuleManager.getInstance(project).getModules()) {
if (WEB_MODULE_TYPE.equals(module.getModuleType().getId())) {
return ModuleRootManager.getInstance(module).getModifiableModel();
}
private static ModifiableRootModel getRootModel(LibraryLevel libraryLevel, Project project) {
switch (libraryLevel) {
case PROJECT:
for (Module module : ModuleManager.getInstance(project).getModules()) {
if (WEB_MODULE_TYPE.equals(module.getModuleType().getId())) {
return ModuleRootManager.getInstance(module).getModifiableModel();
}
}
break;
case GLOBAL:
return null;
}
return null;
}
@@ -56,6 +71,10 @@ public class ScriptingLibraryManager {
}
public void commitModel() {
if (myLibLevel == LibraryLevel.GLOBAL) {
ModuleManager.getInstance(myProject).getModifiableModel().commit();
return;
}
if (myRootModel != null && !myRootModel.isDisposed()) {
myRootModel.commit();
resetModel();
@@ -64,15 +83,32 @@ public class ScriptingLibraryManager {
public void resetModel() {
disposeModel();
myRootModel = getRootModel(myProject);
myRootModel = getRootModel(myLibLevel, myProject);
}
@Nullable
public LibraryTable getLibraryTable(boolean readOnly) {
if (!readOnly && myLibLevel == LibraryLevel.PROJECT) {
return myRootModel != null ? myRootModel.getModuleLibraryTable() : null;
}
String libLevel = null;
switch (myLibLevel) {
case PROJECT:
libLevel = LibraryTablesRegistrar.PROJECT_LEVEL;
break;
case GLOBAL:
libLevel = LibraryTablesRegistrar.APPLICATION_LEVEL;
break;
}
if (libLevel != null) {
return LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(libLevel, myProject);
}
return null;
}
@Nullable
public LibraryTable getLibraryTable() {
if (myRootModel != null) {
return myRootModel.getModuleLibraryTable();
}
return null;
return getLibraryTable(false);
}
public Project getProject() {
@@ -91,7 +91,7 @@ public class ProjectSdksModel implements SdkModel {
//can't be
}
}
myProjectSdk = findSdk(ProjectRootManager.getInstance(project).getProjectJdkName());
myProjectSdk = findSdk(ProjectRootManager.getInstance(project).getProjectSdkName());
myModified = false;
myInitialized = true;
}
@@ -523,6 +523,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
final FileViewProvider viewProvider = getCachedViewProvider(document);
if (viewProvider == null) return;
if (viewProvider.getVirtualFile().getFileType().isBinary()) return;
if (viewProvider.getManager() != myPsiManager) return;
final List<PsiFile> files = viewProvider.getAllFiles();
boolean commitNecessary = false;
@@ -536,7 +537,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
}
textBlock.documentChanged(event);
assert file instanceof PsiFileImpl : event + "; file="+file+"; allFiles="+files+"; viewProvider="+viewProvider;
assert file instanceof PsiFileImpl || "mock.file".equals(file.getName()) && ApplicationManager.getApplication().isUnitTestMode() : event + "; file="+file+"; allFiles="+files+"; viewProvider="+viewProvider;
myUncommittedDocuments.add(document);
commitNecessary = true;
}
@@ -568,6 +569,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
}
char[] fileText = psiFile.textToCharArray();
@SuppressWarnings({"NonConstantStringShouldBeStringBuffer"})
@NonNls String error = "File '" + psiFile.getName() + "' text mismatch after reparse. " +
"File length=" + fileText.length + "; Doc length=" + documentLength + "\n";
int i = 0;
@@ -19,16 +19,22 @@ import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Iconable;
import com.intellij.psi.PsiFile;
import com.intellij.util.Icons;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* User: anna
* Date: Sep 6, 2010
*/
public class ChangeSignatureDetectorAction implements IntentionAction {
public class ChangeSignatureDetectorAction implements IntentionAction, Iconable {
private static final Logger LOG = Logger.getInstance("#" + ChangeSignatureDetectorAction.class.getName());
@NonNls public static final String CHANGE_SIGNATURE = "Change signature ...";
@NotNull
@Override
@@ -56,4 +62,9 @@ public class ChangeSignatureDetectorAction implements IntentionAction {
public boolean startInWriteAction() {
return false;
}
@Override
public Icon getIcon(int flags) {
return Icons.ADVICE_ICON;
}
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorBundle;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.actions.EditorActionUtil;
@@ -50,11 +51,16 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
private final PsiDocumentManager myPsiDocumentManager;
private final PsiManager myPsiManager;
private final FileEditorManager myFileEditorManager;
private final Project myProject;
public ChangeSignatureGestureDetector(final PsiDocumentManager psiDocumentManager, final PsiManager psiManager, final FileEditorManager fileEditorManager) {
public ChangeSignatureGestureDetector(final PsiDocumentManager psiDocumentManager,
final PsiManager psiManager,
final FileEditorManager fileEditorManager,
final Project project) {
myPsiDocumentManager = psiDocumentManager;
myPsiManager = psiManager;
myFileEditorManager = fileEditorManager;
myProject = project;
}
public static ChangeSignatureGestureDetector getInstance(Project project){
@@ -100,11 +106,11 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
public void projectOpened() {
myPsiManager.addPsiTreeChangeListener(this);
EditorFactory.getInstance().addEditorFactoryListener(this);
Disposer.register(myPsiManager.getProject(), new Disposable() {
Disposer.register(myProject, new Disposable() {
public void dispose() {
myPsiManager.removePsiTreeChangeListener(ChangeSignatureGestureDetector.this);
EditorFactory.getInstance().removeEditorFactoryListener(ChangeSignatureGestureDetector.this);
myListenerMap.clear();
LOG.assertTrue(myListenerMap.isEmpty(), myListenerMap);
}
});
}
@@ -163,12 +169,14 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
@Override
public void editorCreated(EditorFactoryEvent event) {
addDocListener(event.getEditor().getDocument());
final Editor editor = event.getEditor();
if (editor.getProject() != myProject) return;
addDocListener(editor.getDocument());
}
public void addDocListener(Document document) {
final PsiFile file = myPsiDocumentManager.getPsiFile(document);
if (file != null && !myListenerMap.containsKey(file)) {
if (file != null && file.isPhysical() && !myListenerMap.containsKey(file)) {
final MyDocumentChangeAdapter adapter = new MyDocumentChangeAdapter();
document.addDocumentListener(adapter);
myListenerMap.put(file, adapter);
@@ -182,7 +190,7 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
public void removeDocListener(Document document) {
final PsiFile file = myPsiDocumentManager.getPsiFile(document);
if (file != null) {
if (file != null && file.isPhysical()) {
if (ArrayUtil.find(myFileEditorManager.getOpenFiles(), file.getVirtualFile()) != -1) {
return;
}
@@ -19,17 +19,22 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.HighlightVisitor;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder;
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Icons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
/**
@@ -42,11 +47,11 @@ public class ChangeSignatureGestureVisitor implements HighlightVisitor {
@Override
public boolean suitableForFile(PsiFile file) {
return file != null && ApplicationManagerEx.getApplicationEx().isInternal() && LanguageChangeSignatureDetectors.isSuitableForLanguage(file.getLanguage());
return file != null && LanguageChangeSignatureDetectors.isSuitableForLanguage(file.getLanguage());
}
@Override
public void visit(PsiElement element, HighlightInfoHolder holder) {
public void visit(final PsiElement element, HighlightInfoHolder holder) {
final ChangeSignatureGestureDetector detector = ChangeSignatureGestureDetector.getInstance(element.getProject());
if (detector.isChangeSignatureAvailable(element)) {
final TextRange range = LanguageChangeSignatureDetectors.getHighlightingRange(element);
@@ -58,7 +63,8 @@ public class ChangeSignatureGestureVisitor implements HighlightVisitor {
HighlightInfoType.INFORMATION, range.getStartOffset(), range.getEndOffset(),
SIGNATURE_SHOULD_BE_POSSIBLY_CHANGED, SIGNATURE_SHOULD_BE_POSSIBLY_CHANGED,
HighlightSeverity.INFORMATION, false, true, false);
QuickFixAction.registerQuickFixAction(info, new ChangeSignatureDetectorAction());
final ChangeSignatureDetectorAction action = new ChangeSignatureDetectorAction();
info.setGutterIconRenderer(new MyGutterIconRenderer(action, element));
holder.add(info);
}
}
@@ -79,5 +85,45 @@ public class ChangeSignatureGestureVisitor implements HighlightVisitor {
return 10;
}
private static class MyGutterIconRenderer extends GutterIconRenderer {
private final ChangeSignatureDetectorAction myAction;
private final PsiElement myElement;
public MyGutterIconRenderer(ChangeSignatureDetectorAction action, PsiElement element) {
myAction = action;
myElement = element;
}
@NotNull
@Override
public Icon getIcon() {
return Icons.ADVICE_ICON;
}
@Override
public AnAction getClickAction() {
return new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
myAction.invoke(myElement.getProject(), null, myElement.getContainingFile());
}
};
}
@Override
public String getTooltipText() {
return ChangeSignatureDetectorAction.CHANGE_SIGNATURE;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof MyGutterIconRenderer)) return false;
return true;
}
@Override
public int hashCode() {
return 0;
}
}
}
@@ -97,17 +97,8 @@ public class VariableInplaceRenameHandler implements RenameHandler {
@Nullable
public VariableInplaceRenamer doRename(final PsiElement elementToRename, final Editor editor, final DataContext dataContext) {
return doRename(elementToRename, editor, dataContext, true);
}
@Nullable
public VariableInplaceRenamer doRename(final PsiElement elementToRename,
final Editor editor,
final DataContext dataContext,
boolean processTextOccurrences) {
VariableInplaceRenamer renamer = createRenamer(elementToRename, editor);
boolean startedRename = renamer == null ? false : renamer.performInplaceRename(processTextOccurrences);
boolean startedRename = renamer == null ? false : renamer.performInplaceRename();
if (!startedRename) {
try {
@@ -94,10 +94,10 @@ public class VariableInplaceRenamer {
}
public boolean performInplaceRename() {
return performInplaceRename(true);
return performInplaceRename(true, null);
}
public boolean performInplaceRename(boolean processTextOccurrences) {
public boolean performInplaceRename(boolean processTextOccurrences, LinkedHashSet<String> nameSuggestions) {
if (InjectedLanguageUtil.isInInjectedLanguagePrefixSuffix(myElementToRename)) {
return false;
}
@@ -170,9 +170,9 @@ public class VariableInplaceRenamer {
PsiElement selectedElement = getSelectedInEditorElement(nameIdentifier, refs, offset);
if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, myElementToRename)) return true;
if (nameIdentifier != null) addVariable(nameIdentifier, selectedElement, builder);
if (nameIdentifier != null) addVariable(nameIdentifier, selectedElement, builder, nameSuggestions);
for (PsiReference ref : refs) {
addVariable(ref, selectedElement, builder, offset);
addVariable(ref, selectedElement, builder, offset, nameSuggestions);
}
final PsiElement scope1 = scope;
@@ -391,10 +391,14 @@ public class VariableInplaceRenamer {
return range.getStartOffset() <= offset && offset <= range.getEndOffset();
}
private void addVariable(final PsiReference reference, final PsiElement selectedElement, final TemplateBuilderImpl builder, int offset) {
private void addVariable(final PsiReference reference,
final PsiElement selectedElement,
final TemplateBuilderImpl builder,
int offset,
final LinkedHashSet<String> names) {
if (reference.getElement() == selectedElement &&
contains(reference.getRangeInElement().shiftRight(selectedElement.getTextRange().getStartOffset()), offset)) {
Expression expression = new MyExpression(myElementToRename.getName());
Expression expression = new MyExpression(myElementToRename.getName(), names);
builder.replaceElement(reference, PRIMARY_VARIABLE_NAME, expression, true);
}
else {
@@ -402,9 +406,12 @@ public class VariableInplaceRenamer {
}
}
private void addVariable(final PsiElement element, final PsiElement selectedElement, final TemplateBuilderImpl builder) {
private void addVariable(final PsiElement element,
final PsiElement selectedElement,
final TemplateBuilderImpl builder,
final LinkedHashSet<String> names) {
if (element == selectedElement) {
Expression expression = new MyExpression(myElementToRename.getName());
Expression expression = new MyExpression(myElementToRename.getName(), names);
builder.replaceElement(element, PRIMARY_VARIABLE_NAME, expression, true);
}
else {
@@ -416,11 +423,13 @@ public class VariableInplaceRenamer {
private final String myName;
private final LookupElement[] myLookupItems;
private MyExpression(String name) {
private MyExpression(String name, LinkedHashSet<String> names) {
myName = name;
Set<String> names = new HashSet<String>();
for(NameSuggestionProvider provider: Extensions.getExtensions(NameSuggestionProvider.EP_NAME)) {
provider.getSuggestedNames(myElementToRename, myElementToRename, names);
if (names == null) {
names = new LinkedHashSet<String>();
for(NameSuggestionProvider provider: Extensions.getExtensions(NameSuggestionProvider.EP_NAME)) {
provider.getSuggestedNames(myElementToRename, myElementToRename, names);
}
}
myLookupItems = new LookupElement[names.size()];
final Iterator<String> iterator = names.iterator();

Some files were not shown because too many files have changed in this diff Show More