Merge remote-tracking branch 'origin/master' appcode/163.5074 clion/163.5075
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>
Fri, 23 Sep 2016 14:54:41 +0000 (17:54 +0300)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Fri, 23 Sep 2016 14:54:41 +0000 (17:54 +0300)
33 files changed:
java/java-impl/src/com/intellij/ide/scopeView/nodes/ClassNode.java
java/java-impl/src/com/intellij/ide/scopeView/nodes/FieldNode.java
java/java-impl/src/com/intellij/ide/scopeView/nodes/MemberNode.java [new file with mode: 0644]
java/java-impl/src/com/intellij/ide/scopeView/nodes/MethodNode.java
java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java
java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/AtomicConversionRule.java
java/typeMigration/testData/intentions/atomic/afterAssignmentOp.java [new file with mode: 0644]
java/typeMigration/testData/intentions/atomic/beforeAssignmentOp.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/application/options/colors/ConsoleFontOptions.java
platform/lang-impl/src/com/intellij/application/options/colors/FontOptions.java
platform/lang-impl/src/com/intellij/application/options/colors/ScopeColorsPageFactory.java
platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
platform/platform-impl/src/com/intellij/internal/statistic/ScaleInfoUsageCollector.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java
platform/platform-impl/src/com/intellij/ui/ComboboxEditorTextField.java
platform/platform-resources-en/src/messages/IdeBundle.properties
platform/platform-resources/src/META-INF/PlatformExtensions.xml
platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java
platform/util/src/com/intellij/util/ui/HTMLEditorKitProvider.java [new file with mode: 0644]
platform/util/src/com/intellij/util/ui/JBUI.java
platform/util/src/com/intellij/util/ui/UIUtil.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java
python/helpers/pydev/_pydev_bundle/_pydev_completer.py
python/helpers/pydev/_pydevd_bundle/pydevd_referrers.py
python/helpers/pydev/tests_pydevd_python/test_pydev_monkey.py
python/testData/debug/test_resume.py [moved from python/testData/debug/Test_Resume.py with 100% similarity]
python/testData/debug/test_two_threads.py
python/testSrc/com/jetbrains/env/python/PythonDebuggerTest.java
python/testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java

index 383ba4b5aaf4ba6012301e8a4f6c70b12e3afccb..dc4eb2624c8a3d58c4916ab7b961315480b4ad9d 100644 (file)
@@ -23,7 +23,7 @@ import com.intellij.psi.presentation.java.ClassPresentationUtil;
  * User: anna
  * Date: 30-Jan-2006
  */
