Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2012-02-25 11:19:55 +04:00
37 changed files with 496 additions and 292 deletions
@@ -36,7 +36,7 @@ public class ChangeExtendsToImplementsFix extends ExtendsListFix {
myName = QuickFixBundle.message("exchange.extends.implements.keyword",
aClass.isInterface() == myClassToExtendFrom.isInterface() ? PsiKeyword.IMPLEMENTS : PsiKeyword.EXTENDS,
aClass.isInterface() == myClassToExtendFrom.isInterface() ? PsiKeyword.EXTENDS : PsiKeyword.IMPLEMENTS,
myClassToExtendFrom.getQualifiedName());
myClassToExtendFrom.getName());
}
@Override
@@ -312,12 +312,13 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase {
}
}
final List<PsiFile> createdFiles = new ArrayList<PsiFile>(fileToClasses.size());
int foIdx = 0;
int[] choice = fileToClasses.size() > 1 ? new int[]{-1} : null;
List<PsiFile> files = new ArrayList<PsiFile>();
for (final Map.Entry<PsiFile, PsiClass[]> entry : fileToClasses.entrySet()) {
final PsiFile psiFile = entry.getKey();
if (psiFile instanceof PsiClassOwner) {
final PsiFile createdFile = copy(psiFile, targetDirectory, copyClassName, map == null ? null : map.get(psiFile));
final PsiFile createdFile = copy(psiFile, targetDirectory, copyClassName, map == null ? null : map.get(psiFile), choice);
if (createdFile == null) return null;
final PsiClass[] sources = entry.getValue();
for (final PsiClass destination : ((PsiClassOwner)createdFile).getClasses()) {
if (destination instanceof SyntheticElement) {
@@ -339,7 +340,7 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase {
}
}
int[] choice = files.size() > 1 ? new int[]{-1} : null;
for (PsiFile file : files) {
try {
final PsiFile fileCopy =
@@ -375,11 +376,12 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase {
return newElement != null ? newElement : createdFiles.size() > 0 ? createdFiles.get(0) : null;
}
private static PsiFile copy(@NotNull PsiFile file, PsiDirectory directory, String name, String relativePath) {
private static PsiFile copy(@NotNull PsiFile file, PsiDirectory directory, String name, String relativePath, int[] choice) {
final String fileName = getNewFileName(file, name);
if (relativePath != null && !relativePath.isEmpty()) {
return buildRelativeDir(directory, relativePath).findOrCreateTargetDirectory().copyFileFrom(fileName, file);
}
if (CopyFilesOrDirectoriesHandler.checkFileExist(directory, choice, file, fileName, "Copy")) return null;
return directory.copyFileFrom(fileName, file);
}
@@ -1,4 +1,4 @@
// "Change 'extends java.lang.Runnable' to 'implements java.lang.Runnable'" "true"
// "Change 'extends Runnable' to 'implements Runnable'" "true"
import java.io.*;
class a <caret>implements Runnable {
@@ -1,4 +1,4 @@
// "Change 'implements java.lang.Object' to 'extends java.lang.Object'" "true"
// "Change 'implements Object' to 'extends Object'" "true"
import java.io.*;
class a extends Object <caret>{
@@ -1,4 +1,4 @@
// "Change 'implements java.lang.Object' to 'extends java.lang.Object'" "true"
// "Change 'implements Object' to 'extends Object'" "true"
import java.io.*;
class a extends Object implements Runnable,<caret> Serializable {
@@ -1,4 +1,4 @@
// "Change 'extends java.lang.Runnable' to 'implements java.lang.Runnable'" "true"
// "Change 'extends Runnable' to 'implements Runnable'" "true"
import java.io.*;
class a extends Object<caret> implements Serializable, Runnable {
@@ -1,4 +1,4 @@
// "Change 'extends java.lang.Runnable' to 'implements java.lang.Runnable'" "true"
// "Change 'extends Runnable' to 'implements Runnable'" "true"
import java.io.*;
class a extends <caret>Runnable {
@@ -1,4 +1,4 @@
// "Change 'implements java.lang.Object' to 'extends java.lang.Object'" "true"
// "Change 'implements Object' to 'extends Object'" "true"
import java.io.*;
class a implements <caret>Object {
@@ -1,4 +1,4 @@
// "Change 'implements java.lang.Object' to 'extends java.lang.Object'" "true"
// "Change 'implements Object' to 'extends Object'" "true"
import java.io.*;
class a implements Runnable,<caret>Object,Serializable {
@@ -1,4 +1,4 @@
// "Change 'extends java.lang.Runnable' to 'implements java.lang.Runnable'" "true"
// "Change 'extends Runnable' to 'implements Runnable'" "true"
import java.io.*;
class a extends Object,<caret>Runnable implements Serializable {
@@ -1,4 +1,4 @@
// "Change 'implements java.lang.Object' to 'extends java.lang.Object'" "false"
// "Change 'implements Object' to 'extends Object'" "false"
import java.io.*;
class a extends b implements Runnable,<caret>Object,Serializable {
@@ -56,7 +56,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
private static final String FORM_EXTENSION = ".form";
public static final boolean USE_EMBEDDED_JAVAC = System.getProperty(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION) == null;
private static final FileFilter JAVA_SOURCES_FILTER = new FileFilter() {
public static final FileFilter JAVA_SOURCES_FILTER = new FileFilter() {
public boolean accept(File file) {
return file.getPath().endsWith(JAVA_EXTENSION);
}
@@ -21,9 +21,7 @@ package com.intellij.lang;
import com.intellij.psi.PsiFile;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class LanguageImportStatements extends LanguageExtension<ImportOptimizer> {
@@ -33,15 +31,14 @@ public class LanguageImportStatements extends LanguageExtension<ImportOptimizer>
super("com.intellij.lang.importOptimizer");
}
public List<Runnable> forFile(PsiFile file) {
List<Runnable> runnables = new ArrayList<Runnable>();
public Set<ImportOptimizer> forFile(PsiFile file) {
Set<ImportOptimizer> optimizers = new HashSet<ImportOptimizer>();
for (PsiFile psiFile : file.getViewProvider().getAllFiles()) {
ImportOptimizer optimizer = forLanguage(psiFile.getLanguage());
if (optimizer != null && optimizer.supports(psiFile) && optimizers.add(optimizer)) {
runnables.add(optimizer.processFile(psiFile));
if (optimizer != null && optimizer.supports(psiFile)) {
optimizers.add(optimizer);
}
}
return runnables;
return optimizers;
}
}
@@ -17,16 +17,20 @@
package com.intellij.codeInsight.actions;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.lang.ImportOptimizer;
import com.intellij.lang.LanguageImportStatements;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Set;
import java.util.concurrent.FutureTask;
public class OptimizeImportsProcessor extends AbstractLayoutCodeProcessor {
@@ -59,12 +63,18 @@ public class OptimizeImportsProcessor extends AbstractLayoutCodeProcessor {
@NotNull
protected FutureTask<Boolean> preprocessFile(@NotNull final PsiFile file, boolean processChangedTextOnly) throws IncorrectOperationException {
final List<Runnable> optimizers = LanguageImportStatements.INSTANCE.forFile(file);
Runnable runnable = optimizers.isEmpty() ? EmptyRunnable.getInstance() : new Runnable() {
final Set<ImportOptimizer> optimizers = LanguageImportStatements.INSTANCE.forFile(file);
final List<Runnable> runnables = ContainerUtil.map(optimizers, new Function<ImportOptimizer, Runnable>() {
@Override
public Runnable fun(ImportOptimizer optimizer) {
return optimizer.processFile(file);
}
});
Runnable runnable = runnables.isEmpty() ? EmptyRunnable.getInstance() : new Runnable() {
@Override
public void run() {
for (Runnable optimizer : optimizers) {
optimizer.run();
for (Runnable runnable : runnables) {
runnable.run();
}
}
};
@@ -33,6 +33,9 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class MnemonicChooser extends JPanel {
private static final Color OCCUPIED_CELL_COLOR = new Color(250, 250, 139);
private static final Color FREE_CELL_COLOR = LightColors.SLIGHTLY_GRAY;
public MnemonicChooser() {
super(new VerticalFlowLayout());
JPanel numbers = new NonOpaquePanel(new GridLayout(2, 5, 2, 2));
@@ -83,7 +86,7 @@ public class MnemonicChooser extends JPanel {
}
private Color backgroundForMnemonic(char c) {
return isOccupied(c) ? LightColors.YELLOW : LightColors.SLIGHTLY_GRAY;
return isOccupied(c) ? OCCUPIED_CELL_COLOR : FREE_CELL_COLOR;
}
private class MnemonicLabel extends JLabel {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -184,4 +184,8 @@ public abstract class ActionGroup extends AnAction {
return myDumbAware;
}
public boolean hideIfNoVisibleChildren() {
return false;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -20,6 +20,7 @@ import com.intellij.ui.MouseDragHelper;
import com.intellij.ui.ScreenUtil;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.tabs.TabInfo;
import com.intellij.ui.util.Axis;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -35,9 +36,6 @@ class DragHelper extends MouseDragHelper {
Rectangle myDragRec;
Dimension myHoldDelta;
Measurer myHorizontal = new Measurer.Width();
Measurer myVertical = new Measurer.Height();
private TabInfo myDragOutSource;
private TabLabel myPressedTabLabel;
@@ -134,14 +132,14 @@ class DragHelper extends MouseDragHelper {
TabLabel targetLabel;
if (myTabs.isHorizontalTabs()) {
targetLabel = findMostOverlapping(myHorizontal, left, right);
targetLabel = findMostOverlapping(Axis.X, left, right);
if (targetLabel == null) {
targetLabel = findMostOverlapping(myVertical, top, bottom);
targetLabel = findMostOverlapping(Axis.Y, top, bottom);
}
} else {
targetLabel = findMostOverlapping(myVertical, top, bottom);
targetLabel = findMostOverlapping(Axis.Y, top, bottom);
if (targetLabel == null) {
targetLabel = findMostOverlapping(myHorizontal, left, right);
targetLabel = findMostOverlapping(Axis.X, left, right);
}
}
@@ -163,7 +161,7 @@ class DragHelper extends MouseDragHelper {
}
}
private TabLabel findMostOverlapping(Measurer measurer, TabLabel... labels) {
private TabLabel findMostOverlapping(Axis measurer, TabLabel... labels) {
double freeSpace;
if (measurer.getMinValue(myDragRec) < measurer.getMinValue(myDragOriginalRec)) {
@@ -179,7 +177,7 @@ class DragHelper extends MouseDragHelper {
if (each == null) continue;
final Rectangle eachBounds = each.getBounds();
if (measurer.getMeasuredValue(eachBounds) > freeSpace + freeSpace *0.3) continue;
if (measurer.getSize(eachBounds) > freeSpace + freeSpace *0.3) continue;
Rectangle intersection = myDragRec.intersection(eachBounds);
int size = intersection.width * intersection.height;
@@ -192,40 +190,6 @@ class DragHelper extends MouseDragHelper {
return maxLabel;
}
interface Measurer {
int getMinValue(Rectangle r);
int getMaxValue(Rectangle r);
int getMeasuredValue(Rectangle r);
class Width implements Measurer{
public int getMinValue(Rectangle r) {
return r.x;
}
public int getMaxValue(Rectangle r) {
return (int)r.getMaxX();
}
public int getMeasuredValue(Rectangle r) {
return r.width;
}
}
class Height implements Measurer{
public int getMinValue(Rectangle r) {
return r.y;
}
public int getMaxValue(Rectangle r) {
return (int)r.getMaxY();
}
public int getMeasuredValue(Rectangle r) {
return r.height;
}
}
}
@Nullable
private TabLabel findLabel(Point dragPoint) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -29,4 +29,8 @@ public class NonEmptyActionGroup extends DefaultActionGroup implements DumbAware
Presentation presentation = event.getPresentation();
presentation.setVisible(getChildrenCount() > 0);
}
public boolean hideIfNoVisibleChildren() {
return true;
}
}
@@ -68,7 +68,7 @@ public class DnDManagerImpl extends DnDManager implements Disposable {
onTimer();
}
});
private Runnable myHightlighterShowRequest;
private Runnable myHighlighterShowRequest;
private Rectangle myLastHighlightedRec;
private int myLastProcessedAction;
@@ -431,7 +431,7 @@ public class DnDManagerImpl extends DnDManager implements Disposable {
}
private void queueTooltip(final DnDEvent aEvent, final JLayeredPane aLayeredPane, final Rectangle aRectangle) {
myHightlighterShowRequest = new Runnable() {
myHighlighterShowRequest = new Runnable() {
public void run() {
if (myCurrentEvent != aEvent) return;
Highlighters.hide(DnDEvent.DropTargetHighlightingType.TEXT | DnDEvent.DropTargetHighlightingType.ERROR_TEXT);
@@ -451,14 +451,14 @@ public class DnDManagerImpl extends DnDManager implements Disposable {
void hideCurrentHighlighter() {
Highlighters.hide();
myHightlighterShowRequest = null;
myHighlighterShowRequest = null;
setLastHighlightedEvent(null, null);
}
private void onTimer() {
if (myHightlighterShowRequest != null) {
myHightlighterShowRequest.run();
myHightlighterShowRequest = null;
if (myHighlighterShowRequest != null) {
myHighlighterShowRequest.run();
myHighlighterShowRequest = null;
}
}
@@ -729,7 +729,7 @@ public class DnDManagerImpl extends DnDManager implements Disposable {
target.cleanUpOnLeave();
}
hideCurrentHighlighter();
myHightlighterShowRequest = null;
myHighlighterShowRequest = null;
}
private Application getApplication() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -131,8 +131,11 @@ public class Utils{
ActionGroup actionGroup = (ActionGroup)child;
if (actionGroup.isPopup()) { // popup menu has its own presentation
// disable group if it contains no visible actions
final boolean enabled = actionGroup.canBePerformed(context) || hasVisibleChildren(actionGroup, presentationFactory, context, place);
presentation.setEnabled(enabled);
final boolean visibleChildren = hasVisibleChildren(actionGroup, presentationFactory, context, place);
if (actionGroup.hideIfNoVisibleChildren() && !visibleChildren) {
continue;
}
presentation.setEnabled(actionGroup.canBePerformed(context) || visibleChildren);
list.add(child);
}
else {
@@ -40,6 +40,7 @@ import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.speedSearch.SpeedSearch;
import com.intellij.util.Alarm;
import com.intellij.util.ImageLoader;
import com.intellij.util.Processor;
import com.intellij.util.ui.ChildFocusWatcher;
@@ -612,6 +613,7 @@ public class AbstractPopup implements JBPopup {
assert ApplicationManager.getApplication().isDispatchThread();
installWindowHook(this);
addActivity();
final boolean shouldShow = beforeShow();
@@ -865,6 +867,19 @@ public class AbstractPopup implements JBPopup {
}
}
//Sometimes just after popup was shown the WINDOW_ACTIVATED cancels it
private static void installWindowHook(final AbstractPopup popup) {
if (popup.myCancelOnWindow) {
popup.myCancelOnWindow = false;
new Alarm(popup).addRequest(new Runnable() {
@Override
public void run() {
popup.myCancelOnWindow = true;
}
}, 100);
}
}
private void addActivity() {
UiActivityMonitor.getInstance().addActivity(myActivityKey);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2012 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.ui.util;
import java.awt.*;
/**
* @author yole
*/
public abstract class Axis {
public abstract int getMinValue(Rectangle r);
public abstract int getMaxValue(Rectangle r);
public abstract int getSize(Rectangle r);
public static Axis X = new Axis() {
@Override
public int getMinValue(Rectangle r) {
return r.x;
}
@Override
public int getMaxValue(Rectangle r) {
return (int) r.getMaxX();
}
@Override
public int getSize(Rectangle r) {
return r.width;
}
};
public static Axis Y = new Axis() {
public int getMinValue(Rectangle r) {
return r.y;
}
public int getMaxValue(Rectangle r) {
return (int)r.getMaxY();
}
public int getSize(Rectangle r) {
return r.height;
}
};
}
@@ -0,0 +1,36 @@
/*
* Copyright 2000-2012 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.util.containers;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author Evgeny Gerashchenko
*/
public class LinkedMultiMap<K, V> extends MultiMap<K, V> {
@Override
protected Map<K, Collection<V>> createMap() {
return new LinkedHashMap<K, Collection<V>>();
}
@Override
protected Map<K, Collection<V>> createMap(int i, float v) {
return new LinkedHashMap<K, Collection<V>>(i, v);
}
}
@@ -1,49 +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.
*/
package com.intellij.util.ui;
import javax.swing.*;
import java.awt.*;
/**
* @deprecated Use UIUtil instead
*/
public class IdeaUIManager {
public static Color getTableSelectionBackgroung(){
return UIUtil.getTableSelectionBackground();
}
public static Color getTableBackgroung(){
return UIUtil.getTableBackground();
}
public static Color getTableSelectionForegroung(){
return UIUtil.getTableSelectionForeground();
}
public static Color getTableForegroung(){
return UIUtil.getTableForeground();
}
public static Color getTreeForegroung() {
return UIUtil.getTreeForeground();
}
}
@@ -60,6 +60,7 @@ import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.concurrent.Callable;
/**
* @author Alexander Lobas
@@ -150,12 +151,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
});
// TODO: run in background
try {
createRenderer(layoutXmlText);
}
catch (IndexNotReadyException e) {
createRenderer(layoutXmlText);
}
createRenderer(layoutXmlText);
Result result = mySession.getResult();
if (!result.isSuccess()) {
@@ -228,32 +224,37 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
}
private void createRenderer(String layoutXmlText) throws Exception {
private void createRenderer(final String layoutXmlText) throws Exception {
// TODO: (profile|device|target|...|theme) panel
AndroidPlatform platform = AndroidPlatform.getInstance(myModule);
IAndroidTarget target = platform.getTarget();
AndroidFacet facet = AndroidFacet.getInstance(myModule);
mySession = ApplicationManager.getApplication().executeOnPooledThread(new Callable<RenderSession>() {
@Override
public RenderSession call() throws Exception {
AndroidPlatform platform = AndroidPlatform.getInstance(myModule);
IAndroidTarget target = platform.getTarget();
AndroidFacet facet = AndroidFacet.getInstance(myModule);
LayoutDeviceManager layoutDeviceManager = new LayoutDeviceManager();
layoutDeviceManager.loadDevices(platform.getSdkData());
LayoutDevice layoutDevice = layoutDeviceManager.getCombinedList().get(0);
LayoutDeviceManager layoutDeviceManager = new LayoutDeviceManager();
layoutDeviceManager.loadDevices(platform.getSdkData());
LayoutDevice layoutDevice = layoutDeviceManager.getCombinedList().get(0);
LayoutDeviceConfiguration deviceConfiguration = layoutDevice.getConfigurations().get(0);
LayoutDeviceConfiguration deviceConfiguration = layoutDevice.getConfigurations().get(0);
FolderConfiguration config = new FolderConfiguration();
config.set(deviceConfiguration.getConfiguration());
config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL));
config.setNightModeQualifier(new NightModeQualifier(NightMode.NIGHT));
config.setLanguageQualifier(new LanguageQualifier());
config.setRegionQualifier(new RegionQualifier());
FolderConfiguration config = new FolderConfiguration();
config.set(deviceConfiguration.getConfiguration());
config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL));
config.setNightModeQualifier(new NightModeQualifier(NightMode.NIGHT));
config.setLanguageQualifier(new LanguageQualifier());
config.setRegionQualifier(new RegionQualifier());
float xdpi = deviceConfiguration.getDevice().getXDpi();
float ydpi = deviceConfiguration.getDevice().getYDpi();
float xdpi = deviceConfiguration.getDevice().getXDpi();
float ydpi = deviceConfiguration.getDevice().getYDpi();
ThemeData theme = new ThemeData("Theme", false);
ThemeData theme = new ThemeData("Theme", false);
mySession = RenderUtil.createRenderSession(myModule.getProject(), layoutXmlText, myFile, target, facet, config, xdpi, ydpi, theme);
return RenderUtil.createRenderSession(myModule.getProject(), layoutXmlText, myFile, target, facet, config, xdpi, ydpi, theme);
}
}).get();
}
@Override
@@ -16,7 +16,7 @@ import java.io.IOException;
*/
public class AndroidAptStateStorage extends AbstractStateStorage<String, AndroidAptValidityState> {
@NonNls private static final String ANDROID_STORAGE_DIR = "android_resource_names";
@NonNls private static final String ANDROID_RESOURCE_NAMES_STORAGE_DIR = "android_resource_names";
@NonNls private static final String RESOURCE_NAMES_STORAGE = "resource_names";
public AndroidAptStateStorage(@NotNull File dataStorageRoot) throws IOException {
@@ -25,7 +25,7 @@ public class AndroidAptStateStorage extends AbstractStateStorage<String, Android
@NotNull
private static File getStorageFile(@NotNull File dataStorageRoot) {
return new File(new File(dataStorageRoot, ANDROID_STORAGE_DIR), RESOURCE_NAMES_STORAGE);
return new File(new File(dataStorageRoot, ANDROID_RESOURCE_NAMES_STORAGE_DIR), RESOURCE_NAMES_STORAGE);
}
private static class MyDataExternalizer implements DataExternalizer<AndroidAptValidityState> {
@@ -3,6 +3,7 @@ package org.jetbrains.jps.android;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.incremental.BuilderService;
import org.jetbrains.jps.incremental.ModuleLevelBuilder;
import org.jetbrains.jps.incremental.ProjectLevelBuilder;
import java.util.Arrays;
import java.util.List;
@@ -17,7 +18,12 @@ public class AndroidBuilderService extends BuilderService {
public List<? extends ModuleLevelBuilder> createModuleLevelBuilders(ExecutorService executorService) {
return Arrays.asList(new AndroidSourceGeneratingBuilder(),
new AndroidLibraryPackagingBuilder(),
new AndroidDexBuilder(),
new AndroidPackagingBuilder());
new AndroidResourcePackagingBuilder());
}
@NotNull
@Override
public List<? extends ProjectLevelBuilder> createProjectLevelBuilders() {
return Arrays.asList(new AndroidDexBuilder());
}
}
@@ -0,0 +1,60 @@
package org.jetbrains.jps.android;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.incremental.storage.ValidityState;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* @author Eugene.Kudelevsky
*/
class AndroidClassesAndJarsState implements ValidityState {
private Map<String, Long> myFiles;
public AndroidClassesAndJarsState(@NotNull Collection<String> roots) {
myFiles = new HashMap<String, Long>();
for (String rootPath : roots) {
AndroidJpsUtil.processClassFilesAndJarsRecursively(rootPath, new Processor<File>() {
@Override
public boolean process(File file) {
myFiles.put(FileUtil.toSystemIndependentName(file.getPath()), file.lastModified());
return true;
}
});
}
}
public AndroidClassesAndJarsState(@NotNull DataInput in) throws IOException {
myFiles = new HashMap<String, Long>();
int size = in.readInt();
while (size-- > 0) {
final String path = in.readUTF();
final long timestamp = in.readLong();
myFiles.put(path, timestamp);
}
}
public boolean equalsTo(ValidityState otherState) {
return otherState instanceof AndroidClassesAndJarsState
&& myFiles.equals(((AndroidClassesAndJarsState)otherState).myFiles);
}
public void save(DataOutput out) throws IOException {
out.writeInt(myFiles.size());
for (String path : myFiles.keySet()) {
out.writeUTF(path);
out.writeLong(myFiles.get(path));
}
}
}
@@ -0,0 +1,43 @@
package org.jetbrains.jps.android;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.incremental.storage.AbstractStateStorage;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidClassesAndJarsStateStorage extends AbstractStateStorage<String, AndroidClassesAndJarsState> {
@NonNls private static final String ANDROID_CLASSES_AND_JARS_STORAGE_DIR = "android_classes_and_jars";
@NonNls private static final String CLASSES_AND_JARS_STORAGE = "classes_and_jars";
public AndroidClassesAndJarsStateStorage(@NotNull File dataStorageRoot) throws IOException {
super(getStorageFile(dataStorageRoot), new EnumeratorStringDescriptor(), new MyDataExternalizer());
}
@NotNull
private static File getStorageFile(@NotNull File dataStorageRoot) {
return new File(new File(dataStorageRoot, ANDROID_CLASSES_AND_JARS_STORAGE_DIR), CLASSES_AND_JARS_STORAGE);
}
private static class MyDataExternalizer implements DataExternalizer<AndroidClassesAndJarsState> {
@Override
public void save(DataOutput out, AndroidClassesAndJarsState value) throws IOException {
value.save(out);
}
@Override
public AndroidClassesAndJarsState read(DataInput in) throws IOException {
return new AndroidClassesAndJarsState(in);
}
}
}
@@ -13,9 +13,11 @@ import org.jetbrains.android.util.AndroidCompilerMessageKind;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.Module;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.ExternalProcessUtil;
import org.jetbrains.jps.incremental.ProjectBuildException;
import org.jetbrains.jps.incremental.ProjectLevelBuilder;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
@@ -28,37 +30,48 @@ import java.util.*;
/**
* @author Eugene.Kudelevsky
*/
// todo: save validity state
// todo: support light builds (for tests)
public class AndroidDexBuilder extends ModuleLevelBuilder {
public class AndroidDexBuilder extends ProjectLevelBuilder {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.android.AndroidDexBuilder");
@NonNls private static final String BUILDER_NAME = "android-dex";
protected AndroidDexBuilder() {
super(BuilderCategory.CLASS_POST_PROCESSOR);
}
@Override
public ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
if (context.isCompilingTests() || !AndroidJpsUtil.containsAndroidFacet(chunk)) {
return ModuleLevelBuilder.ExitCode.OK;
public void build(CompileContext context) throws ProjectBuildException {
if (!AndroidJpsUtil.containsAndroidFacet(context.getProject())) {
return;
}
context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.dex")));
try {
return doBuild(context, chunk);
doBuild(context);
}
catch (ProjectBuildException e) {
throw e;
}
catch (Exception e) {
return AndroidJpsUtil.handleException(context, e, BUILDER_NAME);
AndroidJpsUtil.handleException(context, e, BUILDER_NAME);
}
}
private static ExitCode doBuild(CompileContext context, ModuleChunk chunk) {
private static void doBuild(CompileContext context) throws IOException, ProjectBuildException {
final AndroidClassesAndJarsStateStorage storage = new AndroidClassesAndJarsStateStorage(context.getDataManager().getDataStorageRoot());
try {
if (!doDexBuild(context, storage)) {
throw new ProjectBuildException();
}
}
finally {
storage.close();
}
}
private static boolean doDexBuild(CompileContext context, AndroidClassesAndJarsStateStorage storage) {
boolean success = true;
for (Module module : chunk.getModules()) {
for (Module module : context.getProject().getModules().values()) {
final AndroidFacet facet = AndroidJpsUtil.getFacet(module);
if (facet == null || facet.getLibrary()) {
continue;
@@ -92,35 +105,51 @@ public class AndroidDexBuilder extends ModuleLevelBuilder {
continue;
}
final Set<String> fileSet = new HashSet<String>();
AndroidJpsUtil.addSubdirectories(classesDir, fileSet);
fileSet.addAll(AndroidJpsUtil.getExternalLibraries(projectPaths, module));
for (String filePath : AndroidJpsUtil.getClassdirsOfDependentModules(projectPaths, module)) {
if (!classesDir.getPath().equals(filePath)) {
fileSet.add(filePath);
try {
final Set<String> fileSet = new HashSet<String>();
AndroidJpsUtil.addSubdirectories(classesDir, fileSet);
fileSet.addAll(AndroidJpsUtil.getExternalLibraries(projectPaths, module));
for (String filePath : AndroidJpsUtil.getClassdirsOfDependentModules(projectPaths, module)) {
if (!classesDir.getPath().equals(filePath)) {
fileSet.add(filePath);
}
}
if (facet.isLibrary()) {
final File testsClassDir = projectPaths.getModuleOutputDir(module, true);
if (testsClassDir != null && testsClassDir.isDirectory()) {
AndroidJpsUtil.addSubdirectories(testsClassDir, fileSet);
}
}
final AndroidClassesAndJarsState newState = new AndroidClassesAndJarsState(fileSet);
final AndroidClassesAndJarsState oldState = storage.getState(module.getName());
if (oldState != null && oldState.equalsTo(newState)) {
continue;
}
final String[] files = new String[fileSet.size()];
int i = 0;
for (String filePath : fileSet) {
files[i++] = FileUtil.toSystemDependentName(filePath);
}
if (!runDex(androidSdk, target, dexOutputDir.getPath(), files, context)) {
success = false;
}
else {
storage.update(module.getName(), newState);
}
}
if (facet.isLibrary()) {
final File testsClassDir = projectPaths.getModuleOutputDir(module, true);
if (testsClassDir != null && testsClassDir.isDirectory()) {
AndroidJpsUtil.addSubdirectories(testsClassDir, fileSet);
}
}
final String[] files = new String[fileSet.size()];
int i = 0;
for (String filePath : fileSet) {
files[i++] = FileUtil.toSystemDependentName(filePath);
}
if (!runDex(androidSdk, target, dexOutputDir.getPath(), files, context)) {
success = false;
catch (IOException e) {
AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME);
return false;
}
}
return success ? ExitCode.OK : ExitCode.ABORT;
return success;
}
@Override
@@ -137,7 +166,7 @@ public class AndroidDexBuilder extends ModuleLevelBuilder {
@NotNull IAndroidTarget target,
@NotNull String outputDir,
@NotNull String[] compileTargets,
@NotNull CompileContext context) {
@NotNull CompileContext context) throws IOException {
@SuppressWarnings("deprecation")
final String dxJarPath = FileUtil.toSystemDependentName(target.getPath(IAndroidTarget.DX_JAR));
@@ -173,23 +202,17 @@ public class AndroidDexBuilder extends ModuleLevelBuilder {
LOG.info(AndroidCommonUtils.command2string(commandLine));
try {
final Process process = Runtime.getRuntime().exec(ArrayUtil.toStringArray(commandLine));
final Process process = Runtime.getRuntime().exec(ArrayUtil.toStringArray(commandLine));
final HashMap<AndroidCompilerMessageKind, List<String>> messages = new HashMap<AndroidCompilerMessageKind, List<String>>(3);
messages.put(AndroidCompilerMessageKind.ERROR, new ArrayList<String>());
messages.put(AndroidCompilerMessageKind.WARNING, new ArrayList<String>());
messages.put(AndroidCompilerMessageKind.INFORMATION, new ArrayList<String>());
final HashMap<AndroidCompilerMessageKind, List<String>> messages = new HashMap<AndroidCompilerMessageKind, List<String>>(3);
messages.put(AndroidCompilerMessageKind.ERROR, new ArrayList<String>());
messages.put(AndroidCompilerMessageKind.WARNING, new ArrayList<String>());
messages.put(AndroidCompilerMessageKind.INFORMATION, new ArrayList<String>());
AndroidCommonUtils.handleDexCompilationResult(process, outFilePath, messages);
AndroidCommonUtils.handleDexCompilationResult(process, outFilePath, messages);
AndroidJpsUtil.addMessages(context, messages, BUILDER_NAME);
AndroidJpsUtil.addMessages(context, messages, BUILDER_NAME);
return messages.get(AndroidCompilerMessageKind.ERROR).size() == 0;
}
catch (IOException e) {
AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME);
return false;
}
return messages.get(AndroidCompilerMessageKind.ERROR).size() == 0;
}
}
@@ -130,7 +130,13 @@ class AndroidJpsUtil {
final File file = new File(filePath);
if (file.exists()) {
collectClassFilesAndJars(filePath, libraries);
processClassFilesAndJarsRecursively(filePath, new Processor<File>() {
@Override
public boolean process(File file) {
libraries.add(file.getPath());
return true;
}
});
}
}
}
@@ -162,8 +168,7 @@ class AndroidJpsUtil {
}
}
private static void collectClassFilesAndJars(@NotNull String root,
@NotNull final Set<String> result) {
public static void processClassFilesAndJarsRecursively(@NotNull String root, @NotNull final Processor<File> processor) {
FileUtil.processFilesRecursively(new File(root), new Processor<File>() {
@Override
public boolean process(File file) {
@@ -171,7 +176,9 @@ class AndroidJpsUtil {
final String ext = FileUtil.getExtension(file.getName());
if ("jar".equals(ext) || "class".equals(ext)) {
result.add(file.getPath());
if (!processor.process(file)) {
return false;
}
}
}
return true;
@@ -247,6 +254,15 @@ class AndroidJpsUtil {
return false;
}
public static boolean containsAndroidFacet(@NotNull Project project) {
for (Module module : project.getModules().values()) {
if (getFacet(module) != null) {
return true;
}
}
return false;
}
public static ModuleLevelBuilder.ExitCode handleException(@NotNull CompileContext context,
@NotNull Exception e,
@NotNull String builderName)
@@ -23,7 +23,6 @@ import java.util.Set;
* @author Eugene.Kudelevsky
*/
// todo: save validity states
// todo: support light builds
public class AndroidLibraryPackagingBuilder extends ModuleLevelBuilder {
@@ -48,46 +47,60 @@ public class AndroidLibraryPackagingBuilder extends ModuleLevelBuilder {
}
}
private static ModuleLevelBuilder.ExitCode doBuild(CompileContext context, ModuleChunk chunk) {
private static ModuleLevelBuilder.ExitCode doBuild(CompileContext context, ModuleChunk chunk) throws IOException {
boolean success = true;
final AndroidClassesAndJarsStateStorage storage = new AndroidClassesAndJarsStateStorage(context.getDataManager().getDataStorageRoot());
for (Module module : chunk.getModules()) {
final AndroidFacet facet = AndroidJpsUtil.getFacet(module);
if (facet == null || !facet.isLibrary()) {
continue;
}
final ProjectPaths projectPaths = context.getProjectPaths();
final File outputDirectoryForPackagedFiles = AndroidJpsUtil.getOutputDirectoryForPackagedFiles(projectPaths, module);
if (outputDirectoryForPackagedFiles == null) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle
.message("android.jps.errors.output.dir.not.specified", module.getName())));
success = false;
continue;
}
final File classesDir = projectPaths.getModuleOutputDir(module, false);
if (classesDir == null || !classesDir.isDirectory()) {
continue;
}
final Set<String> subdirs = new HashSet<String>();
AndroidJpsUtil.addSubdirectories(classesDir, subdirs);
if (subdirs.size() > 0) {
final File outputJarFile = new File(outputDirectoryForPackagedFiles, AndroidCommonUtils.CLASSES_JAR_FILE_NAME);
try {
AndroidCommonUtils.packClassFilesIntoJar(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.toStringArray(subdirs), outputJarFile);
try {
for (Module module : chunk.getModules()) {
final AndroidFacet facet = AndroidJpsUtil.getFacet(module);
if (facet == null || !facet.isLibrary()) {
continue;
}
catch (IOException e) {
AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME);
final ProjectPaths projectPaths = context.getProjectPaths();
final File outputDirectoryForPackagedFiles = AndroidJpsUtil.getOutputDirectoryForPackagedFiles(projectPaths, module);
if (outputDirectoryForPackagedFiles == null) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle
.message("android.jps.errors.output.dir.not.specified", module.getName())));
success = false;
continue;
}
final File classesDir = projectPaths.getModuleOutputDir(module, false);
if (classesDir == null || !classesDir.isDirectory()) {
continue;
}
final Set<String> subdirs = new HashSet<String>();
AndroidJpsUtil.addSubdirectories(classesDir, subdirs);
final AndroidClassesAndJarsState newState = new AndroidClassesAndJarsState(subdirs);
final AndroidClassesAndJarsState oldState = storage.getState(module.getName());
if (oldState != null && oldState.equals(newState)) {
continue;
}
if (subdirs.size() > 0) {
final File outputJarFile = new File(outputDirectoryForPackagedFiles, AndroidCommonUtils.CLASSES_JAR_FILE_NAME);
try {
AndroidCommonUtils.packClassFilesIntoJar(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.toStringArray(subdirs), outputJarFile);
storage.update(module.getName(), newState);
}
catch (IOException e) {
AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME);
success = false;
}
}
}
return success ? ModuleLevelBuilder.ExitCode.OK : ModuleLevelBuilder.ExitCode.ABORT;
}
finally {
storage.close();
}
return success ? ModuleLevelBuilder.ExitCode.OK : ModuleLevelBuilder.ExitCode.ABORT;
}
@Override
@@ -29,10 +29,10 @@ import java.util.Map;
// todo: save validity states
// todo: support light builds (for tests)
public class AndroidPackagingBuilder extends ModuleLevelBuilder {
public class AndroidResourcePackagingBuilder extends ModuleLevelBuilder {
@NonNls private static final String BUILDER_NAME = "android-packager";
protected AndroidPackagingBuilder() {
protected AndroidResourcePackagingBuilder() {
super(BuilderCategory.PACKAGER);
}
@@ -301,10 +301,14 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
final Set<String> depLibPackagesSet = getDepLibPackages(module);
depLibPackagesSet.remove(packageName);
if (!updateState(module, resPaths, manifestFile, packageName, depLibPackagesSet, storage)) {
final Set<ResourceEntry> resources = collectResources(resPaths);
final Set<ResourceEntry> manifestElements = collectManifestElements(manifestFile);
final AndroidAptValidityState newState = new AndroidAptValidityState(resources, manifestElements, depLibPackagesSet, packageName);
final AndroidAptValidityState oldState = storage.getState(module.getName());
if (newState.equalsTo(oldState)) {
continue;
}
final File outputDirectory = moduleData.getOutputDirectory();
final File aptOutputDirectory = new File(outputDirectory, "generated-aapt");
@@ -323,6 +327,7 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
success = false;
}
else {
storage.update(module.getName(), newState);
JavaBuilder.addTempSourcePathRoot(context, aptOutputDirectory);
}
}
@@ -334,25 +339,6 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
return success;
}
private static boolean updateState(@NotNull Module module,
@NotNull String[] resPaths,
@NotNull File manifestFile,
@NotNull String packageName,
@NotNull Set<String> depLibPackagesSet,
@NotNull AndroidAptStateStorage storage) throws IOException {
final Set<ResourceEntry> resources = collectResources(resPaths);
final Set<ResourceEntry> manifestElements = collectManifestElements(manifestFile);
final AndroidAptValidityState newState = new AndroidAptValidityState(resources, manifestElements, depLibPackagesSet, packageName);
final AndroidAptValidityState oldState = storage.getState(module.getName());
if (newState.equalsTo(oldState)) {
return false;
}
storage.update(module.getName(), newState);
return true;
}
@NotNull
private static Set<String> getDepLibPackages(@NotNull Module module) throws IOException {
final Set<String> result = new HashSet<String>();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -25,10 +25,7 @@ import com.intellij.openapi.cvsIntegration.CvsResult;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.actions.VcsContextFactory;
import com.intellij.openapi.vcs.changes.ChangesUtil;
@@ -58,11 +55,9 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi
private static final Logger LOG = Logger.getInstance("#com.intellij.cvsSupport2.changeBrowser.CvsCommittedChangesProvider");
private final Project myProject;
private final MyZipper myZipper;
public CvsCommittedChangesProvider(Project project) {
myProject = project;
myZipper = new MyZipper();
}
public ChangeBrowserSettings createDefaultSettings() {
@@ -74,10 +69,13 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi
}
public VcsCommittedListsZipper getZipper() {
return myZipper;
return new MyZipper();
}
private static class MyZipper extends VcsCommittedListsZipperAdapter {
private long lastNumber = 0;
private final Map<CommittedChangeListKey, Long> numberCache = new HashMap();
private MyZipper() {
super(new GroupCreator() {
public Object createKey(final RepositoryLocation location) {
@@ -97,7 +95,22 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi
@Override
public long getNumber(final CommittedChangeList list) {
return list.getCommitDate().getTime();
final long time = list.getCommitDate().getTime();
final Long roundedTime = Long.valueOf(time - (time % CvsChangeList.SUITABLE_DIFF));
final CommittedChangeListKey key = new CommittedChangeListKey(list.getCommitterName(), roundedTime, list.getComment());
final Long number = numberCache.get(key);
if (number == null) {
numberCache.put(key, Long.valueOf(lastNumber));
return lastNumber++;
}
return number.longValue();
}
}
private static class CommittedChangeListKey extends Trinity<String, Long, String> {
CommittedChangeListKey(String name, Long commitDate, String comment) {
super(name, commitDate, comment);
}
}
@@ -44,7 +44,7 @@ public abstract class XPathAction extends AnAction {
} else if (ActionPlaces.MAIN_MENU.equals(event.getPlace())) {
updateMainMenu(event);
} else if (ActionPlaces.EDITOR_POPUP.equals(event.getPlace())) {
updatePopupMenu(event);
presentation.setVisible(presentation.isEnabled());
}
}
@@ -53,22 +53,18 @@ public abstract class XPathAction extends AnAction {
event.getPresentation().setVisible(b && isEnabled(event, false));
}
protected void updatePopupMenu(AnActionEvent event) {
event.getPresentation().setVisible(isEnabled(event, false));
}
protected void updateToolbar(AnActionEvent event) {
event.getPresentation().setVisible(myComponent.getConfig().SHOW_IN_TOOLBAR);
}
protected boolean isEnabled(AnActionEvent event, boolean checkAvailable) {
final Project project = LangDataKeys.PROJECT.getData(event.getDataContext());
final Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext());
if (project == null) {
// no active project
return false;
}
Editor editor = LangDataKeys.EDITOR.getData(event.getDataContext());
Editor editor = PlatformDataKeys.EDITOR.getData(event.getDataContext());
if (editor == null) {
FileEditorManager fem = FileEditorManager.getInstance(project);
editor = fem.getSelectedTextEditor();