From a1b76c89d1b2201c5685ea395bd2ec66356298c0 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Tue, 29 Nov 2011 14:29:58 +0100 Subject: [PATCH 01/44] IDEA-77787 XSLT debug: Saxon9: sequence expressions are evaluated to the first element --- .../engine/local/saxon9/Saxon9StyleFrame.java | 72 +++++++++++++++---- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java b/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java index dc9df67055c6..54b24dabb2a9 100644 --- a/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java +++ b/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java @@ -22,10 +22,7 @@ import net.sf.saxon.expr.StackFrame; import net.sf.saxon.expr.XPathContext; import net.sf.saxon.expr.instruct.GlobalVariable; import net.sf.saxon.expr.instruct.SlotManager; -import net.sf.saxon.om.Item; -import net.sf.saxon.om.NodeInfo; -import net.sf.saxon.om.StructuredQName; -import net.sf.saxon.om.ValueRepresentation; +import net.sf.saxon.om.*; import net.sf.saxon.style.StyleElement; import net.sf.saxon.trans.XPathException; import net.sf.saxon.type.ItemType; @@ -65,22 +62,22 @@ class Saxon9StyleFrame extends AbstractSaxon9Frame extends AbstractSaxon9Frame Date: Tue, 29 Nov 2011 14:33:54 +0100 Subject: [PATCH 02/44] IDEA-77800 XSLT debug: Run to Cursor causes IOOBE at SegmentArray.getSegmentStart() --- .../plugins/xsltDebugger/impl/XsltBreakpointHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java index af00a57d6461..e5e69d9d7ca3 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java @@ -164,7 +164,7 @@ public class XsltBreakpointHandler extends XBreakpointHandler position.getLine()) { + if (document != null && document.getLineCount() > position.getLine() && position.getLine() >= 0) { offset = document.getLineStartOffset(position.getLine()); } if (offset < 0) { From a55d2720c5c48342d0fb116c6f83964dc7e98b29 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Tue, 29 Nov 2011 14:43:32 +0100 Subject: [PATCH 03/44] XSLT debug: Run to Cursor broken --- .../xsltDebugger/XsltDebuggerSession.java | 41 ++----------------- .../xsltDebugger/impl/XsltDebugProcess.java | 4 +- 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerSession.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerSession.java index 97ec8374b013..1c20129a774f 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerSession.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerSession.java @@ -26,7 +26,6 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.pom.Navigatable; import com.intellij.psi.PsiFile; import com.intellij.util.EventDispatcher; import com.intellij.xdebugger.XSourcePosition; @@ -153,14 +152,14 @@ public class XsltDebuggerSession implements Disposable { myClient.stepInto(); } - public boolean canRunTo(final PsiFile file, final int offset) { - return XsltBreakpointHandler.getActualLineNumber(myProject, new MyXSourcePosition(file, offset)) != -1; + public boolean canRunTo(final XSourcePosition position) { + return XsltBreakpointHandler.getActualLineNumber(myProject, position) != -1; } - public void runTo(final PsiFile file, final int offset) { + public void runTo(final PsiFile file, final XSourcePosition position) { assert myTempBreakpoint == null; - final int lineNumber = XsltBreakpointHandler.getActualLineNumber(myProject, new MyXSourcePosition(file, offset)); + final int lineNumber = XsltBreakpointHandler.getActualLineNumber(myProject, position); final String uri = XsltBreakpointHandler.getFileURL(file.getVirtualFile()); myTempBreakpoint = myClient.getBreakpointManager().setBreakpoint(uri, lineNumber); @@ -224,36 +223,4 @@ public class XsltDebuggerSession implements Disposable { void debuggerStopped(); } - - private static class MyXSourcePosition implements XSourcePosition { - private final PsiFile myFile; - private final int myOffset; - - public MyXSourcePosition(PsiFile file, int offset) { - myFile = file; - myOffset = offset; - } - - @Override - public int getLine() { - return -1; - } - - @Override - public int getOffset() { - return myOffset; - } - - @NotNull - @Override - public VirtualFile getFile() { - return myFile.getVirtualFile(); - } - - @NotNull - @Override - public Navigatable createNavigatable(@NotNull Project project) { - throw new UnsupportedOperationException(); - } - } } diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java index 498c28e93734..b9c2b97cc569 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java @@ -163,8 +163,8 @@ public class XsltDebugProcess extends XDebugProcess implements Disposable { public void runToPosition(@NotNull XSourcePosition position) { final PsiFile psiFile = PsiManager.getInstance(getSession().getProject()).findFile(position.getFile()); assert psiFile != null; - if (myDebuggerSession.canRunTo(psiFile, position.getOffset())) { - myDebuggerSession.runTo(psiFile, position.getOffset()); + if (myDebuggerSession.canRunTo(position)) { + myDebuggerSession.runTo(psiFile, position); } else { StatusBar.Info.set("Not a valid position in file '" + psiFile.getName() + "'", psiFile.getProject()); final Debugger c = myDebuggerSession.getClient(); From c52b1d847a9c0dff4990d395f92eafa580afcacf Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Tue, 29 Nov 2011 14:44:14 +0100 Subject: [PATCH 04/44] message extracted --- .../org/intellij/plugins/xsltDebugger/VMPausedException.java | 1 + .../intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java | 2 +- .../plugins/xsltDebugger/impl/XsltExecutionStack.java | 2 +- .../intellij/plugins/xsltDebugger/impl/XsltStackFrame.java | 4 +++- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/VMPausedException.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/VMPausedException.java index 90c6ed935d3a..8a1bd37a61d0 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/VMPausedException.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/VMPausedException.java @@ -20,4 +20,5 @@ package org.intellij.plugins.xsltDebugger; * Thrown by the EDTGuard when some method cannot be completed due to the target VM being paused. */ public class VMPausedException extends RuntimeException { + public static final String MESSAGE = "Target VM is not responding"; } diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java index b9c2b97cc569..29ab7418c8ce 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java @@ -145,7 +145,7 @@ public class XsltDebugProcess extends XDebugProcess implements Disposable { try { return myDebuggerSession.getClient().ping(); } catch (VMPausedException e) { - getSession().reportMessage("Target VM is not responding", MessageType.WARNING); + getSession().reportMessage(VMPausedException.MESSAGE, MessageType.WARNING); return false; } } diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltExecutionStack.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltExecutionStack.java index b8e2a8b302cf..3f57574e175c 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltExecutionStack.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltExecutionStack.java @@ -44,7 +44,7 @@ public class XsltExecutionStack extends XExecutionStack { } } } catch (VMPausedException e) { - container.errorOccurred("VM is paused"); + container.errorOccurred(VMPausedException.MESSAGE); } } } diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltStackFrame.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltStackFrame.java index 187a31c6373b..4867c1b25173 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltStackFrame.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltStackFrame.java @@ -97,7 +97,7 @@ public class XsltStackFrame extends XStackFrame { super.computeChildren(node); } } catch (VMPausedException e) { - node.setErrorMessage("Target VM is not responding"); + node.setErrorMessage(VMPausedException.MESSAGE); } } @@ -200,6 +200,8 @@ public class XsltStackFrame extends XStackFrame { try { final Value eval = myFrame.eval(expression); callback.evaluated(new MyValue(new ExpressionResult(eval))); + } catch (VMPausedException e) { + callback.errorOccurred(VMPausedException.MESSAGE); } catch (Debugger.EvaluationException e) { callback.errorOccurred(e.getMessage() != null ? e.getMessage() : e.toString()); } From 2a3bc7116c0488347f53af7aec3e0838a04df4d0 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Tue, 29 Nov 2011 15:22:56 +0100 Subject: [PATCH 05/44] IDEA-77787 XSLT debug: Saxon9: sequence expressions are evaluated to the first element --- .../xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java b/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java index 54b24dabb2a9..ff19095fb87a 100644 --- a/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java +++ b/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java @@ -184,7 +184,7 @@ class Saxon9StyleFrame extends AbstractSaxon9Frame Date: Tue, 29 Nov 2011 15:34:31 +0100 Subject: [PATCH 06/44] IDEA-77786: XSLT debug: on debugging 2.0 stylesheet highlighting in Evaluate Expression and Watches could follow 2.0 syntax --- .../xpath/xslt/run/XsltCommandLineState.java | 11 ++++-- plugins/xslt-debugger/src/META-INF/plugin.xml | 3 +- .../xsltDebugger/XsltBreakpointType.java | 35 ++++++++++++++++--- .../xsltDebugger/XsltDebuggerExtension.java | 18 +++++++--- .../xsltDebugger/XsltDebuggerRunner.java | 4 ++- .../impl/XsltBreakpointHandler.java | 4 +-- .../xsltDebugger/impl/XsltDebugProcess.java | 9 +++-- .../impl/XsltDebuggerEditorsProvider.java | 12 +++++-- 8 files changed, 75 insertions(+), 21 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/run/XsltCommandLineState.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/run/XsltCommandLineState.java index 7e9e88d549c9..f1994c65e9ca 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/run/XsltCommandLineState.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/run/XsltCommandLineState.java @@ -54,7 +54,7 @@ import java.util.List; import static org.intellij.lang.xpath.xslt.run.XsltRunConfiguration.isEmpty; -class XsltCommandLineState extends CommandLineState { +public class XsltCommandLineState extends CommandLineState { private static final Logger LOG = Logger.getInstance(XsltCommandLineState.class.getName()); public static final Key STATE = Key.create("STATE"); @@ -145,7 +145,8 @@ class XsltCommandLineState extends CommandLineState { assert descriptor != null; pluginPath = descriptor.getPath(); } else { - pluginPath = new File(System.getProperty("xslt.plugin.path")); + // -Dxslt.plugin.path=C:\work\java\intellij/ultimate\out\classes\production\xslt-rt + pluginPath = new File(System.getProperty("xslt.plugin.path")); } LOG.debug("Plugin Path = " + pluginPath.getAbsolutePath()); @@ -187,7 +188,11 @@ class XsltCommandLineState extends CommandLineState { return myPort; } - private class MyProcessAdapter extends ProcessAdapter { + public UserDataHolder getExtensionData() { + return myExtensionData; + } + + private class MyProcessAdapter extends ProcessAdapter { public void processTerminated(final ProcessEvent event) { diff --git a/plugins/xslt-debugger/src/META-INF/plugin.xml b/plugins/xslt-debugger/src/META-INF/plugin.xml index 2670f2b5e4bf..c02c972de3da 100644 --- a/plugins/xslt-debugger/src/META-INF/plugin.xml +++ b/plugins/xslt-debugger/src/META-INF/plugin.xml @@ -20,7 +20,8 @@ - + + diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltBreakpointType.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltBreakpointType.java index dbfb1b09581e..65fa36c0ee2b 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltBreakpointType.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltBreakpointType.java @@ -13,6 +13,7 @@ import com.intellij.xdebugger.breakpoints.XLineBreakpointType; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.ui.DebuggerIcons; import org.intellij.lang.xpath.xslt.XsltSupport; +import org.intellij.lang.xpath.xslt.impl.XsltChecker; import org.intellij.plugins.xsltDebugger.impl.XsltDebuggerEditorsProvider; import org.jetbrains.annotations.NotNull; @@ -23,12 +24,12 @@ import javax.swing.*; * User: sweinreuter * Date: 03.03.11 */ -public final class XsltBreakpointType extends XLineBreakpointType { +public abstract class XsltBreakpointType extends XLineBreakpointType { - private final XsltDebuggerEditorsProvider myMyEditorsProvider = new XsltDebuggerEditorsProvider(); + private final XsltDebuggerEditorsProvider myMyEditorsProvider = new XsltDebuggerEditorsProvider(getLanguageLevel()); - public XsltBreakpointType() { - super("xslt", "XSLT Breakpoints"); + protected XsltBreakpointType(final String id) { + super(id, "XSLT Breakpoints"); } @Override @@ -44,9 +45,11 @@ public final class XsltBreakpointType extends XLineBreakpointType VERSION = Key.create("VERSION"); private static final Key PORT = Key.create("PORT"); private static final Key MANIFEST = Key.create("MANIFEST"); @@ -133,6 +134,7 @@ public class XsltDebuggerExtension extends XsltRunnerExtension { assert descriptor != null; pluginPath = descriptor.getPath(); } else { + // -Dxslt-debugger.plugin.path=C:\work\java\intellij/ultimate\out\classes\production\xslt-debugger-engine pluginPath = new File(System.getProperty("xslt-debugger.plugin.path")); } @@ -192,12 +194,20 @@ public class XsltDebuggerExtension extends XsltRunnerExtension { parameters.getVMParametersList().defineProperty("xslt.transformer.type", "xalan"); } } + + final VirtualFile xsltFile = configuration.findXsltFile(); + final PsiManager psiManager = PsiManager.getInstance(configuration.getProject()); + final XsltChecker.LanguageLevel level; + if (xsltFile != null) { + level = XsltSupport.getXsltLanguageLevel(psiManager.findFile(xsltFile)); + } else { + level = XsltChecker.LanguageLevel.V1; + } + extensionData.putUserData(VERSION, level); + if (!parameters.getVMParametersList().hasProperty("xslt.transformer.type")) { // add saxon for backward-compatibility - final VirtualFile xsltFile = configuration.findXsltFile(); - final PsiManager psiManager = PsiManager.getInstance(configuration.getProject()); - if (xsltFile != null && XsltSupport.getXsltLanguageLevel(psiManager.findFile(xsltFile)) == XsltChecker.LanguageLevel.V2) - { + if (level == XsltChecker.LanguageLevel.V2) { parameters.getVMParametersList().defineProperty("xslt.transformer.type", "saxon9"); addSaxon(parameters, pluginPath, SAXON_9_JAR); } else { diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerRunner.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerRunner.java index 0aa7e9b17c83..b0b1939d56e3 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerRunner.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/XsltDebuggerRunner.java @@ -14,6 +14,7 @@ import com.intellij.xdebugger.XDebugProcess; import com.intellij.xdebugger.XDebugProcessStarter; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerManager; +import org.intellij.lang.xpath.xslt.run.XsltCommandLineState; import org.intellij.lang.xpath.xslt.run.XsltRunConfiguration; import org.intellij.plugins.xsltDebugger.impl.XsltDebugProcess; import org.jetbrains.annotations.NonNls; @@ -63,8 +64,9 @@ public class XsltDebuggerRunner extends DefaultProgramRunner { public XDebugProcess start(@NotNull final XDebugSession session) throws ExecutionException { ACTIVE.set(Boolean.TRUE); try { + final XsltCommandLineState c = (XsltCommandLineState)runProfileState; final ExecutionResult result = runProfileState.execute(executor, XsltDebuggerRunner.this); - return new XsltDebugProcess(session, result); + return new XsltDebugProcess(session, result, c.getExtensionData().getUserData(XsltDebuggerExtension.VERSION)); } finally { ACTIVE.remove(); } diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java index e5e69d9d7ca3..ce001241ad72 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java @@ -29,8 +29,8 @@ import org.jetbrains.annotations.Nullable; public class XsltBreakpointHandler extends XBreakpointHandler> { private XsltDebugProcess myXsltDebugProcess; - public XsltBreakpointHandler(XsltDebugProcess xsltDebugProcess) { - super(XsltBreakpointType.class); + public XsltBreakpointHandler(XsltDebugProcess xsltDebugProcess, final Class typeClass) { + super(typeClass); myXsltDebugProcess = xsltDebugProcess; } diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java index 29ab7418c8ce..d108aea47652 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java @@ -17,7 +17,9 @@ import com.intellij.xdebugger.breakpoints.XBreakpointHandler; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.frame.XExecutionStack; import com.intellij.xdebugger.frame.XSuspendContext; +import org.intellij.lang.xpath.xslt.impl.XsltChecker; import org.intellij.plugins.xsltDebugger.VMPausedException; +import org.intellij.plugins.xsltDebugger.XsltBreakpointType; import org.intellij.plugins.xsltDebugger.XsltDebuggerSession; import org.intellij.plugins.xsltDebugger.rt.engine.Breakpoint; import org.intellij.plugins.xsltDebugger.rt.engine.BreakpointManager; @@ -38,16 +40,17 @@ public class XsltDebugProcess extends XDebugProcess implements Disposable { private BreakpointManager myBreakpointManager = new BreakpointManagerImpl(); private final XBreakpointHandler[] myXBreakpointHandlers = new XBreakpointHandler[]{ - new XsltBreakpointHandler(this) + new XsltBreakpointHandler(this, XsltBreakpointType.V1.class), + new XsltBreakpointHandler(this, XsltBreakpointType.V2.class) }; private XsltDebuggerSession myDebuggerSession; - public XsltDebugProcess(XDebugSession session, ExecutionResult executionResult) { + public XsltDebugProcess(XDebugSession session, ExecutionResult executionResult, XsltChecker.LanguageLevel data) { super(session); myProcessHandler = executionResult.getProcessHandler(); myProcessHandler.putUserData(KEY, this); myExecutionConsole = executionResult.getExecutionConsole(); - myEditorsProvider = new XsltDebuggerEditorsProvider(); + myEditorsProvider = new XsltDebuggerEditorsProvider(data); Disposer.register(myExecutionConsole, this); } diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebuggerEditorsProvider.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebuggerEditorsProvider.java index 8872caf1f3c5..d1fec61805b3 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebuggerEditorsProvider.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebuggerEditorsProvider.java @@ -12,16 +12,24 @@ import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.EvaluationMode; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import org.intellij.lang.xpath.XPathFileType; +import org.intellij.lang.xpath.xslt.impl.XsltChecker; import org.intellij.plugins.xsltDebugger.BreakpointContext; import org.intellij.plugins.xsltDebugger.rt.engine.Debugger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class XsltDebuggerEditorsProvider extends XDebuggerEditorsProvider { + + private final XPathFileType myFileType; + + public XsltDebuggerEditorsProvider(XsltChecker.LanguageLevel level) { + myFileType = level == XsltChecker.LanguageLevel.V2 ? XPathFileType.XPATH2 : XPathFileType.XPATH; + } + @NotNull @Override public FileType getFileType() { - return XPathFileType.XPATH; + return myFileType; } @NotNull @@ -31,7 +39,7 @@ public class XsltDebuggerEditorsProvider extends XDebuggerEditorsProvider { @Nullable XSourcePosition sourcePosition, @NotNull EvaluationMode mode) { final PsiFile psiFile = PsiFileFactory.getInstance(project) - .createFileFromText("XPathExpr.xpath", XPathFileType.XPATH, text, LocalTimeCounter.currentTime(), true); + .createFileFromText("XPathExpr." + myFileType.getDefaultExtension(), myFileType, text, LocalTimeCounter.currentTime(), true); if (sourcePosition instanceof XsltSourcePosition && ((XsltSourcePosition)sourcePosition).getLocation() instanceof Debugger.StyleFrame) { final Debugger.Locatable location = ((XsltSourcePosition)sourcePosition).getLocation(); From 9aa8e57fb0fc95672dfd8ea2e501b34ec9fd4bc5 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 29 Nov 2011 15:52:47 +0100 Subject: [PATCH 07/44] fix broken popup location --- .../com/intellij/ide/navigationToolbar/NavBarPopup.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java index b04f5bc222b8..98fe6fdddcc2 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java @@ -39,8 +39,9 @@ import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.*; +import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * @author Konstantin Bulenkov @@ -109,7 +110,7 @@ public class NavBarPopup extends LightweightHint implements Disposable{ } private void show(final NavBarItem item, boolean checkRepaint) { - final RelativePoint point = new RelativePoint(item, new Point(-NavBarUIManager.getUI().getPopupOffset(item), item.getHeight())); + final RelativePoint point = new RelativePoint(item, new Point(0, item.getHeight())); final Point p = point.getPoint(myPanel); if (p.x == 0 && p.y == 0 && checkRepaint) { // need repaint of nav bar panel ApplicationManager.getApplication().invokeLater(new Runnable() { @@ -119,7 +120,8 @@ public class NavBarPopup extends LightweightHint implements Disposable{ } }); } else { - show(myPanel, p.x, p.y, myPanel, new HintHint(myPanel, p)); + int offset = NavBarUIManager.getUI().getPopupOffset(item); + show(myPanel, p.x - offset, p.y, myPanel, new HintHint(myPanel, p)); final JBList list = getList(); if (0 <= myIndex && myIndex < list.getItemsCount()) { ListScrollingUtil.selectItem(list, myIndex); From 8cb83e4650a1e6529b1244b7d705a98358fbc677 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Tue, 29 Nov 2011 16:03:39 +0100 Subject: [PATCH 08/44] Maven: no live templates after '<' --- .../maven/utils/MavenLiveTemplateContextType.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenLiveTemplateContextType.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenLiveTemplateContextType.java index 4e8b0f1abbf3..298fe24d1a8d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenLiveTemplateContextType.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenLiveTemplateContextType.java @@ -16,7 +16,10 @@ package org.jetbrains.idea.maven.utils; import com.intellij.codeInsight.template.TemplateContextType; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlText; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.dom.MavenDomUtil; @@ -26,6 +29,13 @@ public class MavenLiveTemplateContextType extends TemplateContextType { } public boolean isInContext(@NotNull final PsiFile file, final int offset) { - return MavenDomUtil.isMavenFile(file); + if (!MavenDomUtil.isMavenFile(file)) return false; + + PsiElement element = file.findElementAt(offset); + if (element == null) return false; + + if (PsiTreeUtil.getParentOfType(element, XmlText.class) == null) return false; + + return true; } } From 6b0572603fea8962c4b0df707f3a8ff342686951 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Tue, 29 Nov 2011 16:12:01 +0100 Subject: [PATCH 09/44] duplicate variables eliminated --- .../rt/engine/local/saxon9/Saxon9StyleFrame.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java b/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java index ff19095fb87a..0fae411e2944 100644 --- a/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java +++ b/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9StyleFrame.java @@ -124,10 +124,18 @@ class Saxon9StyleFrame extends AbstractSaxon9Frame Date: Tue, 29 Nov 2011 16:24:43 +0100 Subject: [PATCH 11/44] Maven: npe in plugin configuration dom --- .../idea/maven/dom/MavenPluginConfigurationDomExtender.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPluginConfigurationDomExtender.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPluginConfigurationDomExtender.java index 6190c8934524..2414a8852270 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPluginConfigurationDomExtender.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPluginConfigurationDomExtender.java @@ -84,7 +84,7 @@ public class MavenPluginConfigurationDomExtender extends DomExtender Date: Tue, 29 Nov 2011 19:13:07 +0400 Subject: [PATCH 12/44] EA-320624 wait for smart mode before every read action --- .../android/compiler/AndroidCompileUtil.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java index 2ab581ed0b9a..396b11f9b948 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java @@ -31,6 +31,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.ui.Messages; @@ -643,12 +644,17 @@ public class AndroidCompileUtil { public static void collectAllResources(@NotNull final AndroidFacet facet, final Set resourceSet) { final LocalResourceManager manager = facet.getLocalResourceManager(); + final Project project = facet.getModule().getProject(); + final DumbService dumbService = DumbService.getInstance(project); + for (final String resType : ResourceType.getNames()) { for (final ResourceElement element : manager.getValueResources(resType)) { + dumbService.waitForSmartMode(); + ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { - if (!element.isValid() || facet.getModule().isDisposed() || facet.getModule().getProject().isDisposed()) { + if (!element.isValid() || facet.getModule().isDisposed() || project.isDisposed()) { return; } final String name = element.getName().getValue(); @@ -662,10 +668,12 @@ public class AndroidCompileUtil { } for (final Resources resources : manager.getResourceElements()) { + dumbService.waitForSmartMode(); + ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { - if (!resources.isValid() || facet.getModule().isDisposed() || facet.getModule().getProject().isDisposed()) { + if (!resources.isValid() || facet.getModule().isDisposed() || project.isDisposed()) { return; } @@ -688,10 +696,12 @@ public class AndroidCompileUtil { }); } + dumbService.waitForSmartMode(); + ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { - if (facet.getModule().isDisposed() || facet.getModule().getProject().isDisposed()) { + if (facet.getModule().isDisposed() || project.isDisposed()) { return; } From 6dcc04af15f9c3026ef879f7e89a02a6d4f4367c Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Tue, 29 Nov 2011 18:31:59 +0300 Subject: [PATCH 13/44] IDEA-77358 If there are no remotes, don't show panel, don't load commits, disable push button, show error --- .../git4idea/push/GitManualPushToBranch.java | 2 +- .../src/git4idea/push/GitPushDialog.java | 21 +++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/plugins/git4idea/src/git4idea/push/GitManualPushToBranch.java b/plugins/git4idea/src/git4idea/push/GitManualPushToBranch.java index 94c34a73f4a9..66665daa7174 100644 --- a/plugins/git4idea/src/git4idea/push/GitManualPushToBranch.java +++ b/plugins/git4idea/src/git4idea/push/GitManualPushToBranch.java @@ -140,7 +140,7 @@ class GitManualPushToBranch extends JPanel { } @NotNull - private static Collection getRemotesWithCommonNames(@NotNull Collection repositories) { + public static Collection getRemotesWithCommonNames(@NotNull Collection repositories) { if (repositories.isEmpty()) { return Collections.emptyList(); } diff --git a/plugins/git4idea/src/git4idea/push/GitPushDialog.java b/plugins/git4idea/src/git4idea/push/GitPushDialog.java index 301ef503987b..03f26a58b440 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushDialog.java +++ b/plugins/git4idea/src/git4idea/push/GitPushDialog.java @@ -61,6 +61,8 @@ public class GitPushDialog extends DialogWrapper { private final Object COMMITS_LOADING_LOCK = new Object(); private final GitManualPushToBranch myRefspecPanel; private final AtomicReference myDestBranchInfoOnRefresh = new AtomicReference(); + + private final boolean myPushPossible; public GitPushDialog(@NotNull Project project) { super(project); @@ -84,10 +86,20 @@ public class GitPushDialog extends DialogWrapper { myListPanel = new GitPushLog(myProject, myRepositories, new RepositoryCheckboxListener()); myRefspecPanel = new GitManualPushToBranch(myRepositories, new RefreshButtonListener()); - + + if (GitManualPushToBranch.getRemotesWithCommonNames(myRepositories).isEmpty()) { + myRefspecPanel.setVisible(false); + setErrorText("Can't push, because no remotes are defined"); + setOKActionEnabled(false); + myPushPossible = false; + } else { + myPushPossible = true; + } + init(); setOKButtonText("Push"); setTitle("Git Push"); + } @Override @@ -105,7 +117,12 @@ public class GitPushDialog extends DialogWrapper { private JComponent createCommitListPanel() { myLoadingPanel.add(myListPanel, BorderLayout.CENTER); - loadCommitsInBackground(); + if (myPushPossible) { + loadCommitsInBackground(); + } else { + myLoadingPanel.startLoading(); + myLoadingPanel.stopLoading(); + } JPanel commitListPanel = new JPanel(new BorderLayout()); commitListPanel.add(myLoadingPanel, BorderLayout.CENTER); From 434c3e84d4b2ecd7940464f50e8406e06de4cb9c Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Tue, 29 Nov 2011 19:02:25 +0300 Subject: [PATCH 14/44] GitPushLog: don't use monospace font. Align commits by pre-calculating their width according to fontmetrics. --- .../src/git4idea/push/GitPushLog.java | 54 +++++++++++++------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/plugins/git4idea/src/git4idea/push/GitPushLog.java b/plugins/git4idea/src/git4idea/push/GitPushLog.java index 35be8eab1f66..997440bb2ca0 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushLog.java +++ b/plugins/git4idea/src/git4idea/push/GitPushLog.java @@ -19,8 +19,6 @@ import com.intellij.openapi.actionSystem.CommonShortcuts; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.DataSink; import com.intellij.openapi.actionSystem.TypeSafeDataProvider; -import com.intellij.openapi.editor.colors.EditorColorsManager; -import com.intellij.openapi.editor.colors.EditorFontType; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.vcs.VcsDataKeys; @@ -276,18 +274,41 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { private static class MyTreeCellRenderer extends CheckboxTree.CheckboxTreeCellRenderer { private int myDateMaxWidth; + private int myHashMaxWidth; + private static final int INSET = UIUtil.DEFAULT_HGAP; void recalculateWidth(@NotNull Collection commits) { for (GitCommit commit : commits) { - int len = getDateString(commit).length(); - if (len > myDateMaxWidth) { - myDateMaxWidth = len; + int dateLen = calcWidth(getDateString(commit)); + if (dateLen > myDateMaxWidth) { + myDateMaxWidth = dateLen; + } + int hashLen = calcWidth(getHashString(commit)); + if (hashLen > myHashMaxWidth) { + myHashMaxWidth = hashLen; } } } + @NotNull + private static String getHashString(@NotNull GitCommit commit) { + return commit.getShortHash().toString(); + } + + int calcWidth(String s) { + SimpleTextAttributes attributes = new SimpleTextAttributes(getCommitTextAttributesStyle(), getTextRenderer().getForeground()); + Font initialFont = getTextRenderer().getFont(); + Font font = initialFont.deriveFont(attributes.getFontStyle(), attributes.isSmaller() ? UIUtil.getFontSize(UIUtil.FontSize.SMALL) : initialFont.getSize()); + FontMetrics metrics = getTextRenderer().getFontMetrics(font); + return metrics.stringWidth(s); + } + + private static int getCommitTextAttributesStyle() { + return SimpleTextAttributes.STYLE_SMALLER; + } + private static String getDateString(GitCommit commit) { - return DateFormatUtil.formatPrettyDateTime(commit.getAuthorTime()); + return DateFormatUtil.formatPrettyDateTime(commit.getAuthorTime()) + " "; } @Override @@ -302,16 +323,19 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { } ColoredTreeCellRenderer renderer = getTextRenderer(); - Font font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN); // using probable monospace font to emulate table - renderer.setFont(font); - - SimpleTextAttributes smallGrey = new SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, UIUtil.getInactiveTextColor()); if (userObject instanceof GitCommit) { GitCommit commit = (GitCommit)userObject; - SimpleTextAttributes small = new SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, renderer.getForeground()); - renderer.append(commit.getShortHash().toString(), smallGrey); - renderer.append(String.format(" %" + myDateMaxWidth + "s ", getDateString(commit)), smallGrey); - renderer.append(commit.getSubject(), small); + SimpleTextAttributes grey = new SimpleTextAttributes(getCommitTextAttributesStyle(), UIUtil.getInactiveTextColor()); + + String hash = getHashString(commit); + renderer.append(hash, grey); + renderer.appendAlign(myHashMaxWidth + INSET); + + String date = getDateString(commit); + renderer.append(date, grey); + renderer.appendAlign(myDateMaxWidth + myHashMaxWidth + INSET * 2); + + renderer.append(commit.getSubject(), new SimpleTextAttributes(getCommitTextAttributesStyle(), getTextRenderer().getForeground())); } else if (userObject instanceof GitRepository) { String repositoryPath = calcRootPath((GitRepository)userObject); @@ -345,7 +369,7 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { break; } renderer.append(text, attrs); - renderer.append(additionalText, smallGrey); + renderer.append(additionalText, new SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, UIUtil.getInactiveTextColor())); } else if (userObject instanceof FakeCommit) { int spaces = 6 + 15 + 3 + 30; From 4a2f4e2d8ffb562c78e869ae6d13bd4026efd543 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 25 Nov 2011 11:58:23 +0100 Subject: [PATCH 15/44] mark introduced parameter as final when introduced from inner class (IDEA-77007) [yole] --- .../introduceParameter/IntroduceParameterHandler.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index ff5921437afc..8ce18260c8af 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -396,12 +396,10 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase { } boolean mustBeFinal = false; - if (myLocalVar != null) { - for(PsiExpression occurrence: occurences) { - if (PsiTreeUtil.getParentOfType(occurrence, PsiClass.class, PsiMethod.class) != method) { - mustBeFinal = true; - break; - } + for (PsiExpression occurrence : occurences) { + if (PsiTreeUtil.getParentOfType(occurrence, PsiClass.class, PsiMethod.class) != method) { + mustBeFinal = true; + break; } } From f8e37d5cc50660d2e975d2e4d167b31562e7ab42 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 25 Nov 2011 14:08:07 +0100 Subject: [PATCH 16/44] logging to prevent incorrect inspections configuration --- .../codeInspection/ex/DescriptorProviderInspection.java | 2 +- .../com/intellij/codeInspection/ex/InspectionToolWrapper.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorProviderInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorProviderInspection.java index 396f22337928..2d8d5ec100a3 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorProviderInspection.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/DescriptorProviderInspection.java @@ -57,7 +57,7 @@ public abstract class DescriptorProviderInspection extends InspectionTool implem private Map myIgnoredElements; private HashMap myOldProblemElements = null; - private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.DescriptorProviderInspection"); + protected static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.DescriptorProviderInspection"); public void addProblemElement(RefEntity refElement, CommonProblemDescriptor... descriptions){ addProblemElement(refElement, true, descriptions); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java index 6800577f73a4..4123e2f6736b 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java @@ -52,6 +52,7 @@ public abstract class InspectionToolWrapper Date: Fri, 25 Nov 2011 14:51:06 +0100 Subject: [PATCH 17/44] collect language level statistics [serega] --- .../impl/LanguageLevelUsagesCollector.java | 64 +++++++++++++++++++ resources/src/META-INF/IdeaPlugin.xml | 1 + 2 files changed, 65 insertions(+) create mode 100644 java/java-impl/src/com/intellij/openapi/roots/impl/LanguageLevelUsagesCollector.java diff --git a/java/java-impl/src/com/intellij/openapi/roots/impl/LanguageLevelUsagesCollector.java b/java/java-impl/src/com/intellij/openapi/roots/impl/LanguageLevelUsagesCollector.java new file mode 100644 index 000000000000..a022b701ff6c --- /dev/null +++ b/java/java-impl/src/com/intellij/openapi/roots/impl/LanguageLevelUsagesCollector.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2011 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.openapi.roots.impl; + +import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.LanguageLevelModuleExtension; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashSet; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +public class LanguageLevelUsagesCollector extends AbstractApplicationUsagesCollector { + public static final String GROUP_ID = "language-level"; + + @NotNull + @Override + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); + } + + + @NotNull + public Set getProjectUsages(@NotNull Project project) { + + final Set languageLevels = new HashSet(); + for (Module module : ModuleManager.getInstance(project).getModules()) { + final LanguageLevelModuleExtension instance = LanguageLevelModuleExtension.getInstance(module); + final LanguageLevel languageLevel = instance.getLanguageLevel(); + if (languageLevel != null) { + languageLevels.add(languageLevel.getPresentableText()); + } + } + languageLevels.add(LanguageLevelProjectExtension.getInstance(project).getLanguageLevel().getPresentableText()); + + return ContainerUtil.map2Set(languageLevels, new Function() { + @Override + public UsageDescriptor fun(String languageLevel) { + return new UsageDescriptor(languageLevel, 1); + } + }); + } +} diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 35a81ac95aa2..c2f291d22407 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -917,6 +917,7 @@ + From 9507051948a1b5a7d9c167812dfedf7b1f2cbb92 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 25 Nov 2011 16:47:02 +0100 Subject: [PATCH 18/44] extract method: do not suggest static method for anonymous/local [romka] --- .../refactoring/extractMethod/ExtractMethodProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index 417883814970..8b4723334984 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -1179,7 +1179,7 @@ public class ExtractMethodProcessor implements MatchProvider { private boolean applyChosenClassAndExtract(List inputVariables, @Nullable Pass extractPass) throws PrepareFailedException { myStatic = shouldBeStatic(); - if (myTargetClass.getContainingClass() == null || myTargetClass.hasModifierProperty(PsiModifier.STATIC)) { + if (!PsiUtil.isLocalOrAnonymousClass(myTargetClass) && (myTargetClass.getContainingClass() == null || myTargetClass.hasModifierProperty(PsiModifier.STATIC))) { ElementNeedsThis needsThis = new ElementNeedsThis(myTargetClass); for (int i = 0; i < myElements.length && !needsThis.usesMembers(); i++) { PsiElement element = myElements[i]; From 8f85cd458f793ead1ee884a13893ad1cba876b74 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 25 Nov 2011 16:52:20 +0100 Subject: [PATCH 19/44] plugins: disable uninstall action for just installed plugins (~IDEA-77630 ) --- .../src/com/intellij/ide/plugins/ActionUninstallPlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java index 64a563a7ee2c..827b8116362b 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java @@ -62,7 +62,8 @@ public class ActionUninstallPlugin extends AnAction implements DumbAware { } } if (descriptor instanceof PluginNode) { - enabled &= PluginManagerColumnInfo.getRealNodeState((PluginNode)descriptor) == PluginNode.STATUS_DOWNLOADED; + enabled = false; + break; } } } From 1cb11541b6a78773f63c7fc0fb54f1da2bedc4dd Mon Sep 17 00:00:00 2001 From: "kirill.safonov" Date: Tue, 29 Nov 2011 19:25:15 +0400 Subject: [PATCH 20/44] AS/JS change signature dialog: don't show column titles with colon --- .../changeSignature/ParameterTableModelBase.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java index 592fe93ef711..7f816e5c9c3c 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java @@ -129,7 +129,11 @@ public abstract class ParameterTableModelBase

extends L private final FileType myFileType; public TypeColumn(Project project, FileType fileType) { - super(RefactoringBundle.message("column.name.type")); + this(project, fileType, RefactoringBundle.message("column.name.type")); + } + + public TypeColumn(Project project, FileType fileType, String title) { + super(title); myProject = project; myFileType = fileType; } @@ -157,7 +161,11 @@ public abstract class ParameterTableModelBase

extends L private final Project myProject; public NameColumn(Project project) { - super(RefactoringBundle.message("column.name.name")); + this(project, RefactoringBundle.message("column.name.name")); + } + + public NameColumn(Project project, String title) { + super(title); myProject = project; } From c9c6d777d2843b37b9a519286b868194b96b46dc Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Tue, 29 Nov 2011 17:27:36 +0100 Subject: [PATCH 21/44] Maven: do not delete/reread maven projects on FileContentUtil.reparseFiles (IDEA-77770, IDEA-77615, IDEA-76228) --- .../project/MavenProjectsManagerWatcher.java | 10 ++- .../project/MavenProjectsManagerTest.java | 70 +++++++++++++------ 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java index 212ef98b9d6c..13ce80de07a1 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java @@ -29,6 +29,7 @@ import com.intellij.openapi.project.ModuleAdapter; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootListener; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; @@ -441,7 +442,7 @@ public class MavenProjectsManagerWatcher { else { if (!isRelevant(each.getPath())) continue; if (each instanceof VFilePropertyChangeEvent) { - if (((VFilePropertyChangeEvent)each).getPropertyName().equals(VirtualFile.PROP_NAME)) { + if (isRenamed(each)) { deleteRecursively(each.getFile()); } } @@ -491,7 +492,7 @@ public class MavenProjectsManagerWatcher { updateFile(each.getFile()); } else if (each instanceof VFilePropertyChangeEvent) { - if (((VFilePropertyChangeEvent)each).getPropertyName().equals(VirtualFile.PROP_NAME)) { + if (isRenamed(each)) { updateFile(each.getFile()); } } @@ -501,5 +502,10 @@ public class MavenProjectsManagerWatcher { } apply(); } + + private static boolean isRenamed(VFileEvent each) { + return ((VFilePropertyChangeEvent)each).getPropertyName().equals(VirtualFile.PROP_NAME) + && !Comparing.equal(((VFilePropertyChangeEvent)each).getOldValue(), ((VFilePropertyChangeEvent)each).getNewValue()); + } } } diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java index 7f98c91d0fc1..89dfcf9a4dc3 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsManagerTest.java @@ -26,6 +26,7 @@ import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.FileContentUtil; import org.jetbrains.idea.maven.MavenImportingTestCase; import org.jetbrains.idea.maven.importing.MavenRootModelAdapter; import org.jetbrains.idea.maven.server.NativeMavenProjectHolder; @@ -96,9 +97,9 @@ public class MavenProjectsManagerTest extends MavenImportingTestCase { "1"); final VirtualFile p2 = createModulePom("project2", - "test" + - "project2" + - "1"); + "test" + + "project2" + + "1"); importProjects(p1, p2); assertEquals(2, myProjectsTree.getRootProjects().size()); @@ -127,9 +128,9 @@ public class MavenProjectsManagerTest extends MavenImportingTestCase { "1"); final VirtualFile p2 = createModulePom("project2", - "test" + - "project2" + - "1"); + "test" + + "project2" + + "1"); importProjects(p1, p2); final VirtualFile oldDir = p2.getParent(); @@ -165,9 +166,9 @@ public class MavenProjectsManagerTest extends MavenImportingTestCase { ""); final VirtualFile m = createModulePom("m1", - "test" + - "m" + - "1"); + "test" + + "m" + + "1"); importProject(); final VirtualFile oldDir = m.getParent(); @@ -726,9 +727,9 @@ public class MavenProjectsManagerTest extends MavenImportingTestCase { ""); final VirtualFile m = createModulePom("m", - "test" + - "m" + - "1"); + "test" + + "m" + + "1"); importProject(); myProjectsManager.performScheduledImportInTests(); // ensure no pending requests assertModules("project", "m"); @@ -822,16 +823,16 @@ public class MavenProjectsManagerTest extends MavenImportingTestCase { ""); final VirtualFile m2 = createModulePom("m2", "test" + - "m2" + - "1" + + "m2" + + "1" + - "" + - " " + - " junit" + - " junit" + - " 4.0" + - " " + - ""); + "" + + " " + + " junit" + + " junit" + + " 4.0" + + " " + + ""); importProject(); @@ -1077,4 +1078,31 @@ public class MavenProjectsManagerTest extends MavenImportingTestCase { assertNull(ModuleManager.getInstance(myProject).findModuleByName("m")); assertTrue(myProjectsManager.isIgnored(myProjectsManager.findProject(m))); } + + public void testDoNotRemoveMavenProjectsOnReparse() throws Exception { + // this pom file doesn't belong to any of the modules, this is won't be processed + // by MavenProjectProjectsManager and won't occur in its projects list. + importProject("test" + + "project" + + "1"); + + final StringBuilder log = new StringBuilder(); + myProjectsManager.performScheduledImportInTests(); + myProjectsManager.addProjectsTreeListener(new MavenProjectsTree.ListenerAdapter() { + @Override + public void projectsUpdated(List> updated, List deleted) { + for (Pair each : updated) { + log.append("updated: " + each.first.getDisplayName() + " "); + } + for (MavenProject each : deleted) { + log.append("deleted: " + each.getDisplayName() + " "); + } + } + }); + + FileContentUtil.reparseFiles(myProject, myProjectsManager.getProjectsFiles(), true); + myProjectsManager.waitForReadingCompletion(); + + assertTrue(log.toString(), log.length() == 0); + } } From b9af09d1095b454b1580a9015af20e5f4263bb8a Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Tue, 29 Nov 2011 17:55:01 +0100 Subject: [PATCH 22/44] Maven: invalidate dom element descriptors on psi changes (rev. Peter) --- .../dom/MavenDomElementDescriptorHolder.java | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomElementDescriptorHolder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomElementDescriptorHolder.java index 996a480488f7..9a72ca519824 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomElementDescriptorHolder.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomElementDescriptorHolder.java @@ -24,6 +24,10 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.PsiModificationTracker; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.xml.XmlElementDescriptor; @@ -38,6 +42,7 @@ import java.util.Map; public class MavenDomElementDescriptorHolder { private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.maven.dom.MavenDomElementDescriptorHolder"); + private enum FileKind { PROJECT_FILE { public String getSchemaUrl() { @@ -59,7 +64,8 @@ public class MavenDomElementDescriptorHolder { } private final Project myProject; - private final Map myDescriptorsMap = new THashMap(); + private final Map> myDescriptorsMap = + new THashMap>(); public MavenDomElementDescriptorHolder(Project project) { myProject = project; @@ -80,14 +86,27 @@ public class MavenDomElementDescriptorHolder { if (desc == null) return null; } LOG.assertTrue(tag.isValid()); + LOG.assertTrue(desc.isValid()); return desc.getElementDescriptor(tag.getName(), desc.getDefaultNamespace()); } @Nullable - private XmlNSDescriptorImpl tryGetOrCreateDescriptor(FileKind kind) { - XmlNSDescriptorImpl result = myDescriptorsMap.get(kind); - if (result != null && result.isValid()) return result; + private XmlNSDescriptorImpl tryGetOrCreateDescriptor(final FileKind kind) { + CachedValue result = myDescriptorsMap.get(kind); + if (result == null) { + result = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider() { + @Override + public Result compute() { + return Result.create(doCreateDescriptor(kind), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); + } + }); + myDescriptorsMap.put(kind, result); + } + return result.getValue(); + } + @Nullable + private XmlNSDescriptorImpl doCreateDescriptor(FileKind kind) { String schemaUrl = kind.getSchemaUrl(); String location = ExternalResourceManager.getInstance().getResourceLocation(schemaUrl); if (schemaUrl.equals(location)) return null; @@ -105,14 +124,12 @@ public class MavenDomElementDescriptorHolder { PsiFile psiFile = PsiManager.getInstance(myProject).findFile(schema); if (!(psiFile instanceof XmlFile)) return null; - result = new XmlNSDescriptorImpl(); - + XmlNSDescriptorImpl result = new XmlNSDescriptorImpl(); result.init(psiFile); - myDescriptorsMap.put(kind, result); - return result; } + @Nullable private FileKind getFileKind(PsiFile file) { if (MavenDomUtil.isProjectFile(file)) return FileKind.PROJECT_FILE; if (MavenDomUtil.isProfilesFile(file)) return FileKind.PROFILES_FILE; From 29ef28277f07ae5b94e80a49424963cb90e7f470 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Tue, 29 Nov 2011 20:59:11 +0400 Subject: [PATCH 23/44] [r=kirillk] pinch zoom gesture for the editor --- .../impl/MouseGestureManager.java | 98 ++++++++++++++----- .../openapi/editor/impl/EditorImpl.java | 3 +- 2 files changed, 73 insertions(+), 28 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java index 678a9b9d8b61..62a0ea86979f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java @@ -15,22 +15,25 @@ */ package com.intellij.openapi.actionSystem.impl; +import com.apple.eawt.event.*; +import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFrame; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; @@ -39,7 +42,9 @@ public class MouseGestureManager implements ApplicationComponent { private static final Logger LOG = Logger.getInstance("MouseGestureManager"); private ActionManagerImpl myActionManager; - private Map myListeners = new HashMap(); + private Map myListeners = new HashMap(); + private boolean HAS_TRACKPAD = false; + public MouseGestureManager(ActionManagerImpl actionManager) { myActionManager = actionManager; @@ -54,32 +59,74 @@ public class MouseGestureManager implements ApplicationComponent { remove(frame); } - Class gestureListenerClass = Class.forName("com.apple.eawt.event.GestureListener"); - Class swipeListenerClass = Class.forName("com.apple.eawt.event.SwipeListener"); - Object listener = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{swipeListenerClass}, new InvocationHandler() { + GestureAdapter listener = new GestureAdapter() { + double magnification = 0; @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if ("swipedRight".equals(method.getName())) { - processRightSwipe(frame); - } else if ("swipedLeft".equals(method.getName())) { - processLeftSwipe(frame); - } - return null; + public void gestureBegan(GesturePhaseEvent event) { + activateTrackpad(); + magnification = 0; } - }); - Class utilsClass = Class.forName("com.apple.eawt.event.GestureUtilities"); - Method addMethod = utilsClass.getDeclaredMethod("addGestureListenerTo", JComponent.class, gestureListenerClass); - addMethod.invoke(null, frame.getComponent(), listener); + @Override + public void gestureEnded(GesturePhaseEvent event) { + activateTrackpad(); + if (magnification != 0) { + processMagnification(frame, magnification); + magnification = 0; + } + } + + @Override + public void swipedLeft(SwipeEvent event) { + activateTrackpad(); + processLeftSwipe(frame); + } + + @Override + public void swipedRight(SwipeEvent event) { + activateTrackpad(); + processRightSwipe(frame); + } + + @Override + public void magnify(MagnificationEvent event) { + activateTrackpad(); + magnification += event.getMagnification(); + } + }; + + GestureUtilities.addGestureListenerTo(frame.getComponent(), listener); myListeners.put(frame, listener); } - catch (Exception e) { + catch (Throwable e) { LOG.debug(e); } } } + private void activateTrackpad() { + HAS_TRACKPAD = true; + } + + public boolean hasTrackpad() { + return HAS_TRACKPAD; + } + + private static void processMagnification(IdeFrame frame, double magnification) { + Point mouse = MouseInfo.getPointerInfo().getLocation(); + SwingUtilities.convertPointFromScreen(mouse, frame.getComponent()); + Component componentAt = SwingUtilities.getDeepestComponentAt(frame.getComponent(), mouse.x, mouse.y); + if (componentAt != null) { + Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(componentAt)); + if (editor != null) { + double currentSize = editor.getColorsScheme().getEditorFontSize(); + int defaultFontSize = EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize(); + ((EditorEx)editor).setFontSize((int)(Math.max(currentSize + magnification * 3, defaultFontSize))); + } + } + } + private void processLeftSwipe(IdeFrame frame) { AnAction forward = myActionManager.getAction("Forward"); if (forward == null) return; @@ -94,7 +141,7 @@ public class MouseGestureManager implements ApplicationComponent { myActionManager.tryToExecute(back, createMouseEventWrapper(frame), null, null, false); } - private MouseEvent createMouseEventWrapper(IdeFrame frame) { + private static MouseEvent createMouseEventWrapper(IdeFrame frame) { return new MouseEvent(frame.getComponent(), ActionEvent.ACTION_PERFORMED, System.currentTimeMillis(), 0, 0, 0, 0, false, 0); } @@ -103,17 +150,14 @@ public class MouseGestureManager implements ApplicationComponent { if (SystemInfo.isMacOSSnowLeopard) { try { - Object listener = myListeners.get(frame); + GestureListener listener = myListeners.get(frame); JComponent cmp = frame.getComponent(); myListeners.remove(frame); if (listener != null && cmp != null && cmp.isShowing()) { - Class gestureListenerClass = Class.forName("com.apple.eawt.event.GestureListener"); - Class utilsClass = Class.forName("com.apple.eawt.event.GestureUtilities"); - Method addMethod = utilsClass.getDeclaredMethod("removeGestureListenerFrom", JComponent.class, gestureListenerClass); - addMethod.invoke(null, cmp, listener); + GestureUtilities.removeGestureListenerFrom(cmp, listener); } } - catch (Exception e) { + catch (Throwable e) { LOG.debug(e); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 459f84dc8bc1..eca9c747af4d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -29,6 +29,7 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.impl.MouseGestureManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationManagerEx; @@ -6096,7 +6097,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi @Override protected void processMouseWheelEvent(MouseWheelEvent e) { - if (mySettings.isWheelFontChangeEnabled()) { + if (mySettings.isWheelFontChangeEnabled() && !MouseGestureManager.getInstance().hasTrackpad()) { if (EditorUtil.isChangeFontSize(e)) { setFontSize(myScheme.getEditorFontSize() - e.getWheelRotation()); return; From 6cebe2c007086522073321a91a4de1ab27c61ef5 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Tue, 29 Nov 2011 18:12:58 +0100 Subject: [PATCH 24/44] IDEA-77412: XSLT debug: ConnectException is reported much later after Debugger GUI shows completed process --- .../org/intellij/plugins/xsltDebugger/DebuggerConnector.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/DebuggerConnector.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/DebuggerConnector.java index 3d7831798c3c..7ce6a6b32c75 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/DebuggerConnector.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/DebuggerConnector.java @@ -93,6 +93,8 @@ class DebuggerConnector implements Runnable { private Debugger connect() { Throwable lastException = null; for (int i = 0; i < 10; i++) { + if (myProcess.isProcessTerminated()) return null; + try { final Debugger realClient = EDTGuard.create(new RemoteDebuggerClient(myPort), myProcess); myProcess.notifyTextAvailable("Connected to XSLT debugger on port " + myPort + "\n", ProcessOutputTypes.SYSTEM); From c5a0383c22361cdcb41e5475b96af7a0639491d8 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Tue, 29 Nov 2011 21:29:19 +0400 Subject: [PATCH 25/44] apple missing API fix --- .../openapi/actionSystem/impl/MouseGestureManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java index 62a0ea86979f..1936715f84cf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java @@ -42,7 +42,7 @@ public class MouseGestureManager implements ApplicationComponent { private static final Logger LOG = Logger.getInstance("MouseGestureManager"); private ActionManagerImpl myActionManager; - private Map myListeners = new HashMap(); + private Map myListeners = new HashMap(); private boolean HAS_TRACKPAD = false; @@ -150,11 +150,11 @@ public class MouseGestureManager implements ApplicationComponent { if (SystemInfo.isMacOSSnowLeopard) { try { - GestureListener listener = myListeners.get(frame); + Object listener = myListeners.get(frame); JComponent cmp = frame.getComponent(); myListeners.remove(frame); if (listener != null && cmp != null && cmp.isShowing()) { - GestureUtilities.removeGestureListenerFrom(cmp, listener); + GestureUtilities.removeGestureListenerFrom(cmp, (GestureListener)listener); } } catch (Throwable e) { From 11a3bd039e8e41505d828ea37474e1a55c5f8b43 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Tue, 29 Nov 2011 18:31:22 +0100 Subject: [PATCH 26/44] IDEA-77666: XSLT debug: Step Out leaves the session in an incomplete state (Step Out not supported yet, does a normal step) --- .../intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java index d108aea47652..48d6c8cadab4 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java @@ -23,8 +23,8 @@ import org.intellij.plugins.xsltDebugger.XsltBreakpointType; import org.intellij.plugins.xsltDebugger.XsltDebuggerSession; import org.intellij.plugins.xsltDebugger.rt.engine.Breakpoint; import org.intellij.plugins.xsltDebugger.rt.engine.BreakpointManager; -import org.intellij.plugins.xsltDebugger.rt.engine.Debugger; import org.intellij.plugins.xsltDebugger.rt.engine.BreakpointManagerImpl; +import org.intellij.plugins.xsltDebugger.rt.engine.Debugger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -132,6 +132,7 @@ public class XsltDebugProcess extends XDebugProcess implements Disposable { @Override public void startStepOut() { + myDebuggerSession.stepOver(); } @Override From f5a9f5522e130231e21ace9428ab827453671245 Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Tue, 29 Nov 2011 18:13:59 +0300 Subject: [PATCH 27/44] eawtstub updated --- lib/eawtstub.jar | Bin 6346 -> 24077 bytes lib/src/eawtstub_src.zip | Bin 16694 -> 32484 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/lib/eawtstub.jar b/lib/eawtstub.jar index 089e5487aad38a83a88b9d6951d9fa0fc2704da7..62903c29ab5b5c8f5002936ef25338522f652359 100644 GIT binary patch literal 24077 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 Q?|?s5z+2mn=k>4u0VdF4w*UYD From 5b52b64eac09ef8e07315f66faa092358efe86d8 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 29 Nov 2011 18:58:39 +0100 Subject: [PATCH 28/44] IDEA-75622 Threads in debugger are sorted case-sensitively --- java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java index 0324b445af37..9a86dff9062c 100644 --- a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java +++ b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java @@ -191,7 +191,7 @@ public class ThreadDumpPanel extends JPanel { final int s1 = getThreadStateCode(o1).ordinal(); final int s2 = getThreadStateCode(o2).ordinal(); if (s1 == s2) { - return o1.getName().compareTo(o2.getName()); + return o1.getName().compareToIgnoreCase(o2.getName()); } else { return s1 < s2 ? - 1 : 1; } From f6e7f6805b968f3d7420d3e0bfcf59bf8d8beea8 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 29 Nov 2011 18:44:16 +0100 Subject: [PATCH 29/44] hide mac gestures from other users --- .../actionSystem/impl/MacGestureAdapter.java | 75 +++++++++++++++++++ .../impl/MouseGestureManager.java | 49 ++---------- 2 files changed, 81 insertions(+), 43 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MacGestureAdapter.java diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MacGestureAdapter.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MacGestureAdapter.java new file mode 100644 index 000000000000..32538508f7a0 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MacGestureAdapter.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2011 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.openapi.actionSystem.impl; + +import com.apple.eawt.event.*; +import com.intellij.openapi.wm.IdeFrame; + +import javax.swing.*; + +/** +* User: anna +* Date: 11/29/11 +*/ +class MacGestureAdapter extends GestureAdapter { + double magnification; + private final IdeFrame myFrame; + private MouseGestureManager myManager; + + public MacGestureAdapter(MouseGestureManager manager, IdeFrame frame) { + myFrame = frame; + magnification = 0; + myManager = manager; + GestureUtilities.addGestureListenerTo(frame.getComponent(), this); + } + + @Override + public void gestureBegan(GesturePhaseEvent event) { + myManager.activateTrackpad(); + magnification = 0; + } + + @Override + public void gestureEnded(GesturePhaseEvent event) { + myManager.activateTrackpad(); + if (magnification != 0) { + MouseGestureManager.processMagnification(myFrame, magnification); + magnification = 0; + } + } + + @Override + public void swipedLeft(SwipeEvent event) { + myManager.activateTrackpad(); + myManager.processLeftSwipe(myFrame); + } + + @Override + public void swipedRight(SwipeEvent event) { + myManager.activateTrackpad(); + myManager.processRightSwipe(myFrame); + } + + @Override + public void magnify(MagnificationEvent event) { + myManager.activateTrackpad(); + magnification += event.getMagnification(); + } + + public void remove(JComponent cmp) { + GestureUtilities.removeGestureListenerFrom(cmp, this); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java index 1936715f84cf..7e4ae8bb03fd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MouseGestureManager.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.actionSystem.impl; -import com.apple.eawt.event.*; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -59,43 +58,7 @@ public class MouseGestureManager implements ApplicationComponent { remove(frame); } - GestureAdapter listener = new GestureAdapter() { - double magnification = 0; - @Override - public void gestureBegan(GesturePhaseEvent event) { - activateTrackpad(); - magnification = 0; - } - - @Override - public void gestureEnded(GesturePhaseEvent event) { - activateTrackpad(); - if (magnification != 0) { - processMagnification(frame, magnification); - magnification = 0; - } - } - - @Override - public void swipedLeft(SwipeEvent event) { - activateTrackpad(); - processLeftSwipe(frame); - } - - @Override - public void swipedRight(SwipeEvent event) { - activateTrackpad(); - processRightSwipe(frame); - } - - @Override - public void magnify(MagnificationEvent event) { - activateTrackpad(); - magnification += event.getMagnification(); - } - }; - - GestureUtilities.addGestureListenerTo(frame.getComponent(), listener); + Object listener = new MacGestureAdapter(this, frame); myListeners.put(frame, listener); } @@ -105,7 +68,7 @@ public class MouseGestureManager implements ApplicationComponent { } } - private void activateTrackpad() { + protected void activateTrackpad() { HAS_TRACKPAD = true; } @@ -113,7 +76,7 @@ public class MouseGestureManager implements ApplicationComponent { return HAS_TRACKPAD; } - private static void processMagnification(IdeFrame frame, double magnification) { + protected static void processMagnification(IdeFrame frame, double magnification) { Point mouse = MouseInfo.getPointerInfo().getLocation(); SwingUtilities.convertPointFromScreen(mouse, frame.getComponent()); Component componentAt = SwingUtilities.getDeepestComponentAt(frame.getComponent(), mouse.x, mouse.y); @@ -127,14 +90,14 @@ public class MouseGestureManager implements ApplicationComponent { } } - private void processLeftSwipe(IdeFrame frame) { + protected void processLeftSwipe(IdeFrame frame) { AnAction forward = myActionManager.getAction("Forward"); if (forward == null) return; myActionManager.tryToExecute(forward, createMouseEventWrapper(frame), null, null, false); } - private void processRightSwipe(IdeFrame frame) { + protected void processRightSwipe(IdeFrame frame) { AnAction back = myActionManager.getAction("Back"); if (back == null) return; @@ -154,7 +117,7 @@ public class MouseGestureManager implements ApplicationComponent { JComponent cmp = frame.getComponent(); myListeners.remove(frame); if (listener != null && cmp != null && cmp.isShowing()) { - GestureUtilities.removeGestureListenerFrom(cmp, (GestureListener)listener); + ((MacGestureAdapter)listener).remove(cmp); } } catch (Throwable e) { From 63518f721c6d1e706e052667d1a148c841149527 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 Nov 2011 19:55:26 +0100 Subject: [PATCH 30/44] dead code(cherry picked from commit 39a0307) --- .../dynamic/DynamicChangeListener.java | 29 ---------- .../intentions/dynamic/DynamicManager.java | 13 ----- .../dynamic/DynamicManagerImpl.java | 53 +++---------------- 3 files changed, 8 insertions(+), 87 deletions(-) delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicChangeListener.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicChangeListener.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicChangeListener.java deleted file mode 100644 index 0f91df3ea3bb..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicChangeListener.java +++ /dev/null @@ -1,29 +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 org.jetbrains.plugins.groovy.annotator.intentions.dynamic; - -import java.util.EventListener; - -/** - * User: Dmitry.Krasilschikov - * Date: 11.01.2008 - */ -public interface DynamicChangeListener extends EventListener { - /* - * Change property - */ - public void dynamicPropertyChange(); -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicManager.java index 459373344ac9..06296cd5eae4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicManager.java @@ -63,16 +63,6 @@ public abstract class DynamicManager implements ProjectComponent, PersistentStat public abstract void replaceClassName(final DClassElement oldClassElement, String newClassName); - /* - * Adds dynamicPropertyChange listener - */ - public abstract void addDynamicChangeListener(DynamicChangeListener listener); - - /* - * Removes dynamicPropertyChange listener - */ - public abstract void removeDynamicChangeListener(DynamicChangeListener listener); - public abstract void addProperty(DynamicElementSettings settings); public abstract void addMethod(DynamicElementSettings settings); @@ -85,9 +75,6 @@ public abstract class DynamicManager implements ProjectComponent, PersistentStat @NotNull public abstract Collection findDynamicPropertiesOfClass(final String conatainingClassName); - @NotNull - public abstract String[] getPropertiesNamesOfClass(final String conatainingClassName); - @Nullable public abstract String getPropertyType(String className, String propertyName); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicManagerImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicManagerImpl.java index 0d472320a8fb..5750b5ede6f1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicManagerImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicManagerImpl.java @@ -19,7 +19,6 @@ import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.components.StorageScheme; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; @@ -27,7 +26,6 @@ import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.wm.ToolWindow; import com.intellij.psi.*; import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns; -import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.tree.TreeUtil; @@ -39,7 +37,10 @@ import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.ui.DynamicEleme import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import javax.swing.tree.DefaultMutableTreeNode; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; /** * User: Dmitry.Krasilschikov @@ -53,10 +54,7 @@ import java.util.*; }) public class DynamicManagerImpl extends DynamicManager { - private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicManagerImpl"); - private final Project myProject; - private final List myListeners = new ArrayList(); private DRootElement myRootElement = new DRootElement(); public DynamicManagerImpl(final Project project) { @@ -111,7 +109,7 @@ public class DynamicManagerImpl extends DynamicManager { doRemove(wrapper, node, parent); } - private void doRemove(DynamicToolWindowWrapper wrapper, DefaultMutableTreeNode node, DefaultMutableTreeNode parent) { + private static void doRemove(DynamicToolWindowWrapper wrapper, DefaultMutableTreeNode node, DefaultMutableTreeNode parent) { DefaultMutableTreeNode toSelect = (parent.getChildAfter(node) != null || parent.getChildCount() == 1 ? node.getNextNode() : node.getPreviousNode()); @@ -166,7 +164,7 @@ public class DynamicManagerImpl extends DynamicManager { }, true); } - private int getIndexToInsert(DefaultMutableTreeNode parent, DNamedElement namedElement) { + private static int getIndexToInsert(DefaultMutableTreeNode parent, DNamedElement namedElement) { if (parent.getChildCount() == 0) return 0; int res = 0; @@ -220,19 +218,6 @@ public class DynamicManagerImpl extends DynamicManager { return new ArrayList(); } - @NotNull - public String[] getPropertiesNamesOfClass(String conatainingClassName) { - final DClassElement classElement = findClassElement(getRootElement(), conatainingClassName); - - Set result = new HashSet(); - if (classElement != null) { - for (DPropertyElement propertyElement : classElement.getProperties()) { - result.add(propertyElement.getName()); - } - } - return ArrayUtil.toStringArray(result); - } - @Nullable public String getPropertyType(String className, String propertyName) { final DPropertyElement dynamicProperty = findConcreteDynamicProperty(getRootElement(), className, propertyName); @@ -253,24 +238,6 @@ public class DynamicManagerImpl extends DynamicManager { return myRootElement; } - /* - * Adds dynamicPropertyChange listener - */ - public void addDynamicChangeListener(DynamicChangeListener listener) { - myListeners.add(listener); - } - - /* - * Removes dynamicPropertyChange listener - */ - public void removeDynamicChangeListener(DynamicChangeListener listener) { - myListeners.remove(listener); - } - - /* - * Changes dynamic property - */ - public String replaceDynamicPropertyName(String className, String oldPropertyName, String newPropertyName) { final DClassElement classElement = findClassElement(getRootElement(), className); if (classElement == null) return null; @@ -403,10 +370,6 @@ public class DynamicManagerImpl extends DynamicManager { } public void fireChange() { - for (DynamicChangeListener listener : myListeners) { - listener.dynamicPropertyChange(); - } - fireChangeCodeAnalyze(); } @@ -427,7 +390,7 @@ public class DynamicManagerImpl extends DynamicManager { } @Nullable - public DPropertyElement findConcreteDynamicProperty(DRootElement rootElement, final String conatainingClassName, final String propertyName) { + private static DPropertyElement findConcreteDynamicProperty(DRootElement rootElement, final String conatainingClassName, final String propertyName) { final DClassElement classElement = rootElement.getClassElement(conatainingClassName); if (classElement == null) return null; @@ -436,7 +399,7 @@ public class DynamicManagerImpl extends DynamicManager { } @Nullable - private DClassElement findClassElement(DRootElement rootElement, final String conatainingClassName) { + private static DClassElement findClassElement(DRootElement rootElement, final String conatainingClassName) { return rootElement.getClassElement(conatainingClassName); } From 8f1cf6ed4d54712d7fb6bea48cd22a8a921cf59e Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 Nov 2011 19:55:43 +0100 Subject: [PATCH 31/44] [^yole] disable groovy hotswap via registry(cherry picked from commit 6967c0b) --- platform/platform-resources-en/src/misc/registry.properties | 3 +++ .../jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index defbbf58363a..3c9022834161 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -162,3 +162,6 @@ navbar.is.decorated=true navbar.is.decorated.description=NavBar with decorations show.anonymous.in.structure.view=false show.anonymous.in.structure.view.description=Enables Java anonymous classes in Structure View + +enable.groovy.hotswap=true +enable.groovy.hotswap.description=Whether IDEA should add a special java agent to the debugged process which allows to hot-swap Groovy changes in some cases diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java index e848a11816cd..8b38ae20f06e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java @@ -17,6 +17,7 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.LanguageLevelModuleExtension; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.registry.Registry; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; @@ -67,10 +68,11 @@ public class GroovyHotSwapper extends JavaProgramPatcher { if (!executor.getId().equals(DefaultDebugExecutor.EXECUTOR_ID)) { return; } - if ("false".equals(System.getProperty("enable.groovy.hotswap", "true"))) { + + if (!Registry.is("enable.groovy.hotswap")) { return; } - + if (!(configuration instanceof RunConfiguration)) { return; } From cbf9c31cbde512154f16c88e4bdfc294535517c8 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 Nov 2011 19:55:47 +0100 Subject: [PATCH 32/44] [^yole] a popup menu for dynamic properties (IDEA-59053, IDEA-54372)(cherry picked from commit c5fa3a0) --- .../plugins/groovy/GroovyBundle.properties | 2 +- .../dynamic/DynamicToolWindowWrapper.java | 28 +++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index ab7d8f55f8d3..d36192f763e5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -275,7 +275,7 @@ duplicate.element.in.the.map=Duplicate element in the map message.nothing.to.show.in.structure.view=There are no dynamic properties dynamic.toolwindow.search.elements=Search dynamic element dynamic.toolwindow.property.fiter=Property Filter -dynamic.tool.window.id=Dynamic properties +dynamic.tool.window.id=Dynamic Properties create.from.usage.family.name=Create From Usage create.field.from.usage=Create Field ''{0}'' diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java index 6c849843cd12..15d5dd7af955 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java @@ -15,8 +15,8 @@ */ package org.jetbrains.plugins.groovy.annotator.intentions.dynamic; -import com.intellij.openapi.actionSystem.DataProvider; -import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.ide.DeleteProvider; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -96,7 +96,7 @@ public class DynamicToolWindowWrapper { private static final int CLASS_OR_ELEMENT_NAME_COLUMN = 0; private static final int TYPE_COLUMN = 1; - private static final String[] myColumnNames = {"Dynamic element", "Type"}; + private static final String[] myColumnNames = {"Dynamic Element", "Type"}; private MyTreeTable myTreeTable; @@ -212,6 +212,10 @@ public class DynamicToolWindowWrapper { myTreeTable = new MyTreeTable(myTreeTableModel); + DefaultActionGroup group = new DefaultActionGroup(); + group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_DELETE)); + PopupHandler.installUnknownPopupHandler(myTreeTable, group, ActionManager.getInstance()); + final MyColoredTreeCellRenderer treeCellRenderer = new MyColoredTreeCellRenderer(); myTreeTable.setDefaultRenderer(String.class, new TableCellRenderer() { @@ -342,12 +346,6 @@ public class DynamicToolWindowWrapper { myTreeTable.setDefaultEditor(String.class, typeCellEditor); - myTreeTable.registerKeyboardAction(new ActionListener() { - public void actionPerformed(ActionEvent event) { - deleteRow(); - } - }, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), JComponent.WHEN_FOCUSED); - myTreeTable.registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent event) { final int selectionRow = myTreeTable.getTree().getLeadSelectionRow(); @@ -743,6 +741,18 @@ public class DynamicToolWindowWrapper { if (element == null) return null; return element.getContainingFile(); + } else if (LangDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { + return new DeleteProvider() { + @Override + public void deleteElement(DataContext dataContext) { + deleteRow(); + } + + @Override + public boolean canDeleteElement(DataContext dataContext) { + return myTreeTable.getTree().getSelectionPaths() != null; + } + }; } return null; From 2e1156fa1c87039b5766f3e53b163f5de306cac2 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 29 Nov 2011 19:55:58 +0100 Subject: [PATCH 33/44] cleanup unused properties, fix a bit of spelling(cherry picked from commit 86c3483) --- .../plugins/groovy/GroovyBundle.properties | 13 +------------ .../dynamic/DynamicToolWindowWrapper.java | 2 +- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index d36192f763e5..8b7b70e6c566 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -253,28 +253,17 @@ Inner.methods.are.not.supported=Inner methods are not supported final.class.cannot.be.extended=Final class cannot be extended #Override and implement -goto.override.method.declaration=go to override method declaration -interface.expected.here=Interface is expected here -overrides.method.from.super=Overrides method in ''{0}'' -implements.method.from.super=Implements method in ''{0}'' -implement.methods=Implement methods -implement.methods.fix=Implement methods method.is.not.implemented=Method ''{0}'' is not implemented -interface.is.not.expected.here=Interface is not expected here change.implements.and.extends.classes=Normalize extends and implements lists -unsafe.dereference=Unsafe dereference -type.definition.can.extend.just.one.super.type=Type definition must extends not more than one class class.is.not.expected.here=Class is not expected here -interface.cannot.contain.implements.clause=Interface cannot contain implements clause fix.package.name=Fix package name #dynamic properties add.dynamic.property=Add dynamic property ''{0}'' duplicate.element.in.the.map=Duplicate element in the map -message.nothing.to.show.in.structure.view=There are no dynamic properties dynamic.toolwindow.search.elements=Search dynamic element -dynamic.toolwindow.property.fiter=Property Filter +dynamic.toolwindow.property.filter=Property Filter dynamic.tool.window.id=Dynamic Properties create.from.usage.family.name=Create From Usage diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java index 15d5dd7af955..46d8dd4b7372 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/DynamicToolWindowWrapper.java @@ -129,7 +129,7 @@ public class DynamicToolWindowWrapper { myBigPanel = new JPanel(new BorderLayout()); myBigPanel.setBackground(UIUtil.getFieldForegroundColor()); - final DynamicFilterComponent filter = new DynamicFilterComponent(GroovyBundle.message("dynamic.toolwindow.property.fiter"), 10); + final DynamicFilterComponent filter = new DynamicFilterComponent(GroovyBundle.message("dynamic.toolwindow.property.filter"), 10); filter.setBackground(UIUtil.getLabelBackground()); myBigPanel.add(new JLabel(GroovyBundle.message("dynamic.toolwindow.search.elements")), BorderLayout.NORTH); From d5b3416de06c3907274f7b27b0dcf8a65b83a0c9 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 29 Nov 2011 16:58:27 +0100 Subject: [PATCH 34/44] show full path to idea.log in error message --- .../com/intellij/openapi/application/impl/ApplicationImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 8408e01bdaf6..bd88f4e29259 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -355,7 +355,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application LOG.error(ex); @NonNls final String errorMessage = "Fatal error initializing class " + componentClassName + ":\n" + ex.toString() + - "\nComplete error stacktrace was written to idea.log"; + "\nComplete error stacktrace was written to " + PathManager.getLogPath() + "/idea.log"; if (!myHeadlessMode) { JOptionPane.showMessageDialog(null, errorMessage); } From 483e9d6ec8c96c484de0a98a6edaa3273eb144f3 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 29 Nov 2011 20:21:53 +0100 Subject: [PATCH 35/44] show full product name in new project wizard --- .../util/newProjectWizard/modes/CreateFromScratchMode.java | 5 ++--- .../util/newProjectWizard/modes/CreateFromSourcesMode.java | 2 +- .../ide/util/newProjectWizard/modes/ImportImlMode.java | 2 +- .../intellij/ide/util/newProjectWizard/modes/ImportMode.java | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java index 8bd7f5477eea..e729aeadff4b 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromScratchMode.java @@ -27,14 +27,13 @@ import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.ModuleWizardStep; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.application.ApplicationNamesInfo; +import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; -import com.intellij.openapi.module.ModuleType; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.util.HashMap; import java.util.Map; @@ -49,7 +48,7 @@ public class CreateFromScratchMode extends WizardMode { @NotNull public String getDescription(final WizardContext context) { - return ProjectBundle.message("project.new.wizard.from.scratch.description", ApplicationNamesInfo.getInstance().getProductName(), context.getPresentationName()); + return ProjectBundle.message("project.new.wizard.from.scratch.description", ApplicationNamesInfo.getInstance().getFullProductName(), context.getPresentationName()); } @Nullable diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromSourcesMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromSourcesMode.java index f4571186789c..d514b0067edc 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromSourcesMode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromSourcesMode.java @@ -52,7 +52,7 @@ public abstract class CreateFromSourcesMode extends WizardMode { @NotNull public String getDescription(final WizardContext context) { return ProjectBundle.message("project.new.wizard.from.existent.sources.description", - ApplicationNamesInfo.getInstance().getProductName(), context.getPresentationName()); + ApplicationNamesInfo.getInstance().getFullProductName(), context.getPresentationName()); } @Nullable diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/ImportImlMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/ImportImlMode.java index 34716c72a9b3..e8311c223944 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/ImportImlMode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/ImportImlMode.java @@ -52,7 +52,7 @@ public class ImportImlMode extends WizardMode { @NotNull public String getDescription(final WizardContext context) { - return IdeBundle.message("prompt.select.module.file.to.import", ApplicationNamesInfo.getInstance().getProductName()); + return IdeBundle.message("prompt.select.module.file.to.import", ApplicationNamesInfo.getInstance().getFullProductName()); } diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/ImportMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/ImportMode.java index bb7b40aec703..e00eef20309c 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/ImportMode.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/ImportMode.java @@ -48,7 +48,7 @@ public class ImportMode extends WizardMode { @NotNull public String getDescription(final WizardContext context) { - final String productName = ApplicationNamesInfo.getInstance().getProductName(); + final String productName = ApplicationNamesInfo.getInstance().getFullProductName(); return ProjectBundle.message("project.new.wizard.import.description", productName, context.getPresentationName(), StringUtil.join( Arrays.asList(Extensions.getExtensions(ProjectImportProvider.PROJECT_IMPORT_PROVIDER)), new Function() { From e51c31bbbd822b0fd917c70b3d5b3f0a6e4706b7 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 29 Nov 2011 21:53:58 +0100 Subject: [PATCH 36/44] Checkout does not need a read action (IDEA-77840) --- .../cvsCheckOut/CheckoutProjectOperation.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutProjectOperation.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutProjectOperation.java index d35ba5783311..d4bd50541bbd 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutProjectOperation.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsCheckOut/CheckoutProjectOperation.java @@ -48,10 +48,8 @@ public class CheckoutProjectOperation extends CvsCommandOperation { private final boolean myPruneEmptyDirectories; private final KeywordSubstitution myKeywordSubstitution; - public static CheckoutProjectOperation createTestInstance(CvsEnvironment env, String moduleName, File targetLocation - ) { - return CheckoutProjectOperation.create(env, new String[]{moduleName}, targetLocation, false, - false); + public static CheckoutProjectOperation createTestInstance(CvsEnvironment env, String moduleName, File targetLocation) { + return create(env, new String[]{moduleName}, targetLocation, false, false); } public CheckoutProjectOperation(String[] moduleNames, @@ -74,22 +72,20 @@ public class CheckoutProjectOperation extends CvsCommandOperation { } public static CheckoutProjectOperation create(CvsEnvironment env, - String[] moduleName, - File targetLocation, - boolean useAlternativecheckoutDir, - boolean makeNewFilesReadOnly) { + String[] moduleName, + File targetLocation, + boolean useAlternativeCheckoutDir, + boolean makeNewFilesReadOnly) { + final CvsApplicationLevelConfiguration config = CvsApplicationLevelConfiguration.getInstance(); + final KeywordSubstitutionWrapper substitution = KeywordSubstitutionWrapper.getValue(config.CHECKOUT_KEYWORD_SUBSTITUTION); - CvsApplicationLevelConfiguration config = CvsApplicationLevelConfiguration.getInstance(); - KeywordSubstitutionWrapper substitution = KeywordSubstitutionWrapper.getValue(config.CHECKOUT_KEYWORD_SUBSTITUTION); - - File root; - String directory; - - if (useAlternativecheckoutDir && targetLocation.getParentFile() == null) { + final File root; + final String directory; + if (useAlternativeCheckoutDir && targetLocation.getParentFile() == null) { root = targetLocation; directory = getModuleRootName(moduleName); } - else if (useAlternativecheckoutDir) { + else if (useAlternativeCheckoutDir) { root = targetLocation.getParentFile(); directory = targetLocation.getName(); } @@ -107,7 +103,6 @@ public class CheckoutProjectOperation extends CvsCommandOperation { substitution == null ? null : substitution.getSubstitution()); } - private static String getModuleRootName(String[] moduleNames) { File current = new File(moduleNames[0]); while (current.getParentFile() != null) current = current.getParentFile(); @@ -119,7 +114,7 @@ public class CheckoutProjectOperation extends CvsCommandOperation { } protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) { - CheckoutCommand command = new CheckoutCommand(new ThrowableRunnable() { + final CheckoutCommand command = new CheckoutCommand(new ThrowableRunnable() { public void run() throws IOCommandException { ((CheckoutAdminWriter) myAdminWriter).finish(); } @@ -155,4 +150,9 @@ public class CheckoutProjectOperation extends CvsCommandOperation { super.modifyOptions(options); options.setCheckedOutFilesReadOnly(myMakeNewFilesReadOnly); } + + @Override + public boolean runInReadThread() { + return false; + } } From 6d48a106d41b24d826945d55ae188caa002a843a Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 30 Nov 2011 00:47:28 +0100 Subject: [PATCH 37/44] Migrate CVS Root action --- .../intellij/cvsSupport2/CvsBundle.properties | 13 +- .../cvs/cvs-plugin/src/META-INF/plugin.xml | 3 +- .../actions/MigrateCvsRootAction.java | 141 +++++++++++++ .../CvsCommittedChangesProvider.java | 51 ++--- .../changeBrowser/LoadHistoryOperation.java | 35 +++- .../cvsSupport2/ui/MigrateRootDialog.java | 193 ++++++++++++++++++ 6 files changed, 394 insertions(+), 42 deletions(-) create mode 100644 plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/MigrateCvsRootAction.java create mode 100644 plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/MigrateRootDialog.java diff --git a/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties b/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties index 6ff67698f0ae..34267dfc644a 100644 --- a/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties +++ b/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties @@ -360,10 +360,12 @@ action.Cvs.Import.description=Put files into a CVS repository action.Cvs.BrowseCVSRepository.text=_Browse CVS Repository... action.Cvs.BrowseCVSRepository.description=Browse a CVS repository group.CvsGlobalGroup.text=_CVS -action.GlobalSettings.text=Global Settings... +action.GlobalSettings.text=Global CVS Settings... action.GlobalSettings.description=Configure global CVS settings action.ConfigureCvsRoots.text=Configure CVS _Roots... -action.ConfigureCvsRoots.description=Configure CVSroots +action.ConfigureCvsRoots.description=Configure CVS Roots +action.MigrateCvsRoot.text=_Migrate CVS Root... +action.MigrateCvsRoot.description=Change CVS root for selected directory and all directories below it group.CvsFilePopupGroup.text=_CVS action.Cvs.GetFromRepository.text=Get action.Cvs.GetFromRepository.description=Get from cvs repository @@ -461,4 +463,9 @@ switched.revision.format=revision {0} changelist.column.branch=Branch annotation.tooltip=Revision: {0} Date: {1}\nAuthor: {2}\n\n{3} message.password.file.does.not.exist=Password file {0} does not exist. Do you want to create it? -title.password.file.does.not.exist=Missing Password File \ No newline at end of file +title.password.file.does.not.exist=Missing Password File +migrate.cvs.root.directory.label=Migrate CVS Root under &directory: +error.message.directory.is.not.under.cvs=Directory is not under CVS +migrate.replace.if.root.equals.label=Replace if CVS root &equals {0} +migrate.replace.all.roots.label=Replace &all CVS roots +migrate.target.root.label=To the following &CVS root: \ No newline at end of file diff --git a/plugins/cvs/cvs-plugin/src/META-INF/plugin.xml b/plugins/cvs/cvs-plugin/src/META-INF/plugin.xml index ef9ac9a368ed..4861b89cee9a 100644 --- a/plugins/cvs/cvs-plugin/src/META-INF/plugin.xml +++ b/plugins/cvs/cvs-plugin/src/META-INF/plugin.xml @@ -1,7 +1,7 @@ CVS Integration CVS - 0.1 + 11 JetBrains com.intellij.cvsSupport2.CvsBundle VCS Integration @@ -57,6 +57,7 @@ + diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/MigrateCvsRootAction.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/MigrateCvsRootAction.java new file mode 100644 index 000000000000..c0ae4033ad4b --- /dev/null +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/actions/MigrateCvsRootAction.java @@ -0,0 +1,141 @@ +/* + * Copyright 2011 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.cvsSupport2.actions; + +import com.intellij.cvsSupport2.CvsUtil; +import com.intellij.cvsSupport2.actions.actionVisibility.CvsActionVisibility; +import com.intellij.cvsSupport2.actions.cvsContext.CvsContextWrapper; +import com.intellij.cvsSupport2.config.CvsRootConfiguration; +import com.intellij.cvsSupport2.ui.MigrateRootDialog; +import com.intellij.cvsSupport2.util.CvsVfsUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vcs.actions.VcsContext; +import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; +import com.intellij.openapi.vfs.VirtualFile; +import org.netbeans.lib.cvsclient.file.FileUtils; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class MigrateCvsRootAction extends AnAction { + private static final Logger LOG = Logger.getInstance("#com.intellij.cvsSupport2.actions.MigrateCvsRootAction"); + private final CvsActionVisibility myVisibility = new CvsActionVisibility(); + + public MigrateCvsRootAction() { + super(); + myVisibility.shouldNotBePerformedOnFile(); + } + + @Override + public void update(AnActionEvent e) { + myVisibility.applyToEvent(e); + } + + @Override + public void actionPerformed(AnActionEvent event) { + final VcsContext context = CvsContextWrapper.createInstance(event); + final VirtualFile selectedFile = context.getSelectedFile(); + final MigrateRootDialog dialog = new MigrateRootDialog(context.getProject(), selectedFile); + dialog.show(); + if (!dialog.isOK()) return; + final File directory = dialog.getSelectedDirectory(); + final boolean shouldReplaceAllRoots = dialog.shouldReplaceAllRoots(); + final List rootFiles = new ArrayList(); + try { + if (shouldReplaceAllRoots) { + collectRootFiles(directory, null, rootFiles); + } else { + collectRootFiles(directory, dialog.getCvsRoot(), rootFiles); + } + } catch (IOException e) { + LOG.error(e); + return; + } + final CvsRootConfiguration cvsConfiguration = dialog.getSelectedCvsConfiguration(); + final String cvsRoot = cvsConfiguration.getCvsRootAsString(); + for (final File file : rootFiles) { + try { + FileUtils.writeLine(file, cvsRoot); + } + catch (IOException e) { + LOG.error(e); + break; + } + } + final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock(); + try { + final VcsDirtyScopeManager dirty = VcsDirtyScopeManager.getInstance(context.getProject()); + for (File file : rootFiles) { + dirty.fileDirty(CvsVfsUtil.findFileByIoFile(file)); + } + CvsVfsUtil.findFileByIoFile(directory).refresh(false, true); + } finally { + token.finish(); + } + } + + + + private static void collectRootFiles(File directory, final String root, final List rootFiles) throws IOException { + final File rootFile = getRootFile(directory); + if (rootFile != null) { + rootFiles.add(rootFile); + } + try { + final File[] files = directory.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + if (!file.isDirectory()) { + return false; + } + final File rootFile = getRootFile(file); + if (!rootFile.exists()) { + return false; + } + if (root == null) { + return true; + } + try { + final String cvsRoot = FileUtils.readLineFromFile(rootFile).trim(); + return root.equals(cvsRoot); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + for (File file : files) { + collectRootFiles(file, root, rootFiles); + } + } catch (RuntimeException e) { + final Throwable cause = e.getCause(); + if (cause instanceof IOException) { + throw (IOException) cause; + } + } + } + + private static File getRootFile(File directory) { + return new File(directory, CvsUtil.CVS + '/' + CvsUtil.CVS_ROOT_FILE); + } +} diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/CvsCommittedChangesProvider.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/CvsCommittedChangesProvider.java index e79044eae769..034575f4c939 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/CvsCommittedChangesProvider.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/CvsCommittedChangesProvider.java @@ -19,10 +19,10 @@ import com.intellij.CvsBundle; import com.intellij.cvsSupport2.CvsUtil; import com.intellij.cvsSupport2.application.CvsEntriesManager; import com.intellij.cvsSupport2.connections.CvsEnvironment; -import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutor; -import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutorCallback; -import com.intellij.cvsSupport2.cvshandlers.CommandCvsHandler; +import com.intellij.cvsSupport2.connections.CvsRootOnFileSystem; +import com.intellij.cvsSupport2.errorHandling.CannotFindCvsRootException; import com.intellij.cvsSupport2.history.CvsRevisionNumber; +import com.intellij.cvsSupport2.util.CvsVfsUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.cvsIntegration.CvsResult; import com.intellij.openapi.diagnostic.Logger; @@ -42,7 +42,6 @@ import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.AsynchConsumer; import com.intellij.util.Consumer; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.netbeans.lib.cvsclient.admin.Entry; @@ -50,7 +49,6 @@ import org.netbeans.lib.cvsclient.command.log.Revision; import java.io.DataInput; import java.io.DataOutput; -import java.io.File; import java.io.IOException; import java.util.*; @@ -63,8 +61,6 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi private final Project myProject; private final MyZipper myZipper; - @NonNls private static final String INVALID_OPTION_S = "invalid option -- S"; - public CvsCommittedChangesProvider(Project project) { myProject = project; myZipper = new MyZipper(); @@ -137,8 +133,7 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi @Nullable @Override public Pair getOneList(VirtualFile file, final VcsRevisionNumber number) throws VcsException { - final File ioFile = new File(file.getPath()); - final FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(ioFile); + final FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file); final VirtualFile vcsRoot = ProjectLevelVcsManager.getInstance(myProject).getVcsRootFor(filePath); final CvsRepositoryLocation cvsLocation = getLocationFor(filePath); if (cvsLocation == null) return null; @@ -158,7 +153,7 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi result[0] = builder.addRevision(revision); } }, cvsLocation.getModuleName(), number.asString()); - final CvsResult executionResult = runRLogOperation(operation); + final CvsResult executionResult = operation.run(myProject); if (executionResult.isCanceled()) { throw new ProcessCanceledException(); @@ -191,7 +186,7 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi } } }); - final CvsResult cvsResult = runRLogOperation(operation2); + final CvsResult cvsResult = operation2.run(myProject); if (cvsResult.hasErrors()) { throw cvsResult.composeError(); } @@ -243,7 +238,7 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi } } }); - final CvsResult executionResult = runRLogOperation(operation); + final CvsResult executionResult = operation.run(myProject); if (executionResult.isCanceled()) { throw new ProcessCanceledException(); @@ -259,11 +254,17 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi private List loadCommittedChanges(final ChangeBrowserSettings settings, final String module, - final CvsEnvironment connectionSettings, + CvsEnvironment connectionSettings, final VirtualFile rootFile) throws VcsException { if (connectionSettings.isOffline()) { return Collections.emptyList(); } + try { + // refresh cvs connection settings from file system + connectionSettings = CvsRootOnFileSystem.createMeOn(CvsVfsUtil.getFileFor(rootFile)); + } + catch (CannotFindCvsRootException ignore) { + } final CvsChangeListsBuilder builder = new CvsChangeListsBuilder(module, connectionSettings, myProject, rootFile); Date dateTo = settings.getDateBeforeFilter(); Date dateFrom = settings.getDateAfterFilter(); @@ -280,7 +281,7 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi log.add(logInformationWrapper); } }); - final CvsResult executionResult = runRLogOperation(operation); + final CvsResult executionResult = operation.run(myProject); if (executionResult.isCanceled()) { throw new ProcessCanceledException(); @@ -296,28 +297,6 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi } } - private CvsResult runRLogOperation(final LoadHistoryOperation operation) { - final CvsResult executionResult = runRLogOperationImpl(operation); - - for (VcsException error : executionResult.getErrors()) { - for (String message : error.getMessages()) { - if (message.contains(INVALID_OPTION_S)) { - operation.disableSuppressEmptyHeadersForCurrentCvsRoot(); - // try only once - return runRLogOperationImpl(operation); - } - } - } - return executionResult; - } - - private CvsResult runRLogOperationImpl(final LoadHistoryOperation operation) { - final CvsOperationExecutor executor = new CvsOperationExecutor(myProject); - executor.performActionSync(new CommandCvsHandler(CvsBundle.message("browse.changes.load.history.progress.title"), operation), - CvsOperationExecutorCallback.EMPTY); - return executor.getResult(); - } - public int getFormatVersion() { return 3; } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/LoadHistoryOperation.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/LoadHistoryOperation.java index bcf677ab7add..bef7e0f96ef6 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/LoadHistoryOperation.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/LoadHistoryOperation.java @@ -15,11 +15,18 @@ */ package com.intellij.cvsSupport2.changeBrowser; +import com.intellij.CvsBundle; import com.intellij.cvsSupport2.connections.CvsEnvironment; import com.intellij.cvsSupport2.connections.CvsRootProvider; +import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutor; +import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutorCallback; +import com.intellij.cvsSupport2.cvshandlers.CommandCvsHandler; import com.intellij.cvsSupport2.cvsoperations.common.CvsExecutionEnvironment; import com.intellij.cvsSupport2.cvsoperations.common.LocalPathIndifferentOperation; import com.intellij.cvsSupport2.cvsoperations.cvsLog.RlogCommand; +import com.intellij.openapi.cvsIntegration.CvsResult; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.VcsException; import com.intellij.util.Consumer; import com.intellij.util.text.SyncDateFormat; import org.jetbrains.annotations.NonNls; @@ -36,6 +43,7 @@ import java.util.Locale; public class LoadHistoryOperation extends LocalPathIndifferentOperation { + @NonNls private static final String INVALID_OPTION_S = "invalid option -- S"; @NonNls private static final SyncDateFormat DATE_FORMAT = new SyncDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ", Locale.US)); private static final Collection ourDoNotSupportingSOptionServers = new HashSet(); @@ -46,7 +54,8 @@ public class LoadHistoryOperation extends LocalPathIndifferentOperation { private final String[] myRevisions; private final boolean myNoTags; - public LoadHistoryOperation(CvsEnvironment environment, String module, + public LoadHistoryOperation(CvsEnvironment environment, + String module, @Nullable Date dateFrom, @Nullable Date dateTo, @NotNull final Consumer consumer) { @@ -93,7 +102,7 @@ public class LoadHistoryOperation extends LocalPathIndifferentOperation { return command; } - public void disableSuppressEmptyHeadersForCurrentCvsRoot() { + private void disableSuppressEmptyHeadersForCurrentCvsRoot() { ourDoNotSupportingSOptionServers.add(myEnvironment.getCvsRootAsString()); } @@ -122,4 +131,26 @@ public class LoadHistoryOperation extends LocalPathIndifferentOperation { protected boolean runInExclusiveLock() { return false; } + + public CvsResult run(Project project) { + final CvsResult executionResult = internalRun(project); + + for (VcsException error : executionResult.getErrors()) { + for (String message : error.getMessages()) { + if (message.contains(INVALID_OPTION_S)) { + disableSuppressEmptyHeadersForCurrentCvsRoot(); + // try only once + return internalRun(project); + } + } + } + return executionResult; + } + + private CvsResult internalRun(Project project) { + final CvsOperationExecutor executor = new CvsOperationExecutor(project); + executor.performActionSync(new CommandCvsHandler(CvsBundle.message("browse.changes.load.history.progress.title"), this), + CvsOperationExecutorCallback.EMPTY); + return executor.getResult(); + } } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/MigrateRootDialog.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/MigrateRootDialog.java new file mode 100644 index 000000000000..5836be3db99f --- /dev/null +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/MigrateRootDialog.java @@ -0,0 +1,193 @@ +/* + * Copyright 2011 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.cvsSupport2.ui; + +import com.intellij.CvsBundle; +import com.intellij.cvsSupport2.CvsUtil; +import com.intellij.cvsSupport2.config.CvsRootConfiguration; +import com.intellij.cvsSupport2.config.ui.SelectCvsConfigurationPanel; +import com.intellij.cvsSupport2.util.CvsVfsUtil; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserFactory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.VirtualFile; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.io.File; + +public class MigrateRootDialog extends DialogWrapper { + + private final JRadioButton myRadioButton1; + private final JRadioButton myRadioButton2 = new JRadioButton(CvsBundle.message("migrate.replace.all.roots.label")); + private final TextFieldWithBrowseButton myDirectoryField = new TextFieldWithBrowseButton(); + private final SelectCvsConfigurationPanel myCvsConfigurationPanel; + private ListSelectionListener myListener; + private String myCvsRoot; + + public MigrateRootDialog(Project project, VirtualFile directory) { + super(project); + setTitle("Migrate CVS Root"); + final File file = CvsVfsUtil.getFileFor(directory); + final String root = CvsUtil.loadRootFrom(file); + myRadioButton1 = new JRadioButton(CvsBundle.message("migrate.replace.if.root.equals.label", root)); + myRadioButton1.setSelected(true); + final ButtonGroup group = new ButtonGroup(); + group.add(myRadioButton1); + group.add(myRadioButton2); + myDirectoryField.setText(directory.getPath()); + final FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, false, false, false, false) { + @Override + public void validateSelectedFiles(VirtualFile[] files) throws Exception { + for (VirtualFile vFile : files) { + final File file = CvsVfsUtil.getFileFor(vFile); + final String root = CvsUtil.loadRootFrom(file); + if (root == null) { + throw new Exception(CvsBundle.message("error.message.directory.is.not.under.cvs")); + } + } + } + }; + final VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRootsFromAllModules(); + for (VirtualFile vFile : roots) { + descriptor.addRoot(vFile); + } + myDirectoryField.addBrowseFolderListener("Select directory to migrate to a new CVS root", "", project, descriptor); + FileChooserFactory.getInstance().installFileCompletion(myDirectoryField.getChildComponent(), descriptor, true, getDisposable()); + myDirectoryField.getTextField().getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + enableOKActionConditionally(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + enableOKActionConditionally(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + enableOKActionConditionally(); + } + }); + myCvsConfigurationPanel = new SelectCvsConfigurationPanel(project); + if (SystemInfo.isMac) { + myCvsConfigurationPanel.setBorder(new EmptyBorder(2, 3, 2, 0)); + } + myListener = new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + enableOKActionConditionally(); + } + }; + myCvsConfigurationPanel.addListSelectionListener(myListener); + setOKButtonText("Migrate"); + init(); + } + + @Override + protected JComponent createCenterPanel() { + final JPanel panel = new JPanel(new GridBagLayout()); + final GridBagConstraints constraints = new GridBagConstraints(); + constraints.gridx = 0; + constraints.gridy = 0; + constraints.insets.bottom = 2; + constraints.weightx = 1.0; + constraints.fill = GridBagConstraints.HORIZONTAL; + constraints.anchor = GridBagConstraints.LINE_START; + final JLabel label1 = new JLabel(CvsBundle.message("migrate.cvs.root.directory.label")); + label1.setLabelFor(myDirectoryField); + panel.add(label1, constraints); + constraints.gridy = 1; + panel.add(myDirectoryField, constraints); + + constraints.gridy = 2; + constraints.insets.left = 5; + panel.add(myRadioButton1, constraints); + constraints.gridy = 3; + panel.add(myRadioButton2, constraints); + + constraints.gridy = 4; + constraints.insets.top = 8; + constraints.insets.left = 0; + final JLabel label2 = new JLabel(CvsBundle.message("migrate.target.root.label")); + panel.add(label2, constraints); + + final JComponent component = myCvsConfigurationPanel.getPreferredFocusedComponent(); + label2.setLabelFor(component); + constraints.insets.top = 0; + constraints.gridy = 5; + panel.add(myCvsConfigurationPanel, constraints); + return panel; + } + + private boolean check() { + final String text = myDirectoryField.getText(); + final File file = new File(text); + if (!file.exists() || !file.isDirectory()) { + return false; + } + myCvsRoot = CvsUtil.loadRootFrom(file); + if (myCvsRoot == null) { + return false; + } + myRadioButton1.setText(CvsBundle.message("migrate.replace.if.root.equals.label", myCvsRoot)); + if (getSelectedCvsConfiguration() == null) { + return false; + } + return true; + } + + @Override + protected void dispose() { + myCvsConfigurationPanel.removeListSelectionListener(myListener); + super.dispose(); + } + + private void enableOKActionConditionally() { + setOKActionEnabled(check()); + } + + public String getCvsRoot() { + return myCvsRoot; + } + + @Override + public JComponent getPreferredFocusedComponent() { + return myCvsConfigurationPanel; + } + + public CvsRootConfiguration getSelectedCvsConfiguration() { + return myCvsConfigurationPanel.getSelectedConfiguration(); + } + + public File getSelectedDirectory() { + return new File(myDirectoryField.getText()); + } + + public boolean shouldReplaceAllRoots() { + return myRadioButton2.isSelected(); + } +} From 6a561ab3b5bd0e1c8509e8ffd6bce948225c205e Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 30 Nov 2011 13:46:18 +0400 Subject: [PATCH 38/44] IDEA-77009: Project structure validation: escape XML chars [rev by Dmitry A.] --- .../projectRoot/daemon/LibraryProjectStructureElement.java | 4 ++-- .../projectRoot/daemon/ModuleProjectStructureElement.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java index 200e95e3d30d..1efe1a27247b 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java @@ -72,7 +72,7 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { private static String createInvalidRootsDescription(List invalidClasses, String rootName, String libraryName) { StringBuilder buffer = new StringBuilder(); buffer.append(""); - buffer.append("Library '").append(libraryName).append("' has broken " + rootName + " " + StringUtil.pluralize("path", invalidClasses.size()) + ":"); + buffer.append("Library '").append(StringUtil.escapeXml(libraryName)).append("' has broken " + rootName + " " + StringUtil.pluralize("path", invalidClasses.size()) + ":"); for (String url : invalidClasses) { buffer.append("
  "); buffer.append(PathUtil.toPresentableUrl(url)); @@ -129,7 +129,7 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { @Override public ProjectStructureProblemDescription createUnusedElementWarning() { final List fixes = Arrays.asList(new AddLibraryToDependenciesFix(), new RemoveLibraryFix()); - return new ProjectStructureProblemDescription(getPresentableName() + " is not used", null, createPlace(), + return new ProjectStructureProblemDescription("Library '" + StringUtil.escapeXml(myLibrary.getName()) + "'" + " is not used", null, createPlace(), ProjectStructureProblemType.unused("unused-library"), ProjectStructureProblemDescription.ProblemLevel.PROJECT, fixes, false); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java index 22f4752597c5..6f3b39a5893c 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java @@ -10,6 +10,7 @@ import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.ModuleEditor; import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; @@ -57,7 +58,7 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { null); } else { - problemsHolder.registerProblem(ProjectBundle.message("project.roots.library.problem.message", entry.getPresentableName()), null, + problemsHolder.registerProblem(ProjectBundle.message("project.roots.library.problem.message", StringUtil.escapeXml(entry.getPresentableName())), null, ProjectStructureProblemType.error("invalid-module-dependency"), createPlace(entry), null); } From 03832fb026b83fe85bd3f70ce1069bcc39d5934e Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 30 Nov 2011 13:46:40 +0400 Subject: [PATCH 39/44] EA-32231 - NPE: XDebugSessionImpl$.run [rev by Dmitry A.] --- .../src/com/intellij/xdebugger/impl/XDebugSessionImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index 6e61a80398c2..e11978e3d91e 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -438,7 +438,9 @@ public class XDebugSessionImpl implements XDebugSession { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - mySessionTab.getUi().clearAttractionBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION); + if (mySessionTab != null) { + mySessionTab.getUi().clearAttractionBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION); + } } }); myDispatcher.getMulticaster().sessionResumed(); From bbea4c78847aa16477ad99db0ca4c60164bc7e2c Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Wed, 30 Nov 2011 14:05:52 +0400 Subject: [PATCH 40/44] fix stub mismatch problem (caused by index being used noncommitted document for indexing that has the same document stamp as committed one) --- .../intellij/util/indexing/FileBasedIndex.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java index 37e3f6dc0c90..7bb4ac18757f 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java @@ -165,6 +165,7 @@ public class FileBasedIndex implements ApplicationComponent { synchronized (myTransactionMap) { myTransactionMap.remove(doc); } + incTransactionCount(doc); } }); @@ -1234,7 +1235,8 @@ public class FileBasedIndex implements ApplicationComponent { content = new AuthenticContent(document); } - final long currentDocStamp = content.getModificationStamp(); + final long currentDocStamp = content.getModificationStamp() + + getTransactionCount(document); // we add transaction count in order to deal with committed status if (currentDocStamp != myLastIndexedDocStamps.getAndSet(document, requestedIndexId, currentDocStamp)) { final Ref exRef = new Ref(null); ProgressManager.getInstance().executeNonCancelableSection(new Runnable() { @@ -1280,6 +1282,18 @@ public class FileBasedIndex implements ApplicationComponent { return true; } + public static final Key TRANSACTION_COUNT = new Key("Transaction count"); + + private long getTransactionCount(@NotNull Document document) { + Integer data = document.getUserData(TRANSACTION_COUNT); + return data != null ? data : 0; + } + + private void incTransactionCount(@NotNull Document document) { + Integer data = document.getUserData(TRANSACTION_COUNT); + document.putUserData(TRANSACTION_COUNT, (data != null ? data : 0) + 1); + } + public static final Key EDITOR_HIGHLIGHTER = new Key("Editor"); @Nullable From 3d55e6c38184840c9db550880d6606899d6a8144 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Wed, 30 Nov 2011 11:16:31 +0100 Subject: [PATCH 41/44] IDEA-77658 XSLT debug: breakpoint in xsl:sequence inside xsl:function is not hit --- .../local/saxon9/Saxon9TraceListener.java | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9TraceListener.java b/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9TraceListener.java index a50e0e4d5e4c..92e15e790085 100644 --- a/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9TraceListener.java +++ b/plugins/xslt-debugger/engine/impl/src/org/intellij/plugins/xsltDebugger/rt/engine/local/saxon9/Saxon9TraceListener.java @@ -17,13 +17,20 @@ package org.intellij.plugins.xsltDebugger.rt.engine.local.saxon9; import net.sf.saxon.expr.XPathContext; +import net.sf.saxon.expr.instruct.InstructionDetails; import net.sf.saxon.lib.TraceListener; import net.sf.saxon.om.Item; import net.sf.saxon.om.NodeInfo; import net.sf.saxon.style.StyleElement; import net.sf.saxon.trace.InstructionInfo; +import org.intellij.plugins.xsltDebugger.rt.engine.Debugger; +import org.intellij.plugins.xsltDebugger.rt.engine.Value; import org.intellij.plugins.xsltDebugger.rt.engine.local.LocalDebugger; +import javax.xml.transform.Source; +import javax.xml.transform.SourceLocator; +import java.util.List; + public class Saxon9TraceListener implements TraceListener { private static final boolean TRACE = "true".equals(System.getProperty("xslt.debugger.trace", "false")); @@ -63,6 +70,8 @@ public class Saxon9TraceListener implements TraceListener { } if (instructionInfo instanceof StyleElement) { myDebugger.enter(new Saxon9StyleFrame(myDebugger.getCurrentFrame(), (StyleElement)instructionInfo, xPathContext)); + } else if (instructionInfo instanceof InstructionDetails) { + myDebugger.enter(new VirtualFrame(myDebugger.getCurrentFrame(), (InstructionDetails)instructionInfo)); } } @@ -70,7 +79,7 @@ public class Saxon9TraceListener implements TraceListener { if (TRACE) { trace(""); } - if (instructionInfo instanceof StyleElement) { + if (instructionInfo instanceof StyleElement || instructionInfo instanceof InstructionDetails) { myDebugger.leave(); } } @@ -89,4 +98,58 @@ public class Saxon9TraceListener implements TraceListener { myDebugger.popSource(); } } + + private static class VirtualFrame extends AbstractSaxon9Frame implements Debugger.StyleFrame { + + public VirtualFrame(Debugger.StyleFrame previous, InstructionDetails instr) { + super(previous, new MySource(instr)); + } + + @Override + public String getInstruction() { + return getPrevious().getInstruction(); + } + + @Override + public Value eval(String expr) throws Debugger.EvaluationException { + return getPrevious().eval(expr); + } + + @Override + public List getVariables() { + return getPrevious().getVariables(); + } + + private static class MySource implements Source, SourceLocator { + private final InstructionDetails myInstruction; + + public MySource(InstructionDetails instr) { + myInstruction = instr; + } + + @Override + public void setSystemId(String systemId) { + } + + @Override + public String getPublicId() { + return null; + } + + @Override + public String getSystemId() { + return myInstruction.getSystemId(); + } + + @Override + public int getLineNumber() { + return myInstruction.getLineNumber(); + } + + @Override + public int getColumnNumber() { + return myInstruction.getColumnNumber(); + } + } + } } \ No newline at end of file From 000dafef904dd076a26be873bce932cb7a653970 Mon Sep 17 00:00:00 2001 From: Sascha Weinreuter Date: Wed, 30 Nov 2011 11:42:40 +0100 Subject: [PATCH 42/44] IDEA-72630: XSLT debug: setting breakpoint just after session completion causes irrelevant message or DSE at RemoteDebuggerClient.handleRemoteException() --- .../plugins/xsltDebugger/impl/XsltBreakpointHandler.java | 3 +++ .../plugins/xsltDebugger/impl/XsltDebugProcess.java | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java index ce001241ad72..a54fe614017b 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltBreakpointHandler.java @@ -23,6 +23,7 @@ import org.intellij.plugins.xsltDebugger.VMPausedException; import org.intellij.plugins.xsltDebugger.XsltBreakpointType; import org.intellij.plugins.xsltDebugger.rt.engine.Breakpoint; import org.intellij.plugins.xsltDebugger.rt.engine.BreakpointManager; +import org.intellij.plugins.xsltDebugger.rt.engine.DebuggerStoppedException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -61,6 +62,7 @@ public class XsltBreakpointHandler extends XBreakpointHandler Date: Wed, 30 Nov 2011 11:42:45 +0100 Subject: [PATCH 43/44] Maven: invalidate dom element descriptors on psi changes (tests fixed) --- .../idea/maven/dom/MavenDomElementDescriptorHolder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomElementDescriptorHolder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomElementDescriptorHolder.java index 9a72ca519824..5f4cf19f3724 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomElementDescriptorHolder.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomElementDescriptorHolder.java @@ -99,7 +99,7 @@ public class MavenDomElementDescriptorHolder { public Result compute() { return Result.create(doCreateDescriptor(kind), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); } - }); + }, false); myDescriptorsMap.put(kind, result); } return result.getValue(); From fb2856b7765265409662017df3ef152c16f6d613 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 30 Nov 2011 15:23:20 +0300 Subject: [PATCH 44/44] GitPushLog: display hash, date, author and full description in a tooltip, remove hash and date from the list. --- .../src/git4idea/push/GitPushLog.java | 82 +++++++------------ 1 file changed, 29 insertions(+), 53 deletions(-) diff --git a/plugins/git4idea/src/git4idea/push/GitPushLog.java b/plugins/git4idea/src/git4idea/push/GitPushLog.java index 997440bb2ca0..94486217b1b0 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushLog.java +++ b/plugins/git4idea/src/git4idea/push/GitPushLog.java @@ -43,6 +43,7 @@ import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.*; import java.awt.*; +import java.awt.event.MouseEvent; import java.io.File; import java.util.*; import java.util.List; @@ -83,8 +84,21 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { } @Override - public boolean getScrollableTracksViewportWidth() { - return false; + public String getToolTipText(MouseEvent event) { + final TreePath path = myTree.getPathForLocation(event.getX(), event.getY()); + if (path == null) { + return ""; + } + Object node = path.getLastPathComponent(); + if (node == null || (!(node instanceof DefaultMutableTreeNode))) { + return ""; + } + Object userObject = ((DefaultMutableTreeNode)node).getUserObject(); + if (userObject instanceof GitCommit) { + GitCommit commit = (GitCommit)userObject; + return getHashString(commit) + " " + getDateString(commit) + " by " + commit.getAuthor() + "\n\n" + commit.getDescription(); + } + return ""; } }; myTree.setRootVisible(false); @@ -107,7 +121,7 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { myChangesBrowser.setChangesToDisplay(Collections.emptyList()); } }); - + ToolTipManager.sharedInstance().registerComponent(myTree); myChangesBrowser = new ChangesBrowser(project, null, Collections.emptyList(), null, false, true, null, ChangesBrowser.MyUseCase.LOCAL_CHANGES, null); myChangesBrowser.getDiffAction().registerCustomShortcutSet(CommonShortcuts.getDiff(), myTree); @@ -152,7 +166,6 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { createNodes(commits); myTreeModel.nodeStructureChanged(myRootNode); myTree.setModel(myTreeModel); // TODO: why doesn't it repaint otherwise? - myTreeCellRenderer.recalculateWidth(commits.getAllCommits()); TreeUtil.expandAll(myTree); selectFirstCommit(); } @@ -271,45 +284,17 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { } } + @NotNull + private static String getDateString(@NotNull GitCommit commit) { + return DateFormatUtil.formatPrettyDateTime(commit.getAuthorTime()) + " "; + } + + @NotNull + private static String getHashString(@NotNull GitCommit commit) { + return commit.getShortHash().toString(); + } + private static class MyTreeCellRenderer extends CheckboxTree.CheckboxTreeCellRenderer { - - private int myDateMaxWidth; - private int myHashMaxWidth; - private static final int INSET = UIUtil.DEFAULT_HGAP; - - void recalculateWidth(@NotNull Collection commits) { - for (GitCommit commit : commits) { - int dateLen = calcWidth(getDateString(commit)); - if (dateLen > myDateMaxWidth) { - myDateMaxWidth = dateLen; - } - int hashLen = calcWidth(getHashString(commit)); - if (hashLen > myHashMaxWidth) { - myHashMaxWidth = hashLen; - } - } - } - - @NotNull - private static String getHashString(@NotNull GitCommit commit) { - return commit.getShortHash().toString(); - } - - int calcWidth(String s) { - SimpleTextAttributes attributes = new SimpleTextAttributes(getCommitTextAttributesStyle(), getTextRenderer().getForeground()); - Font initialFont = getTextRenderer().getFont(); - Font font = initialFont.deriveFont(attributes.getFontStyle(), attributes.isSmaller() ? UIUtil.getFontSize(UIUtil.FontSize.SMALL) : initialFont.getSize()); - FontMetrics metrics = getTextRenderer().getFontMetrics(font); - return metrics.stringWidth(s); - } - - private static int getCommitTextAttributesStyle() { - return SimpleTextAttributes.STYLE_SMALLER; - } - - private static String getDateString(GitCommit commit) { - return DateFormatUtil.formatPrettyDateTime(commit.getAuthorTime()) + " "; - } @Override public void customizeRenderer(final JTree tree, final Object value, final boolean selected, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) { @@ -325,17 +310,8 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider { ColoredTreeCellRenderer renderer = getTextRenderer(); if (userObject instanceof GitCommit) { GitCommit commit = (GitCommit)userObject; - SimpleTextAttributes grey = new SimpleTextAttributes(getCommitTextAttributesStyle(), UIUtil.getInactiveTextColor()); - - String hash = getHashString(commit); - renderer.append(hash, grey); - renderer.appendAlign(myHashMaxWidth + INSET); - - String date = getDateString(commit); - renderer.append(date, grey); - renderer.appendAlign(myDateMaxWidth + myHashMaxWidth + INSET * 2); - - renderer.append(commit.getSubject(), new SimpleTextAttributes(getCommitTextAttributesStyle(), getTextRenderer().getForeground())); + renderer.append(commit.getSubject(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, getTextRenderer().getForeground())); + renderer.setToolTipText(getHashString(commit) + " " + getDateString(commit)); } else if (userObject instanceof GitRepository) { String repositoryPath = calcRootPath((GitRepository)userObject);