-public class ClassNode extends BasePsiNode<PsiClass> implements Comparable<ClassNode>{
+public class ClassNode extends MemberNode<PsiClass> implements Comparable<ClassNode>{
   public ClassNode(final PsiClass aClass) {
     super(aClass);
   }
@@ -33,12 +33,6 @@ public class ClassNode extends BasePsiNode<PsiClass> implements Comparable<Class
     return aClass != null && aClass.isValid() ? ClassPresentationUtil.getNameForClass(aClass, false) : "";
   }
 
-  @Override
-  public boolean isDeprecated() {
-    final PsiClass psiClass = (PsiClass)getPsiElement();
-    return psiClass != null && psiClass.isDeprecated();
-  }
-
   public int compareTo(final ClassNode o) {
     final int comparision = ClassTreeNode.getClassPosition((PsiClass)getPsiElement()) - ClassTreeNode.getClassPosition((PsiClass)o.getPsiElement());
     if (comparision == 0) {
index 919f1b1960da6e0d8e2349b59cc303239ddd6365..42e52fd2b0b8dbb75d3ce1a1b8098465903e3bb1 100644 (file)
@@ -24,7 +24,7 @@ import com.intellij.psi.util.PsiFormatUtil;
  * User: anna
  * Date: 30-Jan-2006
  */
-public class FieldNode extends BasePsiNode<PsiField> {
+public class FieldNode extends MemberNode<PsiField> {
 
   public FieldNode(final PsiField field) {
     super(field);
@@ -47,10 +47,4 @@ public class FieldNode extends BasePsiNode<PsiField> {
   public int getWeight() {
     return 5;
   }
-
-  @Override
-  public boolean isDeprecated() {
-    final PsiField psiField = (PsiField)getPsiElement();
-    return psiField != null && psiField.isDeprecated();
-  }
 }
diff --git a/java/java-impl/src/com/intellij/ide/scopeView/nodes/MemberNode.java b/java/java-impl/src/com/intellij/ide/scopeView/nodes/MemberNode.java
new file mode 100644 (file)
index 0000000..fb959b4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2016 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.scopeView.nodes;
+
+import com.intellij.openapi.project.DumbService;
+import com.intellij.psi.PsiDocCommentOwner;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class MemberNode<T extends PsiDocCommentOwner> extends BasePsiNode<T> {
+
+  public MemberNode(T element) {
+    super(element);
+  }
+
+  @Override
+  public final boolean isDeprecated() {
+    if (DumbService.isDumb(myProject)) return false;
+    final PsiDocCommentOwner psiField = (PsiDocCommentOwner)getPsiElement();
+    return psiField != null && psiField.isDeprecated();
+  }
+}
index 9bccefd2db2f4d2ac818eab18fd03a1ade765fe8..4928bbc749b05bde47b6ddde77538cc1a1bb589f 100644 (file)
@@ -25,7 +25,7 @@ import com.intellij.psi.util.PsiFormatUtil;
  * User: anna
  * Date: 30-Jan-2006
  */
-public class MethodNode extends BasePsiNode<PsiMethod> {
+public class MethodNode extends MemberNode<PsiMethod> {
 
   public MethodNode(final PsiMethod element) {
     super(element);
@@ -51,10 +51,4 @@ public class MethodNode extends BasePsiNode<PsiMethod> {
   public int getWeight() {
     return 5;
   }
-
-  @Override
-  public boolean isDeprecated() {
-    final PsiMethod psiMethod = (PsiMethod)getPsiElement();
-    return psiMethod != null && psiMethod.isDeprecated();
-  }
 }
index c1b36db3267a28c963c001aaf01783e53a8b1f98..bf2f17d838d6d21497179335c0ebc3694caea711 100644 (file)
@@ -7,7 +7,6 @@ import com.intellij.lang.java.JavaLanguage;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -21,15 +20,14 @@ import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
 import com.intellij.refactoring.typeMigration.TypeEvaluator;
 import com.intellij.refactoring.typeMigration.TypeMigrationReplacementUtil;
 import com.intellij.refactoring.typeMigration.rules.AtomicConversionRule;
-import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo;
 import com.intellij.refactoring.util.RefactoringUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.Query;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.*;
@@ -160,7 +158,8 @@ public class ConvertFieldToAtomicIntention extends PsiElementBaseIntentionAction
 
     try {
       for (PsiReference reference : refs) {
-        PsiElement psiElement = reference.getElement();
+        PsiElement refElement = reference.getElement();
+        PsiElement psiElement = refElement;
         if (psiElement instanceof PsiExpression) {
           final PsiElement parent = psiElement.getParent();
           if (parent instanceof PsiExpression && !(parent instanceof PsiReferenceExpression || parent instanceof PsiPolyadicExpression)) {
@@ -168,14 +167,14 @@ public class ConvertFieldToAtomicIntention extends PsiElementBaseIntentionAction
           }
           if (psiElement instanceof PsiBinaryExpression) {
             PsiBinaryExpression binary = (PsiBinaryExpression)psiElement;
-            if (isBinaryOperatorApplicable(binary.getOperationTokenType(), binary.getLOperand(), binary.getROperand(), true)) {
+            if (isBinaryOpApplicable(binary.getOperationTokenType(), binary.getLOperand(), binary.getROperand(), refElement, toType)) {
               continue;
             }
           }
           else if (psiElement instanceof PsiAssignmentExpression) {
             final PsiAssignmentExpression assignment = (PsiAssignmentExpression)psiElement;
             final IElementType opSign = TypeConversionUtil.convertEQtoOperation(assignment.getOperationTokenType());
-            if (opSign != null && isBinaryOperatorApplicable(opSign, assignment.getLExpression(), assignment.getRExpression(), true)) {
+            if (isBinaryOpApplicable(opSign, assignment.getLExpression(), assignment.getRExpression(), refElement, toType)) {
               continue;
             }
           }
@@ -227,4 +226,15 @@ public class ConvertFieldToAtomicIntention extends PsiElementBaseIntentionAction
   public boolean startInWriteAction() {
     return true;
   }
+
+  private static boolean isBinaryOpApplicable(@Nullable IElementType opSign,
+                                              @NotNull PsiExpression lExpr,
+                                              @Nullable PsiExpression rExpr,
+                                              @NotNull PsiElement varElement,
+                                              @NotNull PsiType migrationType) {
+    if (opSign == null || rExpr == null) return false;
+    PsiType lType = lExpr == varElement ? migrationType : lExpr.getType();
+    PsiType rType = rExpr == varElement ? migrationType : rExpr.getType();
+    return isBinaryOperatorApplicable(opSign, lType, rType, true);
+  }
 }
index a6275b650266d944a0df7c06ef7676cc94097692..21195048f5e89b0d10d6255668bb07baa5988899 100644 (file)
@@ -7,13 +7,16 @@ package com.intellij.refactoring.typeMigration.rules;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.impl.PsiDiamondTypeUtil;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.psi.util.TypeConversionUtil;
 import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
 import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
+import com.intellij.refactoring.typeMigration.TypeEvaluator;
 import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -114,9 +117,22 @@ public class AtomicConversionRule extends TypeConversionRule {
           final IElementType operationSign = signToken.getTokenType();
           final String sign = signToken.getText();
           if (operationSign == JavaTokenType.PLUSEQ || operationSign == JavaTokenType.MINUSEQ) {
-            return new TypeConversionDescriptor("$qualifier$ " + sign + " $val$", "$qualifier$.getAndAdd(" +
-                                                                                  (operationSign == JavaTokenType.MINUSEQ ? "-" : "") +
-                                                                                  "($val$))");
+            return new TypeConversionDescriptor("$qualifier$ " + sign + " $val$",
+                                                "$qualifier$.addAndGet(" + (operationSign == JavaTokenType.MINUSEQ ? "-($val$))" : "$val$)")) {
+              @Override
+              public PsiExpression replace(PsiExpression expression, TypeEvaluator evaluator) {
+                final PsiMethodCallExpression result = (PsiMethodCallExpression)super.replace(expression, evaluator);
+                final PsiExpression argument = result.getArgumentList().getExpressions()[0];
+                if (argument instanceof PsiPrefixExpression) {
+                  final PsiExpression operand = ((PsiPrefixExpression)argument).getOperand();
+                  final PsiExpression striped = ParenthesesUtils.stripParentheses(operand);
+                  if (striped != null && operand != striped) {
+                    operand.replace(striped);
+                  }
+                }
+                return result;
+              }
+            };
           }
         }
       }
@@ -198,11 +214,22 @@ public class AtomicConversionRule extends TypeConversionRule {
           return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.set($val$)");
         }
         else {
-          return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.set(" +
-                                                                              getBoxedWrapper(from, to, "$qualifier$.get() " +
-                                                                                                        sign.charAt(0) +
-                                                                                                        " $val$") +
-                                                                              ")");
+          if (PsiUtil.isLanguageLevel8OrHigher(context)) {
+            final String name =
+              JavaCodeStyleManager.getInstance(context.getProject()).suggestUniqueVariableName("v", context, false);
+            return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.updateAndGet("
+                                                                                + name + " -> " + name + " " + sign.charAt(0) + " $val$)"); }
+          else {
+            if (context.getParent() instanceof PsiStatement) {
+              return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.set(" +
+                                                                                  getBoxedWrapper(from, to, "$qualifier$.get() " +
+                                                                                                            sign.charAt(0) +
+                                                                                                            " $val$") +
+                                                                                  ")");
+            } else {
+              return null;
+            }
+          }
         }
       } //else should be a conflict
     }
diff --git a/java/typeMigration/testData/intentions/atomic/afterAssignmentOp.java b/java/typeMigration/testData/intentions/atomic/afterAssignmentOp.java
new file mode 100644 (file)
index 0000000..0bb7d49
--- /dev/null
@@ -0,0 +1,18 @@
+import java.util.concurrent.atomic.AtomicLong;
+
+// "Convert to atomic" "true"
+class A {
+  final AtomicLong x = new AtomicLong(0);
+
+  public void testAtomicLong() {
+    x.getAndIncrement();
+    x.getAndDecrement();
+    x.addAndGet(2);
+    x.addAndGet(-2);
+    x.updateAndGet(v -> v * 3);
+    x.updateAndGet(v -> v / 3);
+    x.updateAndGet(v -> v % 3);
+    x.updateAndGet(v -> v & 3);
+    x.updateAndGet(v -> v | 3);
+  }
+}
\ No newline at end of file
diff --git a/java/typeMigration/testData/intentions/atomic/beforeAssignmentOp.java b/java/typeMigration/testData/intentions/atomic/beforeAssignmentOp.java
new file mode 100644 (file)
index 0000000..6b6d59d
--- /dev/null
@@ -0,0 +1,16 @@
+// "Convert to atomic" "true"
+class A {
+  long <caret>x = 0;
+
+  public void testAtomicLong() {
+    x++;
+    x--;
+    x+=2;
+    x-=2;
+    x*=3;
+    x/=3;
+    x%=3;
+    x&=3;
+    x|=3;
+  }
+}
\ No newline at end of file
index 59e36910097bb517b4ced0be07c1b5a22c2ab547..8c1fdb85be87a00e5cc0410530ac83489d5c7994 100644 (file)
@@ -32,6 +32,11 @@ public class ConsoleFontOptions extends FontOptions {
     return getCurrentScheme().getConsoleFontPreferences();
   }
 
+  @Override
+  protected void setFontSize(int fontSize) {
+    getCurrentScheme().setConsoleFontSize(fontSize);
+  }
+
   @Override
   protected float getLineSpacing() {
     return getCurrentScheme().getConsoleLineSpacing();
index 6e43fa0c730659613a812eae0d64433ca469400a..a3843dea882c0192f1d21d078d9d543e8da3c773 100644 (file)
@@ -147,8 +147,7 @@ public class FontOptions extends JPanel implements OptionsPanel{
         if (myIsInSchemeChange || !SwingUtilities.isEventDispatchThread()) return;
         String selectedFont = myPrimaryCombo.getFontName();
         if (selectedFont != null) {
-          FontPreferences fontPreferences = getFontPreferences();
-          fontPreferences.register(selectedFont, getFontSizeFromField());
+          setFontSize(getFontSizeFromField());
         }
         updateDescription(true);
       }
@@ -296,6 +295,10 @@ public class FontOptions extends JPanel implements OptionsPanel{
     return getCurrentScheme().getFontPreferences();
   }
 
+  protected void setFontSize(int fontSize) {
+    getCurrentScheme().setEditorFontSize(fontSize);
+  }
+
   protected float getLineSpacing() {
     return getCurrentScheme().getLineSpacing();
   }
index ffe5afdadfe4469aa4de51fb98bde82e6b7f9aa8..cba8bb463ef3b45a97b7a0a9e0b4bd98a856e3d4 100644 (file)
@@ -20,9 +20,11 @@ import com.intellij.ide.DataManager;
 import com.intellij.ide.util.scopeChooser.EditScopesDialog;
 import com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.options.ex.Settings;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectManager;
+import com.intellij.util.ui.JBUI;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
@@ -56,9 +58,7 @@ class ScopeColorsPageFactory implements ColorAndFontPanelFactory {
     //panel.setBorder(new LineBorder(Color.red));
     if (projects.length == 0) return panel;
     GridBagConstraints gc = new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
-                                                   new Insets(0, 0, 0, 0), 0, 0);
-    final Project contextProject = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
-    final Project project = contextProject != null ? contextProject : projects[0];
+                                                   JBUI.emptyInsets(), 0, 0);
 
     JButton button = new JButton("Manage Scopes...");
     button.setPreferredSize(new Dimension(230, button.getPreferredSize().height));
@@ -74,7 +74,9 @@ class ScopeColorsPageFactory implements ColorAndFontPanelFactory {
     button.addActionListener(new ActionListener() {
       @Override
       public void actionPerformed(@NotNull ActionEvent e) {
-        Settings settings = Settings.KEY.getData(DataManager.getInstance().getDataContext());
+        DataContext context = DataManager.getInstance().getDataContext(panel);
+        Settings settings = Settings.KEY.getData(context);
+        Project project = CommonDataKeys.PROJECT.getData(context);
         if (settings != null) {
           try {
             if (settings.select(settings.find(ScopeChooserConfigurable.PROJECT_SCOPES)).isRejected()) {
index a9cf0aeeefe3903f85fed5c0639b0fe3ba14ec59..3ccf199c0dab942fe5de2daf63be6e71854e1b18 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.ide.actions;
 
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.IdeBundle;
+import com.intellij.ide.highlighter.ProjectFileType;
 import com.intellij.ide.impl.ProjectUtil;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -90,10 +91,23 @@ public class OpenFileAction extends AnAction implements DumbAware {
 
       // try to open as a project - unless the file is an .ipr of the current one
       if ((project == null || !file.equals(project.getProjectFile())) && OpenProjectFileChooserDescriptor.isProjectFile(file)) {
-        Project openedProject = ProjectUtil.openOrImport(file.getPath(), project, false);
-        if (openedProject != null) {
-          FileChooserUtil.setLastOpenedFile(openedProject, file);
-          return;
+        int answer = file.getFileType() instanceof ProjectFileType
+                     ? Messages.YES
+                     : Messages.showYesNoCancelDialog(project,
+                                                IdeBundle.message("message.open.file.is.project", file.getName()),
+                                                IdeBundle.message("title.open.project"),
+                                                IdeBundle.message("message.open.file.is.project.open.as.project"),
+                                                IdeBundle.message("message.open.file.is.project.open.as.file"),
+                                                IdeBundle.message("button.cancel"),
+                                                Messages.getQuestionIcon());
+        if (answer == Messages.CANCEL)  return;
+        
+        if (answer == Messages.YES) {
+          Project openedProject = ProjectUtil.openOrImport(file.getPath(), project, false);
+          if (openedProject != null) {
+            FileChooserUtil.setLastOpenedFile(openedProject, file);
+            return;
+          }
         }
       }
 
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/ScaleInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/ScaleInfoUsageCollector.java
new file mode 100644 (file)
index 0000000..fdec26e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2016 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.internal.statistic;
+
+import com.intellij.internal.statistic.beans.GroupDescriptor;
+import com.intellij.internal.statistic.beans.UsageDescriptor;
+import com.intellij.util.ui.JBUI;
+import com.intellij.util.ui.UIUtil;
+import org.jdesktop.swingx.util.OS;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author tav
+ */
+public class ScaleInfoUsageCollector extends UsagesCollector {
+  @NotNull
+  @Override
+  public Set<UsageDescriptor> getUsages() throws CollectUsagesException {
+    float scale = JBUI.SYSTEM_DEF_SCALE;
+
+    if (OS.isMacOSX()) {
+      scale = UIUtil.isRetina() ? 2.0f : 1.0f;
+    } else {
+      int scaleBase = (int)Math.floor(scale);
+      float scaleFract = scale - scaleBase;
+
+      if (scaleFract == 0.0f) scaleFract = 0.0f; // count integer scale on a precise match only
+      else if (scaleFract < 0.375f) scaleFract = 0.25f;
+      else if (scaleFract < 0.625f) scaleFract = 0.5f;
+      else scaleFract = 0.75f;
+
+      scale = scaleBase + scaleFract;
+    }
+
+    String os = OS.isWindows() ? "Windows" : OS.isLinux() ? "Linux" : OS.isMacOSX() ? "Mac" : "Unknown OS";
+    return Collections.singleton(new UsageDescriptor(os + " screen scale " + scale, 1));
+  }
+
+  @NotNull
+  @Override
+  public GroupDescriptor getGroupId() {
+    return GroupDescriptor.create("user.jdk");
+  }
+}
index 21111bd2504ea99e65fdc5ac1304724248fa271c..edec3ae37125d587d898eff7b4d607461753c120 100644 (file)
@@ -424,12 +424,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
 
   @Override
   public void initToolWindow(@NotNull ToolWindowEP bean) {
-    JLabel label = new JLabel("Initializing...", SwingConstants.CENTER);
-    label.setOpaque(true);
-    final Color treeBg = UIManager.getColor("Tree.background");
-    label.setBackground(ColorUtil.toAlpha(treeBg, 180));
-    final Color treeFg = UIUtil.getTreeForeground();
-    label.setForeground(ColorUtil.toAlpha(treeFg, 180));
+    WindowInfoImpl before = myLayout.getInfo(bean.id, false);
+    boolean visible = before != null && before.isVisible();
+    JLabel label = createInitializingLabel();
     ToolWindowAnchor toolWindowAnchor = ToolWindowAnchor.fromText(bean.anchor);
     final ToolWindowFactory factory = bean.getToolWindowFactory();
     final ToolWindowImpl toolWindow =
@@ -461,7 +458,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
       toolWindow.ensureContentInitialized();
       activation.setDone();
     };
-    if (ApplicationManager.getApplication().isUnitTestMode()) {
+    if (visible || ApplicationManager.getApplication().isUnitTestMode()) {
       runnable.run();
     }
     else {
@@ -469,6 +466,17 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
     }
   }
 
+  @NotNull
+  private static JLabel createInitializingLabel() {
+    JLabel label = new JLabel("Initializing...", SwingConstants.CENTER);
+    label.setOpaque(true);
+    final Color treeBg = UIManager.getColor("Tree.background");
+    label.setBackground(ColorUtil.toAlpha(treeBg, 180));
+    final Color treeFg = UIUtil.getTreeForeground();
+    label.setForeground(ColorUtil.toAlpha(treeFg, 180));
+    return label;
+  }
+
   @Override
   public void projectClosed() {
     final String[] ids = getToolWindowIds();
index 4afe9bdb16d75fa1da1d13c278b8fb1cc3ce8739..79b887ef5bf183a9dfd9f500f6d77d337307b283 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 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,10 @@ public class ComboboxEditorTextField extends EditorTextField {
     // TODO:
     if (UIUtil.isUnderDarcula() || UIUtil.isUnderIntelliJLaF() || (SystemInfo.isMac && UIUtil.isUnderAquaLookAndFeel())) {
       IdeFocusManager.getInstance(getProject()).doWhenFocusSettlesDown(() -> {
-        final Container parent1 = getParent();
-        if (parent1 != null) parent1.repaint();
+        JComboBox comboBox = UIUtil.getParentOfType(JComboBox.class, this);
+        if (comboBox != null) {
+          comboBox.repaint();
+        }
       });
     }
   }
index 042e343e10c8adc3453293b332898db90f67aeb0..632eedaa068793f1ee349926879c3d70726b6438 100644 (file)
@@ -427,6 +427,9 @@ title.popup.new.element.same.place=New in This Directory
 command.go.to.next.split=Go to next split
 message.occurrence.N.of.M=Occurrence {0} of {1}
 error.dir.contains.no.project=''{0}'' does not contain a project
+message.open.file.is.project={0} is a project file.\nWould you like to open this project?
+message.open.file.is.project.open.as.project=Open as &Project
+message.open.file.is.project.open.as.file=Open as &File
 error.files.of.this.type.cannot.be.opened=Files of this type cannot be opened in {0}
 title.cannot.open.file=Cannot Open File
 title.cannot.open.project=Cannot Open Project
index 60eb886c5d4565502ebed107301cdb885062b3cd..071385c6b13587466a913158f14190faf01e3f86 100644 (file)
     <statistics.usagesCollector implementation="com.intellij.internal.statistic.UiInfoUsageCollector"/>
     <statistics.usagesCollector implementation="com.intellij.internal.statistic.JdkInfoUsageCollector"/>
     <statistics.usagesCollector implementation="com.intellij.internal.statistic.BuildNumberUsageCollector"/>
+    <statistics.usagesCollector implementation="com.intellij.internal.statistic.ScaleInfoUsageCollector"/>
 
     <applicationConfigurable parentId="preferences.general" instance="com.intellij.internal.statistic.configurable.StatisticsConfigurable" id="usage.statistics"
                              displayName="Usage Statistics"/>
index f08475ce3d90e9c5a81218bb2edb296b78255e3c..8cab38c39fb6ee0fe8f398b967339063a91d3ef9 100644 (file)
@@ -44,6 +44,10 @@ public abstract class NotNullLazyValue<T> {
     return result;
   }
 
+  public boolean isComputed() {
+    return myValue != null;
+  }
+
   @NotNull
   public static <T> NotNullLazyValue<T> createConstantValue(@NotNull final T value) {
     return new NotNullLazyValue<T>() {
diff --git a/platform/util/src/com/intellij/util/ui/HTMLEditorKitProvider.java b/platform/util/src/com/intellij/util/ui/HTMLEditorKitProvider.java
new file mode 100644 (file)
index 0000000..dc117df
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2000-2016 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 com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.util.ui.accessibility.ScreenReader;
+import org.jetbrains.annotations.NonNls;
+
+import javax.swing.*;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.StyleSheet;
+import java.awt.*;
+
+import static com.intellij.util.ui.UIUtil.getLabelFont;
+import static com.intellij.util.ui.UIUtil.isUnderDarcula;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class HTMLEditorKitProvider {
+  private static final Logger LOG = Logger.getInstance(HTMLEditorKitProvider.class);
+  private static final StyleSheet DEFAULT_HTML_KIT_CSS;
+
+  static {
+    blockATKWrapper();
+    // save the default JRE CSS and ..
+    HTMLEditorKit kit = new HTMLEditorKit();
+    DEFAULT_HTML_KIT_CSS = kit.getStyleSheet();
+    // .. erase global ref to this CSS so no one can alter it
+    kit.setStyleSheet(null);
+  }
+
+  private static void blockATKWrapper() {
+    /*
+     * The method should be called before java.awt.Toolkit.initAssistiveTechnologies()
+     * which is called from Toolkit.getDefaultToolkit().
+     */
+    if (!(SystemInfo.isLinux && Registry.is("linux.jdk.accessibility.atkwrapper.block"))) return;
+
+    if (ScreenReader.isEnabled(ScreenReader.ATK_WRAPPER)) {
+      // Replace AtkWrapper with a dummy Object. It'll be instantiated & GC'ed right away, a NOP.
+      System.setProperty("javax.accessibility.assistive_technologies", "java.lang.Object");
+      LOG.info(ScreenReader.ATK_WRAPPER + " is blocked, see IDEA-149219");
+    }
+  }
+
+  public static HTMLEditorKit getHTMLEditorKit(boolean noGapsBetweenParagraphs) {
+    Font font = getLabelFont();
+    @NonNls String family = !SystemInfo.isWindows && font != null ? font.getFamily() : "Tahoma";
+    int size = font != null ? font.getSize() : JBUI.scale(11);
+
+    String customCss = String.format("body, div, p { font-family: %s; font-size: %s; }", family, size);
+    if (noGapsBetweenParagraphs) {
+      customCss += " p { margin-top: 0; }";
+    }
+
+    final StyleSheet style = new StyleSheet();
+    style.addStyleSheet(isUnderDarcula() ? (StyleSheet)UIManager.getDefaults().get("StyledEditorKit.JBDefaultStyle") : DEFAULT_HTML_KIT_CSS);
+    style.addRule(customCss);
+
+    return new HTMLEditorKit() {
+      @Override
+      public StyleSheet getStyleSheet() {
+        return style;
+      }
+    };
+  }
+}
index 5a95162f3aa23d3e3791eb1f6936609224c52d00..e14f67b8289c267375bfcd280873656db8773c10 100644 (file)
@@ -37,23 +37,24 @@ import java.awt.*;
 public class JBUI {
   private static final Logger LOG = Logger.getInstance("#com.intellij.util.ui.JBUI");
 
-  private static float scaleFactor = 1.0f;
+  /**
+   * A default system scale factor.
+   */
+  public static final float SYSTEM_DEF_SCALE = getSystemDefScale();
+
+  private static float scaleFactor;
 
   static {
-    calculateScaleFactor();
+    setScaleFactor(SYSTEM_DEF_SCALE);
   }
 
-  private static void calculateScaleFactor() {
+  private static float getSystemDefScale() {
     if (SystemInfo.isMac) {
-      LOG.info("UI scale factor: 1.0");
-      scaleFactor = 1.0f;
-      return;
+      return 1.0f;
     }
 
     if (SystemProperties.has("hidpi") && !SystemProperties.is("hidpi")) {
-      LOG.info("UI scale factor: 1.0");
-      scaleFactor = 1.0f;
-      return;
+      return 1.0f;
     }
 
     UIUtil.initSystemFontData();
@@ -65,11 +66,13 @@ public class JBUI {
     } else {
       size = Fonts.label().getSize();
     }
-    setScaleFactor(size/UIUtil.DEF_SYSTEM_FONT_SIZE);
+    return size / UIUtil.DEF_SYSTEM_FONT_SIZE;
   }
 
   public static void setScaleFactor(float scale) {
     if (SystemProperties.has("hidpi") && !SystemProperties.is("hidpi")) {
+      scaleFactor = 1.0f;
+      LOG.info("UI scale factor: 1.0");
       return;
     }
 
index fad7a812e93c2ef24c34006359d02b8f006a0af0..a518786d789c2abc890f3459c6cfb176e0b6b2f5 100644 (file)
@@ -30,7 +30,6 @@ import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.JBIterable;
 import com.intellij.util.containers.JBTreeTraverser;
 import com.intellij.util.containers.WeakHashMap;
-import com.intellij.util.ui.accessibility.ScreenReader;
 import org.intellij.lang.annotations.Language;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -93,31 +92,6 @@ public class UIUtil {
 
   public static final String BORDER_LINE = "<hr size=1 noshade>";
 
-  private static final StyleSheet DEFAULT_HTML_KIT_CSS;
-
-  static {
-    blockATKWrapper();
-    // save the default JRE CSS and ..
-    HTMLEditorKit kit = new HTMLEditorKit();
-    DEFAULT_HTML_KIT_CSS = kit.getStyleSheet();
-    // .. erase global ref to this CSS so no one can alter it
-    kit.setStyleSheet(null);
-  }
-
-  private static void blockATKWrapper() {
-    /*
-     * The method should be called before java.awt.Toolkit.initAssistiveTechnologies()
-     * which is called from Toolkit.getDefaultToolkit().
-     */
-    if (!(SystemInfo.isLinux && Registry.is("linux.jdk.accessibility.atkwrapper.block"))) return;
-
-    if (ScreenReader.isEnabled(ScreenReader.ATK_WRAPPER)) {
-      // Replace AtkWrapper with a dummy Object. It'll be instantiated & GC'ed right away, a NOP.
-      System.setProperty("javax.accessibility.assistive_technologies", "java.lang.Object");
-      LOG.info(ScreenReader.ATK_WRAPPER + " is blocked, see IDEA-149219");
-    }
-  }
-
   public static int getMultiClickInterval() {
     Object property = Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
     if (property instanceof Integer) {
@@ -2335,25 +2309,7 @@ public class UIUtil {
   }
 
   public static HTMLEditorKit getHTMLEditorKit(boolean noGapsBetweenParagraphs) {
-    Font font = getLabelFont();
-    @NonNls String family = !SystemInfo.isWindows && font != null ? font.getFamily() : "Tahoma";
-    int size = font != null ? font.getSize() : JBUI.scale(11);
-
-    String customCss = String.format("body, div, p { font-family: %s; font-size: %s; }", family, size);
-    if (noGapsBetweenParagraphs) {
-      customCss += " p { margin-top: 0; }";
-    }
-
-    final StyleSheet style = new StyleSheet();
-    style.addStyleSheet(isUnderDarcula() ? (StyleSheet)UIManager.getDefaults().get("StyledEditorKit.JBDefaultStyle") : DEFAULT_HTML_KIT_CSS);
-    style.addRule(customCss);
-
-    return new HTMLEditorKit() {
-      @Override
-      public StyleSheet getStyleSheet() {
-        return style;
-      }
-    };
+    return HTMLEditorKitProvider.getHTMLEditorKit(noGapsBetweenParagraphs);
   }
 
   public static void removeScrollBorder(final Component c) {
index ec4409176f408cf9dadc27fdb1f94a480576ee45..e011b1b328db1cf95081f4979624aa1d4e3b91dd 100644 (file)
@@ -34,9 +34,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.SimpleToolWindowPanel;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Factory;
-import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.*;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.ProjectLevelVcsManager;
 import com.intellij.openapi.vcs.VcsBundle;
@@ -97,7 +95,13 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
   private JBSplitter mySplitter;
 
   private boolean myDetailsOn;
-  @NotNull private final MyChangeProcessor myDiffDetails;
+  @NotNull private final NotNullLazyValue<MyChangeProcessor> myDiffDetails = new NotNullLazyValue<MyChangeProcessor>() {
+    @NotNull
+    @Override
+    protected MyChangeProcessor compute() {
+      return new MyChangeProcessor(myProject);
+    }
+  };
 
   @NotNull private final TreeSelectionListener myTsl;
   private Content myContent;
@@ -112,7 +116,6 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
     myContentManager = contentManager;
     myView = new ChangesListView(project);
     myRepaintAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, project);
-    myDiffDetails = new MyChangeProcessor(myProject);
     myTsl = new TreeSelectionListener() {
       @Override
       public void valueChanged(TreeSelectionEvent e) {
@@ -167,7 +170,6 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
   }
 
   public void projectClosed() {
-    Disposer.dispose(myDiffDetails);
     myView.removeTreeSelectionListener(myTsl);
     myDisposed = true;
     myRepaintAlarm.cancelAllRequests();
@@ -239,17 +241,19 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
 
   private void changeDetails() {
     if (!myDetailsOn) {
-      myDiffDetails.clear();
+      if (myDiffDetails.isComputed()) {
+        myDiffDetails.getValue().clear();
 
-      if (mySplitter.getSecondComponent() != null) {
-        setChangeDetailsPanel(null);
+        if (mySplitter.getSecondComponent() != null) {
+          setChangeDetailsPanel(null);
+        }
       }
     }
     else {
-      myDiffDetails.refresh();
+      myDiffDetails.getValue().refresh();
 
       if (mySplitter.getSecondComponent() == null) {
-        setChangeDetailsPanel(myDiffDetails.getComponent());
+        setChangeDetailsPanel(myDiffDetails.getValue().getComponent());
       }
     }
   }
@@ -528,6 +532,7 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
   private class MyChangeProcessor extends CacheChangeProcessor {
     public MyChangeProcessor(@NotNull Project project) {
       super(project, DiffPlaces.CHANGES_VIEW);
+      Disposer.register(project, this);
     }
 
     @Override
index 5b8982ea6efb26a8ce3480cba32404e49daf3ce1..5d36ba5952f8cdda8b240dc7d0e5ca210614ba33 100644 (file)
@@ -38,6 +38,7 @@ import com.intellij.reference.SoftReference;
 import com.intellij.ui.ClickListener;
 import com.intellij.ui.LayeredIcon;
 import com.intellij.util.ui.JBUI;
+import com.intellij.util.ui.components.BorderLayoutPanel;
 import com.intellij.xdebugger.XDebuggerBundle;
 import com.intellij.xdebugger.XExpression;
 import com.intellij.xdebugger.XSourcePosition;
@@ -139,22 +140,33 @@ public abstract class XDebuggerEditorBase {
   }
 
   protected JPanel decorate(JComponent component, boolean multiline, boolean showEditor) {
-    JPanel panel = JBUI.Panels.simplePanel();
+    BorderLayoutPanel panel = JBUI.Panels.simplePanel();
 
     JPanel factoryPanel = JBUI.Panels.simplePanel();
     factoryPanel.add(myChooseFactory, multiline ? BorderLayout.NORTH : BorderLayout.CENTER);
     panel.add(factoryPanel, BorderLayout.WEST);
 
     if (!multiline && showEditor) {
-      ComponentWithBrowseButton<JComponent> componentWithButton =
-        new ComponentWithBrowseButton<>(component, e -> showCodeFragmentEditor(component, this));
-      componentWithButton.setButtonIcon(AllIcons.Actions.ShowViewer);
-      componentWithButton.getButton().setDisabledIcon(IconLoader.getDisabledIcon(AllIcons.Actions.ShowViewer));
-      panel.add(componentWithButton, BorderLayout.CENTER);
-    } else {
-      panel.add(component, BorderLayout.CENTER);
+      component = addMultilineButton(component);
     }
 
+    panel.addToCenter(component);
+
+    return panel;
+  }
+
+  protected JPanel addMultilineButton(JComponent component) {
+    ComponentWithBrowseButton<JComponent> componentWithButton =
+      new ComponentWithBrowseButton<>(component, e -> showCodeFragmentEditor(component, this));
+    componentWithButton.setButtonIcon(AllIcons.Actions.ShowViewer);
+    componentWithButton.getButton().setDisabledIcon(IconLoader.getDisabledIcon(AllIcons.Actions.ShowViewer));
+    return componentWithButton;
+  }
+
+  protected JComponent addChooser(JComponent component) {
+    BorderLayoutPanel panel = JBUI.Panels.simplePanel(component);
+    panel.setBackground(component.getBackground());
+    panel.addToRight(myChooseFactory);
     return panel;
   }
 
@@ -345,7 +357,10 @@ public abstract class XDebuggerEditorBase {
       protected void doOKAction() {
         super.doOKAction();
         baseEditor.setExpression(inputComponent.getInputEditor().getExpression());
-        IdeFocusManager.findInstance().requestFocus(baseEditor.getEditorComponent(), false);
+        JComponent component = baseEditor.getPreferredFocusedComponent();
+        if (component != null) {
+          IdeFocusManager.findInstance().requestFocus(component, false);
+        }
       }
 
       @Nullable
index 0bf83c4d51bde97001dffc31d08f3d3095d1379a..d5069dbf36fb74657390a4d56e5255ed0a832640 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.ComboBox;
 import com.intellij.ui.EditorComboBoxEditor;
 import com.intellij.ui.EditorComboBoxRenderer;
+import com.intellij.ui.EditorTextField;
 import com.intellij.util.ui.UIUtil;
 import com.intellij.xdebugger.XExpression;
 import com.intellij.xdebugger.XSourcePosition;
@@ -35,6 +36,7 @@ import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
+import java.awt.event.ActionListener;
 
 /**
  * @author nik
@@ -42,7 +44,7 @@ import java.awt.*;
 public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
   private final JComponent myComponent;
   private final ComboBox<XExpression> myComboBox;
-  private EditorComboBoxEditor myEditor;
+  private XDebuggerComboBoxEditor myEditor;
   private XExpression myExpression;
 
   public XDebuggerExpressionComboBox(@NotNull Project project, @NotNull XDebuggerEditorsProvider debuggerEditorsProvider, @Nullable @NonNls String historyId,
@@ -56,7 +58,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
     myComboBox.setMinimumSize(minimumSize);
     initEditor();
     fillComboBox();
-    myComponent = decorate(myComboBox, false, showEditor);
+    myComponent = showEditor ? addMultilineButton(myComboBox) : myComboBox;
   }
 
   public ComboBox getComboBox() {
@@ -70,11 +72,11 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
 
   @Nullable
   public Editor getEditor() {
-    return myEditor.getEditor();
+    return myEditor.getEditorTextField().getEditor();
   }
 
   public JComponent getEditorComponent() {
-    return myEditor.getEditorComponent();
+    return myEditor.getEditorTextField();
   }
 
   public void setEnabled(boolean enable) {
@@ -92,23 +94,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
   }
 
   private void initEditor() {
-    myEditor = new EditorComboBoxEditor(getProject(), getEditorsProvider().getFileType()) {
-      @Override
-      public void setItem(Object anObject) {
-        if (anObject == null) {
-          anObject = XExpressionImpl.EMPTY_EXPRESSION;
-        }
-        XExpression expression = (XExpression)anObject;
-        getEditorComponent().setNewDocumentAndFileType(getFileType(expression), createDocument(expression));
-      }
-
-      @Override
-      protected void onEditorCreate(EditorEx editor) {
-        editor.putUserData(DebuggerCopyPastePreprocessor.REMOVE_NEWLINES_ON_PASTE, true);
-        editor.getColorsScheme().setEditorFontSize(myComboBox.getFont().getSize());
-      }
-    };
-    myEditor.getEditorComponent().setFontInheritedFromLAF(false);
+    myEditor = new XDebuggerComboBoxEditor();
     myComboBox.setEditor(myEditor);
     //myEditor.setItem(myExpression);
     myComboBox.setRenderer(new EditorComboBoxRenderer(myEditor));
@@ -144,20 +130,76 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
 
   @Override
   public XExpression getExpression() {
-    Object document = myEditor.getItem();
-    if (document instanceof Document) { // sometimes null on Mac
-      return getEditorsProvider().createExpression(getProject(), (Document)document, myExpression.getLanguage(), myExpression.getMode());
-    }
-    return myExpression;
+    XExpression item = myEditor.getItem();
+    return item != null ? item : myExpression;
   }
 
   @Override
   public JComponent getPreferredFocusedComponent() {
-    return (JComponent)myComboBox.getEditor().getEditorComponent();
+    return myEditor.getEditorTextField();
   }
 
   @Override
   public void selectAll() {
     myComboBox.getEditor().selectAll();
   }
+
+  private class XDebuggerComboBoxEditor implements ComboBoxEditor {
+    private final JComponent myPanel;
+    private final EditorComboBoxEditor myDelegate;
+
+    public XDebuggerComboBoxEditor() {
+      myDelegate = new EditorComboBoxEditor(getProject(), getEditorsProvider().getFileType()) {
+        @Override
+        protected void onEditorCreate(EditorEx editor) {
+          editor.putUserData(DebuggerCopyPastePreprocessor.REMOVE_NEWLINES_ON_PASTE, true);
+          editor.getColorsScheme().setEditorFontSize(myComboBox.getFont().getSize());
+        }
+      };
+      myDelegate.getEditorComponent().setFontInheritedFromLAF(false);
+      myPanel = addChooser(myDelegate.getEditorComponent());
+    }
+
+    public EditorTextField getEditorTextField() {
+      return myDelegate.getEditorComponent();
+    }
+
+    @Override
+    public JComponent getEditorComponent() {
+      return myPanel;
+    }
+
+    @Override
+    public void setItem(Object anObject) {
+      if (anObject == null) {
+        anObject = XExpressionImpl.EMPTY_EXPRESSION;
+      }
+      XExpression expression = (XExpression)anObject;
+      myDelegate.getEditorComponent().setNewDocumentAndFileType(getFileType(expression), createDocument(expression));
+    }
+
+    @Override
+    public XExpression getItem() {
+      Object document = myDelegate.getItem();
+      if (document instanceof Document) { // sometimes null on Mac
+        return getEditorsProvider().createExpression(getProject(), (Document)document, myExpression.getLanguage(), myExpression.getMode());
+      }
+      return null;
+    }
+
+    @Override
+    public void selectAll() {
+      myDelegate.selectAll();
+    }
+
+    @Override
+    public void addActionListener(ActionListener l) {
+      myDelegate.addActionListener(l);
+    }
+
+    @Override
+    public void removeActionListener(ActionListener l) {
+      myDelegate.removeActionListener(l);
+    }
+  }
 }
index 038910bdeb2e55d8088b730997d3f85955a6a43c..0fc445f3436e9adb79dc41fa63cfa4900e31b9b6 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.ui.AppUIUtil;
 import com.intellij.ui.SimpleColoredComponent;
+import com.intellij.util.ui.JBUI;
 import com.intellij.xdebugger.frame.XValueModifier;
 import com.intellij.xdebugger.frame.presentation.XValuePresentation;
 import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
@@ -28,6 +29,7 @@ import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
 import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
 import com.intellij.xdebugger.impl.ui.tree.nodes.XValuePresentationUtil;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
@@ -39,24 +41,36 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor {
   private final JPanel myEditorPanel;
   private final XValueModifier myModifier;
   private final XValueNodeImpl myValueNode;
+  private final int myNameOffset;
 
   private SetValueInplaceEditor(final XValueNodeImpl node, @NotNull final String nodeName) {
     super(node, "setValue");
     myValueNode = node;
     myModifier = myValueNode.getValueContainer().getModifier();
 
-    myEditorPanel = new JPanel();
-    myEditorPanel.setLayout(new BorderLayout(0, 0));
     SimpleColoredComponent nameLabel = new SimpleColoredComponent();
+    nameLabel.getIpad().right = 0;
+    nameLabel.getIpad().left = 0;
     nameLabel.setIcon(myNode.getIcon());
     nameLabel.append(nodeName, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
     XValuePresentation presentation = node.getValuePresentation();
     if (presentation != null) {
       XValuePresentationUtil.appendSeparator(nameLabel, presentation.getSeparator());
     }
-    myEditorPanel.add(nameLabel, BorderLayout.WEST);
+    myNameOffset = nameLabel.getPreferredSize().width;
+    myEditorPanel = JBUI.Panels.simplePanel(myExpressionEditor.getComponent());
+  }
 
-    myEditorPanel.add(myExpressionEditor.getComponent(), BorderLayout.CENTER);
+  @Nullable
+  @Override
+  protected Rectangle getEditorBounds() {
+    Rectangle bounds = super.getEditorBounds();
+    if (bounds == null) {
+      return null;
+    }
+    bounds.x += myNameOffset;
+    bounds.width -= myNameOffset;
+    return bounds;
   }
 
   public static void show(final XValueNodeImpl node, @NotNull final String nodeName) {
index d60f5099d46daade35a1a754faa025088e6c2b8c..a1c0a881de41f942031257af25575d0d6fcf1aae 100644 (file)
@@ -97,10 +97,8 @@ public abstract class TreeInplaceEditor implements AWTEventListener {
   protected abstract Project getProject();
 
   private static void setInplaceEditorBounds(JComponent component, int x, int y, int width, int height) {
-    int preferredHeight = component.getPreferredSize().height;
-    int h = Math.max(height, preferredHeight);
-    int delta = Math.max(0, h - height) / 2;
-    component.setBounds(x, y - delta, width, Math.max(height, preferredHeight));
+    int h = Math.max(height, component.getPreferredSize().height);
+    component.setBounds(x, y - (h - height) / 2, width, h);
   }
 
   public final void show() {
@@ -271,7 +269,7 @@ public abstract class TreeInplaceEditor implements AWTEventListener {
   }
 
   @Nullable
-  private Rectangle getEditorBounds() {
+  protected Rectangle getEditorBounds() {
     final JTree tree = getTree();
     Rectangle bounds = tree.getVisibleRect();
     Rectangle nodeBounds = tree.getPathBounds(getNodePath());
index 380cd3aeef499ea6779b851db126df73ceebec06..d1c10b5ecb8f5259920b34d0c88afa4de6780665 100644 (file)
@@ -20,7 +20,7 @@ except ImportError:
     IS_JYTHON = False
     from _pydev_bundle import _pydev_imports_tipper
 
-from _pydevd_bundle import pydevd_vars
+from _pydevd_bundle import pydevd_xml
 dir2 = _pydev_imports_tipper.generate_imports_tip_for_module
 
 
@@ -176,8 +176,8 @@ def generate_completions_as_xml(frame, act_tok):
         #list(tuple(name, descr, parameters, type))
         completions = completer.complete(act_tok)
 
-    valid_xml = pydevd_vars.make_valid_xml_value
-    quote = pydevd_vars.quote
+    valid_xml = pydevd_xml.make_valid_xml_value
+    quote = pydevd_xml.quote
 
     msg = ["<xml>"]
 
index 7556adb193f217035bebfc063abcc9c217759f5e..f1253aa488653c7b8ce903e4e255e058cf28dce4 100644 (file)
@@ -1,6 +1,6 @@
 from _pydevd_bundle.pydevd_constants import dict_contains
 import sys
-from _pydevd_bundle import pydevd_vars
+from _pydevd_bundle import pydevd_xml
 from os.path import basename
 import traceback
 try:
@@ -72,7 +72,7 @@ def get_referrer_info(searched_obj):
                 ret = ['<xml>\n']
 
                 ret.append('<for>\n')
-                ret.append(pydevd_vars.var_to_xml(
+                ret.append(pydevd_xml.var_to_xml(
                     searched_obj,
                     'Skipping getting referrers for None',
                     additionalInXml=' id="%s"' % (id(searched_obj),)))
@@ -93,7 +93,7 @@ def get_referrer_info(searched_obj):
                 ret = ['<xml>\n']
 
                 ret.append('<for>\n')
-                ret.append(pydevd_vars.var_to_xml(
+                ret.append(pydevd_xml.var_to_xml(
                     searched_obj,
                     'Exception raised while trying to get_referrers.',
                     additionalInXml=' id="%s"' % (id(searched_obj),)))
@@ -123,7 +123,7 @@ def get_referrer_info(searched_obj):
             if DEBUG:
                 sys.stderr.write('Searching Referrers of obj with id="%s"\n' % (obj_id,))
 
-            ret.append(pydevd_vars.var_to_xml(
+            ret.append(pydevd_xml.var_to_xml(
                 searched_obj,
                 'Referrers of obj with id="%s"' % (obj_id,)))
             ret.append('</for>\n')
@@ -200,9 +200,9 @@ def get_referrer_info(searched_obj):
                 if found_as:
                     if not isinstance(found_as, str):
                         found_as = str(found_as)
-                    found_as = ' found_as="%s"' % (pydevd_vars.make_valid_xml_value(found_as),)
+                    found_as = ' found_as="%s"' % (pydevd_xml.make_valid_xml_value(found_as),)
 
-                ret.append(pydevd_vars.var_to_xml(
+                ret.append(pydevd_xml.var_to_xml(
                     r,
                     representation,
                     additionalInXml=' id="%s"%s' % (r_id, found_as)))
@@ -225,7 +225,7 @@ def get_referrer_info(searched_obj):
         ret = ['<xml>\n']
 
         ret.append('<for>\n')
-        ret.append(pydevd_vars.var_to_xml(
+        ret.append(pydevd_xml.var_to_xml(
             searched_obj,
             'Error getting referrers for:',
             additionalInXml=' id="%s"' % (id(searched_obj),)))
index 27fa4f6b8e5d387806a88377c835c98e9a0ad16c..67859a226e7aec9a70b4cbd18f1b49fefbad1f0d 100644 (file)
@@ -25,6 +25,7 @@ class TestCase(unittest.TestCase):
                 'sys.path.append(r\'%s\'); '
                 'import pydevd; pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, '
                     'trace_only_current_thread=False, patch_multiprocessing=True); '
+                    'sys.original_argv = []; '
                     'connect("127.0.0.1")' % pydev_src_dir,
                 pydev_monkey.patch_arg_str_win(check)
             )
@@ -48,6 +49,7 @@ class TestCase(unittest.TestCase):
                 (
                     'import sys; sys.path.append(r\'%s\'); import pydevd; '
                     'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True); '
+                    'sys.original_argv = []; '
                     'connect(\\"127.0.0.1\\")'
                 ) % pydev_src_dir
             ])
index d0d1e75f561c9301136e53f5c2bd00961f8fae48..49d229678ec3b3b6d9929a9e655de7452dd10361 100644 (file)
@@ -3,14 +3,14 @@ from time import sleep
 
 
 def fun1(n):
-    for i in range(1000):
+    while True:
         sleep(0.01)
     print("finished fun1()", n)
 
 
 def fun2(m):
     sleep(2)
-    for i in range(1000):
+    while True:
         sleep(0.01) #breakpoint
     print("finished fun2()", m)
 
index 665a3f1b21af8fe454431a093488b52b2509b8ef..da9b42c6a631203bafdc103b3e28f488f567fa17 100644 (file)
@@ -992,7 +992,7 @@ public class PythonDebuggerTest extends PyEnvTestCase {
 
       @Override
       public void testing() throws Exception {
-        waitForPause();
+        waitForAllThreadsPause();
         eval("m").hasValue("42");
         assertNull(getRunningThread());
         resume();
@@ -1078,14 +1078,13 @@ public class PythonDebuggerTest extends PyEnvTestCase {
     });
   }
 
-  //TODO: fix me as I don't work properly sometimes (something connected with process termination on agent)
   @Staging
   @Test
   public void testResume() throws Exception {
-    runPythonTest(new PyDebuggerTask("/debug", "Test_Resume.py") {
+    runPythonTest(new PyDebuggerTask("/debug", "test_resume.py") {
       @Override
       public void before() throws Exception {
-        toggleBreakpoint(getScriptName(), 2);
+        toggleBreakpoint(getScriptName(), 1);
       }
 
       @Override
index 6065fdd87a0269c962c26f50667261007521c8ac..ba45bee3466e732bf2211f12131c50b909b61733 100644 (file)
@@ -39,6 +39,7 @@ import org.jetbrains.annotations.Nullable;
 import org.junit.Assert;
 
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.net.ServerSocket;
 import java.util.concurrent.Semaphore;
 
@@ -167,7 +168,7 @@ public class PyDebuggerTask extends PyBaseDebuggerTask {
     myPausedSemaphore = new Semaphore(0);
     
 
-    mySession.addSessionListener(new XDebugSessionAdapter() {
+    mySession.addSessionListener(new XDebugSessionListener() {
       @Override
       public void sessionPaused() {
         if (myPausedSemaphore != null) {
@@ -195,6 +196,21 @@ public class PyDebuggerTask extends PyBaseDebuggerTask {
     myMultiprocessDebug = multiprocessDebug;
   }
 
+  protected void waitForAllThreadsPause() throws InterruptedException, InvocationTargetException {
+    waitForPause();
+    Assert.assertTrue(String.format("All threads didn't stop within timeout\n" +
+                                    "Output: %s", output()), waitForAllThreads());
+    XDebuggerTestUtil.waitForSwing();
+  }
+
+  protected boolean waitForAllThreads() throws InterruptedException {
+    long until = System.currentTimeMillis() + NORMAL_TIMEOUT;
+    while (System.currentTimeMillis() < until && getRunningThread() != null) {
+      Thread.sleep(1000);
+    }
+    return getRunningThread() == null;
+  }
+
   @Override
   protected void disposeDebugProcess() throws InterruptedException {
     if (myDebugProcess != null) {