mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+1
-1
@@ -258,7 +258,7 @@
|
||||
<inspection_tool class="HardcodedActionUrl" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="HardwiredNamespacePrefix" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="IOResource" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredTypesString" value="java.io.ByteArrayOutputStream,java.io.ByteArrayInputStream,java.io.StringBufferInputStream,java.io.CharArrayWriter,java.io.CharArrayReader,java.io.StringWriter,java.io.StringReader" />
|
||||
<option name="ignoredTypesString" value="java.io.ByteArrayOutputStream,java.io.ByteArrayInputStream,java.io.StringBufferInputStream,java.io.CharArrayWriter,java.io.CharArrayReader,java.io.StringWriter,java.io.StringReader,io.netty.buffer.ByteBufOutputStream" />
|
||||
<option name="insideTryAllowed" value="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="IfStatementWithIdenticalBranches" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
|
||||
@@ -194,7 +194,7 @@ LD_LIBRARY_PATH="$IDE_BIN_HOME:$LD_LIBRARY_PATH" "$JAVA_BIN" \
|
||||
EC=$?
|
||||
test $EC -ne 88 && exit $EC
|
||||
if [ -x "$HOME/.@@system_selector@@/restart/restarter.sh" ]; then
|
||||
$HOME/.@@system_selector@@/restart/restarter.sh
|
||||
"$HOME/.@@system_selector@@/restart/restarter.sh"
|
||||
"$RM" -f "$HOME/.@@system_selector@@/restart/restarter.sh"
|
||||
fi
|
||||
exec "$0" "$@"
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
<isset property="build" />
|
||||
</condition>
|
||||
|
||||
<condition property="test.patterns" value="${testpatterns}"
|
||||
else="org.jetbrains.android.*;com.android.tools.idea.*;com.google.gct.*;com.intellij.android.*">
|
||||
<condition property="test.patterns" value="${testpatterns}" else="">
|
||||
<isset property="testpatterns" />
|
||||
</condition>
|
||||
|
||||
@@ -42,15 +41,15 @@
|
||||
<sequential>
|
||||
<java failonerror="true" jar="${project.home}/lib/ant/lib/ant-launcher.jar" fork="true">
|
||||
<jvmarg line="-Xmx612m -XX:MaxPermSize=152m"/>
|
||||
<jvmarg value="-Djna.nosys=true" />
|
||||
<jvmarg value="-Dout=${out.dir}" />
|
||||
<jvmarg value="-DbuildNumber=${build.number}" />
|
||||
<jvmarg value="-Didea.test.patterns=${test.patterns}" />
|
||||
<jvmarg value="-Dproduct=${product.name}" />
|
||||
<sysproperty key="jna.nosys" value="true" />
|
||||
<sysproperty key="out" value="${out.dir}" />
|
||||
<sysproperty key="buildNumber" value="${build.number}" />
|
||||
<sysproperty key="idea.test.patterns" value="${test.patterns}" />
|
||||
<sysproperty key="product" value="${product.name}" />
|
||||
<sysproperty key="java.awt.headless" value="true"/>
|
||||
<arg line=""-Dgant.script=@{script}""/>
|
||||
<arg line=""-Dteamcity.build.tempDir=${tmp.dir}""/>
|
||||
<arg line=""-Didea.test.group=ALL_EXCLUDE_DEFINED""/>
|
||||
<sysproperty key="gant.script" value="@{script}"/>
|
||||
<sysproperty key="teamcity.build.tempDir" value="${tmp.dir}"/>
|
||||
<sysproperty key="idea.test.group" value="ALL_EXCLUDE_DEFINED"/>
|
||||
<arg value="-f"/>
|
||||
<arg value="${project.home}/build/gant.xml"/>
|
||||
</java>
|
||||
|
||||
@@ -158,7 +158,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
myDebugProcessDispatcher.addListener(new DebugProcessAdapter() {
|
||||
@Override
|
||||
public void paused(SuspendContext suspendContext) {
|
||||
myThreadBlockedMonitor.stopWatching(suspendContext.getThread());
|
||||
myThreadBlockedMonitor.stopWatching(
|
||||
suspendContext.getSuspendPolicy() != EventRequest.SUSPEND_ALL ? suspendContext.getThread() : null);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2143,6 +2144,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
// }
|
||||
//}
|
||||
|
||||
@NotNull
|
||||
public DebuggerContextImpl getDebuggerContext() {
|
||||
return mySession.getContextManager().getContext();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.SingleAlarm;
|
||||
@@ -42,6 +43,8 @@ import java.util.HashSet;
|
||||
* @author egor
|
||||
*/
|
||||
public class ThreadBlockedMonitor {
|
||||
private static final Logger LOG = Logger.getInstance(ThreadBlockedMonitor.class);
|
||||
|
||||
private final Collection<ThreadReferenceProxy> myWatchedThreads = new HashSet<ThreadReferenceProxy>();
|
||||
|
||||
private final SingleAlarm myAlarm;
|
||||
@@ -71,14 +74,17 @@ public class ThreadBlockedMonitor {
|
||||
if (thread != null) {
|
||||
myWatchedThreads.remove(thread);
|
||||
}
|
||||
else {
|
||||
myWatchedThreads.clear();
|
||||
}
|
||||
if (myWatchedThreads.isEmpty()) {
|
||||
myAlarm.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void onThreadBlocked(@NotNull final ThreadReference blockedThread,
|
||||
@NotNull final ThreadReference blockingThread,
|
||||
final DebugProcessImpl process) {
|
||||
private static void onThreadBlocked(@NotNull final ThreadReference blockedThread,
|
||||
@NotNull final ThreadReference blockingThread,
|
||||
final DebugProcessImpl process) {
|
||||
XDebugSessionImpl.NOTIFICATION_GROUP.createNotification(
|
||||
DebuggerBundle.message("status.thread.blocked.by", blockedThread.name(), blockingThread.name()),
|
||||
DebuggerBundle.message("status.thread.blocked.by.resume", blockingThread.name()),
|
||||
@@ -101,6 +107,11 @@ public class ThreadBlockedMonitor {
|
||||
}).notify(process.getProject());
|
||||
}
|
||||
|
||||
private ThreadReference getCurrentThread() {
|
||||
ThreadReferenceProxyImpl threadProxy = myProcess.getDebuggerContext().getThreadProxy();
|
||||
return threadProxy != null ? threadProxy.getThreadReference() : null;
|
||||
}
|
||||
|
||||
private void checkBlockingThread() {
|
||||
myProcess.getManagerThread().schedule(new DebuggerCommandImpl() {
|
||||
@Override
|
||||
@@ -115,14 +126,16 @@ public class ThreadBlockedMonitor {
|
||||
vmProxy.canGetCurrentContendedMonitor() ? thread.getThreadReference().currentContendedMonitor() : null;
|
||||
if (waitedMonitor != null && vmProxy.canGetMonitorInfo()) {
|
||||
ThreadReference blockingThread = waitedMonitor.owningThread();
|
||||
if (blockingThread != null) {
|
||||
if (blockingThread != null
|
||||
&& blockingThread.suspendCount() > 1
|
||||
&& getCurrentThread() != blockingThread) {
|
||||
onThreadBlocked(thread.getThreadReference(), blockingThread, myProcess);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IncompatibleThreadStateException e) {
|
||||
e.printStackTrace();
|
||||
LOG.info(e);
|
||||
}
|
||||
finally {
|
||||
vmProxy.getVirtualMachine().resume();
|
||||
|
||||
@@ -306,7 +306,14 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
|
||||
InvalidStackFrameException error = null;
|
||||
for (int attempt = 0; attempt < 2; attempt++) {
|
||||
try {
|
||||
return getAllValues().get(localVariable.getVariable());
|
||||
Map<LocalVariable, Value> values = getAllValues();
|
||||
LocalVariable variable = localVariable.getVariable();
|
||||
if (values.containsKey(variable)) {
|
||||
return values.get(variable);
|
||||
}
|
||||
else { // try direct get
|
||||
return getStackFrame().getValue(variable);
|
||||
}
|
||||
}
|
||||
catch (InvalidStackFrameException e) {
|
||||
error = e;
|
||||
@@ -359,6 +366,14 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
|
||||
catch (AbsentInformationException e) {
|
||||
throw EvaluateExceptionUtil.createEvaluateException(e);
|
||||
}
|
||||
catch (InternalException e) {
|
||||
// extra logging for IDEA-141270
|
||||
if (e.errorCode() == 35 || e.errorCode() == 101) {
|
||||
LOG.info(e);
|
||||
myAllValues = Collections.emptyMap();
|
||||
}
|
||||
else throw e;
|
||||
}
|
||||
}
|
||||
return myAllValues;
|
||||
}
|
||||
|
||||
@@ -25,15 +25,14 @@ import com.intellij.debugger.engine.requests.RequestManagerImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.BreakpointRequest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
@@ -67,29 +66,29 @@ public class StepIntoBreakpoint extends RunToCursorBreakpoint {
|
||||
}
|
||||
|
||||
if (!locations.isEmpty()) {
|
||||
final Set<Method> methods = new HashSet<Method>();
|
||||
MultiMap<Method, Location> methods = new MultiMap<Method, Location>();
|
||||
for (Location loc : locations) {
|
||||
if (acceptLocation(debugProcess, classType, loc)) {
|
||||
methods.add(loc.method());
|
||||
methods.putValue(loc.method(), loc);
|
||||
}
|
||||
}
|
||||
Location location = null;
|
||||
final int methodsFound = methods.size();
|
||||
if (methodsFound == 1) {
|
||||
location = methods.iterator().next().location();
|
||||
location = methods.values().iterator().next();
|
||||
}
|
||||
else {
|
||||
if (myFilter instanceof LambdaMethodFilter) {
|
||||
final LambdaMethodFilter lambdaFilter = (LambdaMethodFilter)myFilter;
|
||||
if (lambdaFilter.getLambdaOrdinal() < methodsFound) {
|
||||
final Method[] candidates = methods.toArray(new Method[methodsFound]);
|
||||
Method[] candidates = methods.keySet().toArray(new Method[methodsFound]);
|
||||
Arrays.sort(candidates, DebuggerUtilsEx.LAMBDA_ORDINAL_COMPARATOR);
|
||||
location = candidates[lambdaFilter.getLambdaOrdinal()].location();
|
||||
location = methods.get(candidates[lambdaFilter.getLambdaOrdinal()]).iterator().next();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (methodsFound > 0) {
|
||||
location = methods.iterator().next().location();
|
||||
location = methods.values().iterator().next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -45,9 +45,15 @@ public class GraphicsObjectRenderer extends ToStringBasedRenderer implements Ful
|
||||
Field surfaceField = ((ClassType)value.type()).fieldByName("surfaceData");
|
||||
if (surfaceField == null) return null;
|
||||
ObjectReference surfaceDataValue = (ObjectReference)value.getValue(surfaceField);
|
||||
final Field bufImgField = ((ClassType)surfaceDataValue.type()).fieldByName("bufImg");
|
||||
if (bufImgField == null) return null;
|
||||
final Value bufImgValue = surfaceDataValue.getValue(bufImgField);
|
||||
if (surfaceDataValue == null) return null;
|
||||
|
||||
Field imgField = ((ReferenceType)surfaceDataValue.type()).fieldByName("bufImg"); // BufImgSurfaceData
|
||||
if (imgField == null) {
|
||||
imgField = ((ReferenceType)surfaceDataValue.type()).fieldByName("offscreenImage"); // CGLSurfaceData
|
||||
}
|
||||
if (imgField == null) return null;
|
||||
|
||||
final Value bufImgValue = surfaceDataValue.getValue(imgField);
|
||||
Type type = bufImgValue.type();
|
||||
if (!(type instanceof ReferenceType) || !DebuggerUtils.instanceOf(type, "java.awt.Image")) {
|
||||
return null;
|
||||
|
||||
+22
-8
@@ -16,10 +16,12 @@
|
||||
package com.intellij.debugger.ui.tree.render;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.FullValueEvaluatorProvider;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContext;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsImpl;
|
||||
import com.intellij.debugger.settings.NodeRendererSettings;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
@@ -42,15 +44,27 @@ class IconObjectRenderer extends ToStringBasedRenderer implements FullValueEvalu
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon calcValueIcon(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener listener)
|
||||
public Icon calcValueIcon(final ValueDescriptor descriptor, final EvaluationContext evaluationContext, final DescriptorLabelListener listener)
|
||||
throws EvaluateException {
|
||||
String getterName = AllIcons.Debugger.Value.getIconHeight() <= 16 ? "iconToBytesPreviewNormal" : "iconToBytesPreviewRetina";
|
||||
if (!Registry.is("debugger.auto.fetch.icons") || DebuggerUtilsImpl.isRemote(evaluationContext.getDebugProcess())) {
|
||||
return null; // do not auto load icon for remote
|
||||
}
|
||||
else {
|
||||
return ImageObjectRenderer.getIcon(evaluationContext, descriptor.getValue(), getterName);
|
||||
}
|
||||
EvaluationContextImpl evalContext = ((EvaluationContextImpl)evaluationContext);
|
||||
DebugProcessImpl debugProcess = evalContext.getDebugProcess();
|
||||
|
||||
if (!Registry.is("debugger.auto.fetch.icons") || DebuggerUtilsImpl.isRemote(debugProcess)) return null;
|
||||
|
||||
debugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(evalContext.getSuspendContext()) {
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.LOW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextAction() throws Exception {
|
||||
String getterName = AllIcons.Debugger.Value.getIconHeight() <= 16 ? "iconToBytesPreviewNormal" : "iconToBytesPreviewRetina";
|
||||
descriptor.setValueIcon(ImageObjectRenderer.getIcon(evaluationContext, descriptor.getValue(), getterName));
|
||||
listener.labelChanged();
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+30
-12
@@ -28,6 +28,8 @@ import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderEnumerator;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -35,6 +37,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -62,19 +65,21 @@ public class JavaScratchCompilationSupport implements ProjectComponent, CompileT
|
||||
if (scratchUrl == null) {
|
||||
return true;
|
||||
}
|
||||
final Module configModule = ((ModuleBasedConfiguration)configuration).getConfigurationModule().getModule();
|
||||
if (configModule == null) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, "A module must be specified for the run configuration", scratchUrl, -1, -1);
|
||||
return true;
|
||||
}
|
||||
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(configModule);
|
||||
final Sdk targetSdk = moduleRootManager.getSdk();
|
||||
@Nullable
|
||||
final Module module = ((ModuleBasedConfiguration)configuration).getConfigurationModule().getModule();
|
||||
final Sdk targetSdk = module != null? ModuleRootManager.getInstance(module).getSdk() : ProjectRootManager.getInstance(project).getProjectSdk();
|
||||
if (targetSdk == null) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, "Cannot find associated SDK for run configuration module \"" + configModule.getName() + "\".\nPlease check project settings.", scratchUrl, -1, -1);
|
||||
final String message = module != null?
|
||||
"Cannot find associated SDK for run configuration module \"" + module.getName() + "\".\nPlease check project settings." :
|
||||
"Cannot find associated project SDK for the run configuration.\nPlease check project settings.";
|
||||
context.addMessage(CompilerMessageCategory.ERROR, message, scratchUrl, -1, -1);
|
||||
return true;
|
||||
}
|
||||
if (!(targetSdk.getSdkType() instanceof JavaSdkType)) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, "Expected Java SDK for run configuration module \"" + configModule.getName() + "\".\nPlease check project settings.", scratchUrl, -1, -1);
|
||||
final String message = module != null?
|
||||
"Expected Java SDK for run configuration module \"" + module.getName() + "\".\nPlease check project settings." :
|
||||
"Expected Java SDK for project \"" + project.getName() + "\".\nPlease check project settings.";
|
||||
context.addMessage(CompilerMessageCategory.ERROR, message, scratchUrl, -1, -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -131,11 +136,24 @@ public class JavaScratchCompilationSupport implements ProjectComponent, CompileT
|
||||
final Collection<File> files = Collections.singleton(srcFile);
|
||||
|
||||
final Set<File> cp = new LinkedHashSet<File>();
|
||||
for (String s : moduleRootManager.orderEntries().compileOnly().recursively().exportedOnly().withoutSdk().getPathsList().getPathList()) {
|
||||
final List<File> platformCp = new ArrayList<File>();
|
||||
|
||||
final Computable<OrderEnumerator> orderEnumerator = module != null ? new Computable<OrderEnumerator>() {
|
||||
@Override
|
||||
public OrderEnumerator compute() {
|
||||
return ModuleRootManager.getInstance(module).orderEntries();
|
||||
}
|
||||
} : new Computable<OrderEnumerator>() {
|
||||
@Override
|
||||
public OrderEnumerator compute() {
|
||||
return ProjectRootManager.getInstance(project).orderEntries();
|
||||
}
|
||||
};
|
||||
|
||||
for (String s : orderEnumerator.compute().compileOnly().recursively().exportedOnly().withoutSdk().getPathsList().getPathList()) {
|
||||
cp.add(new File(s));
|
||||
}
|
||||
final List<File> platformCp = new ArrayList<File>();
|
||||
for (String s : moduleRootManager.orderEntries().compileOnly().sdkOnly().getPathsList().getPathList()) {
|
||||
for (String s : orderEnumerator.compute().compileOnly().sdkOnly().getPathsList().getPathList()) {
|
||||
platformCp.add(new File(s));
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -641,6 +641,10 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
|
||||
for (int row = 0; row < myModel.getRowCount(); row++) {
|
||||
final OrderEntry orderEntry = getItemAt(row).getEntry();
|
||||
if (orderEntry != null && entry.getPresentableName().equals(orderEntry.getPresentableName())) {
|
||||
if (orderEntry instanceof ExportableOrderEntry && entry instanceof ExportableOrderEntry &&
|
||||
((ExportableOrderEntry)entry).getScope() != ((ExportableOrderEntry)orderEntry).getScope()) {
|
||||
continue;
|
||||
}
|
||||
myEntryTable.getSelectionModel().setSelectionInterval(row, row);
|
||||
TableUtil.scrollSelectionToVisible(myEntryTable);
|
||||
}
|
||||
|
||||
+18
-10
@@ -17,6 +17,8 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.DumbModePermission;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
@@ -56,18 +58,24 @@ public class ChangeLibraryLevelAction extends ChangeLibraryLevelActionBase {
|
||||
final LibraryProjectStructureElement libraryElement = (LibraryProjectStructureElement)selectedElement;
|
||||
final LibraryEx oldLibrary = (LibraryEx)context.getLibrary(libraryElement.getLibrary().getName(), mySourceConfigurable.getLevel());
|
||||
LOG.assertTrue(oldLibrary != null);
|
||||
final Library newLibrary = doCopy(oldLibrary);
|
||||
if (newLibrary == null) return;
|
||||
|
||||
final Collection<ProjectStructureElementUsage> usages = context.getDaemonAnalyzer().getUsages(libraryElement);
|
||||
for (ProjectStructureElementUsage usage : usages) {
|
||||
usage.replaceElement(new LibraryProjectStructureElement(context, newLibrary));
|
||||
}
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Library newLibrary = doCopy(oldLibrary);
|
||||
if (newLibrary == null) return;
|
||||
|
||||
if (!myCopy) {
|
||||
mySourceConfigurable.removeLibrary(libraryElement);
|
||||
}
|
||||
ProjectStructureConfigurable.getInstance(myProject).selectProjectOrGlobalLibrary(newLibrary, true);
|
||||
final Collection<ProjectStructureElementUsage> usages = context.getDaemonAnalyzer().getUsages(libraryElement);
|
||||
for (ProjectStructureElementUsage usage : usages) {
|
||||
usage.replaceElement(new LibraryProjectStructureElement(context, newLibrary));
|
||||
}
|
||||
|
||||
if (!myCopy) {
|
||||
mySourceConfigurable.removeLibrary(libraryElement);
|
||||
}
|
||||
ProjectStructureConfigurable.getInstance(myProject).selectProjectOrGlobalLibrary(newLibrary, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-2
@@ -26,6 +26,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -413,8 +414,15 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
}
|
||||
|
||||
final PsiType qualifierExpressionType = qualifierExpression.getType();
|
||||
return qualifierExpressionType != null && !TypeConversionUtil.containsWildcards(qualifierExpressionType)
|
||||
? qualifierExpressionType.getCanonicalText() : getClassReferenceName(containingClass);
|
||||
if (qualifierExpressionType != null && !TypeConversionUtil.containsWildcards(qualifierExpressionType)) {
|
||||
try {
|
||||
final String canonicalText = qualifierExpressionType.getCanonicalText();
|
||||
JavaPsiFacade.getElementFactory(containingClass.getProject()).createExpressionFromText(canonicalText + "::foo", qualifierExpression);
|
||||
return canonicalText;
|
||||
}
|
||||
catch (IncorrectOperationException ignore){}
|
||||
}
|
||||
return getClassReferenceName(containingClass);
|
||||
}
|
||||
|
||||
private static String getClassReferenceName(PsiClass containingClass) {
|
||||
|
||||
+9
-11
@@ -1513,12 +1513,12 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
|
||||
static List<MethodContract> getMethodContracts(@NotNull final PsiMethod method) {
|
||||
final PsiAnnotation contractAnno = findContractAnnotation(method);
|
||||
if (contractAnno != null) {
|
||||
return CachedValuesManager.getCachedValue(contractAnno, new CachedValueProvider<List<MethodContract>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<List<MethodContract>> compute() {
|
||||
return CachedValuesManager.getCachedValue(method, new CachedValueProvider<List<MethodContract>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<List<MethodContract>> compute() {
|
||||
final PsiAnnotation contractAnno = findContractAnnotation(method);
|
||||
if (contractAnno != null) {
|
||||
String text = AnnotationUtil.getStringAttributeValue(contractAnno, null);
|
||||
if (text != null) {
|
||||
try {
|
||||
@@ -1534,12 +1534,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return Result.create(Collections.<MethodContract>emptyList(), contractAnno, method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
return Result.create(Collections.<MethodContract>emptyList(), method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+2
-1
@@ -768,7 +768,8 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
iterator.advance();
|
||||
}
|
||||
|
||||
if (!iterator.atEnd() && (iterator.getTokenType() == JavaTokenType.LPARENTH)) {
|
||||
if (!iterator.atEnd() && iterator.getTokenType() == JavaTokenType.LPARENTH && PsiTreeUtil.getParentOfType(ref, PsiExpression.class, PsiClass.class) == null) {
|
||||
// looks like a method declaration, e.g. StringBui<caret>methodName() inside a class
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ide;
|
||||
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.compiler.CompilerManager;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
@@ -36,6 +36,7 @@ import javax.swing.*;
|
||||
* @author yole
|
||||
*/
|
||||
public class JavaFileIconPatcher implements FileIconPatcher {
|
||||
@Override
|
||||
public Icon patchIcon(final Icon baseIcon, final VirtualFile file, final int flags, final Project project) {
|
||||
if (project == null) {
|
||||
return baseIcon;
|
||||
@@ -58,7 +59,7 @@ public class JavaFileIconPatcher implements FileIconPatcher {
|
||||
}
|
||||
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
|
||||
if (psiFile instanceof PsiClassOwner && psiFile.getViewProvider().getBaseLanguage() == StdLanguages.JAVA) {
|
||||
if (psiFile instanceof PsiClassOwner && psiFile.getViewProvider().getBaseLanguage() == JavaLanguage.INSTANCE) {
|
||||
PsiClass[] classes = ((PsiClassOwner)psiFile).getClasses();
|
||||
if (classes.length > 0) {
|
||||
// prefer icon of the class named after file
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -18,7 +18,6 @@ package com.intellij.ide.highlighter;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -28,14 +27,6 @@ public class JavaClassFileType implements FileType {
|
||||
|
||||
public static final JavaClassFileType INSTANCE = new JavaClassFileType();
|
||||
|
||||
private static final NotNullLazyValue<Icon> ICON = new NotNullLazyValue<Icon>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected Icon compute() {
|
||||
return AllIcons.FileTypes.JavaClass;
|
||||
}
|
||||
};
|
||||
|
||||
private JavaClassFileType() {
|
||||
}
|
||||
|
||||
@@ -59,7 +50,7 @@ public class JavaClassFileType implements FileType {
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ICON.getValue();
|
||||
return AllIcons.FileTypes.JavaClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -139,11 +139,8 @@ public class ClassInnerStuffCache {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<PsiMethod> compute() {
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
|
||||
String text = "public static " + myClass.getName() + "[] values() { }";
|
||||
PsiMethod physicalMethod = factory.createMethodFromText(text, myClass);
|
||||
PsiMethod method = new LightMethod(myClass.getManager(), physicalMethod, myClass);
|
||||
return new Result<PsiMethod>(method, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
|
||||
return new Result<PsiMethod>(getSyntheticMethod(text), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -154,11 +151,8 @@ public class ClassInnerStuffCache {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<PsiMethod> compute() {
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
|
||||
String text = "public static " + myClass.getName() + " valueOf(java.lang.String name) throws java.lang.IllegalArgumentException { }";
|
||||
PsiMethod physicalMethod = factory.createMethodFromText(text, myClass);
|
||||
PsiMethod method = new LightMethod(myClass.getManager(), physicalMethod, myClass);
|
||||
return new Result<PsiMethod>(method, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
|
||||
return new Result<PsiMethod>(getSyntheticMethod(text), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -236,6 +230,12 @@ public class ClassInnerStuffCache {
|
||||
return cachedInners;
|
||||
}
|
||||
|
||||
private PsiMethod getSyntheticMethod(String text) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
|
||||
PsiMethod method = factory.createMethodFromText(text, myClass);
|
||||
return new LightMethod(myClass.getManager(), method, myClass);
|
||||
}
|
||||
|
||||
public void dropCaches() {
|
||||
myTracker.incModificationCount();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class Zoo {
|
||||
|
||||
void foo(int x) {
|
||||
if (x < getAnnotati<caret>onsAreaOffset());
|
||||
|
||||
}
|
||||
|
||||
int getAnnotationsAreaOffset() {}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Replace lambda with method reference" "true"
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
class Test<T> {
|
||||
|
||||
|
||||
class Bar {
|
||||
void f( ){
|
||||
Function<Test<T>.Bar, String> r = Bar::foo;
|
||||
}
|
||||
|
||||
private String foo() {}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Replace lambda with method reference" "true"
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
class Test<T> {
|
||||
|
||||
|
||||
class Bar {
|
||||
void f( ){
|
||||
Function<Test<T>.Bar, String> r = (Test<T>.Bar t) -> t.fo<caret>o();
|
||||
}
|
||||
|
||||
private String foo() {}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -117,7 +117,7 @@ public class HeavyNormalCompletionTest extends JavaCodeInsightFixtureTestCase {
|
||||
myFixture.completeBasic();
|
||||
assertOrderedEquals(myFixture.getLookupElementStrings(), "getAaa", "getBbb");
|
||||
myFixture.getEditor().getCaretModel().moveToOffset(myFixture.getEditor().getCaretModel().getOffset() + 2);
|
||||
assertNull(myFixture.completeBasic());
|
||||
assert myFixture.completeBasic() == null
|
||||
}
|
||||
|
||||
public void testQualifyInaccessibleClassName() throws Exception {
|
||||
|
||||
+5
@@ -512,6 +512,11 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testBreakInIfCondition() throws Throwable { doTest(); }
|
||||
public void testAccessStaticViaInstance() throws Throwable { doTest(); }
|
||||
|
||||
public void testIfConditionLt() {
|
||||
configure()
|
||||
myFixture.assertPreferredCompletionItems 0, 'getAnnotationsAreaOffset'
|
||||
}
|
||||
|
||||
public void testAccessStaticViaInstanceSecond() throws Throwable {
|
||||
configure()
|
||||
myFixture.complete(CompletionType.BASIC, 2)
|
||||
|
||||
@@ -148,11 +148,11 @@ public class FindInEditorMultiCaretTest extends LightPlatformCodeInsightFixtureT
|
||||
}
|
||||
|
||||
private void nextOccurrence() {
|
||||
executeHeaderAction(EditorSearchSession.createNextOccurrenceAction());
|
||||
executeHeaderAction(new NextOccurrenceAction());
|
||||
}
|
||||
|
||||
private void prevOccurrence() {
|
||||
executeHeaderAction(EditorSearchSession.createPrevOccurrenceAction());
|
||||
executeHeaderAction(new PrevOccurrenceAction());
|
||||
}
|
||||
|
||||
private void addOccurrence() {
|
||||
|
||||
+3
-1
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
public class DeclarationStatementHandler extends MatchingHandler {
|
||||
private MatchingHandler myCommentHandler;
|
||||
|
||||
@Override
|
||||
public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
|
||||
if (patternNode instanceof PsiComment) {
|
||||
return myCommentHandler.match(patternNode, matchedNode, context);
|
||||
@@ -59,7 +60,7 @@ public class DeclarationStatementHandler extends MatchingHandler {
|
||||
node = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace.class);
|
||||
while (PsiUtil.isJavaToken(node, JavaTokenType.COMMA)) {
|
||||
node = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace.class);
|
||||
if (node != null) {
|
||||
if (node instanceof PsiField) {
|
||||
matchNodes.add(node);
|
||||
}
|
||||
node = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace.class);
|
||||
@@ -89,6 +90,7 @@ public class DeclarationStatementHandler extends MatchingHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAdvanceTheMatchFor(PsiElement patternElement, PsiElement matchedElement) {
|
||||
if (patternElement instanceof PsiComment &&
|
||||
( matchedElement instanceof PsiField ||
|
||||
|
||||
@@ -93,7 +93,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
|
||||
private final FileTreeAccessFilter myFileTreeAccessFilter = new FileTreeAccessFilter();
|
||||
private VirtualFileFilter myVirtualFileFilter = new FileTreeAccessFilter();
|
||||
|
||||
@Override
|
||||
protected boolean isRunInWriteAction() {
|
||||
@@ -282,7 +282,7 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
|
||||
}
|
||||
final JavaPsiFacadeEx facade = getJavaFacade();
|
||||
if (facade != null) {
|
||||
facade.setAssertOnFileLoadingFilter(myFileTreeAccessFilter, myTestRootDisposable); // check repository work
|
||||
facade.setAssertOnFileLoadingFilter(myVirtualFileFilter, myTestRootDisposable); // check repository work
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -302,16 +302,24 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
|
||||
|
||||
@Override
|
||||
protected Editor createEditor(@NotNull VirtualFile file) {
|
||||
allowTreeAccessForFile(file);
|
||||
if (myVirtualFileFilter instanceof FileTreeAccessFilter) {
|
||||
allowTreeAccessForFile(file);
|
||||
}
|
||||
return super.createEditor(file);
|
||||
}
|
||||
|
||||
protected void setVirtualFileFilter(@NotNull VirtualFileFilter filter) {
|
||||
myVirtualFileFilter = filter;
|
||||
}
|
||||
|
||||
protected void allowTreeAccessForFile(@NotNull VirtualFile file) {
|
||||
myFileTreeAccessFilter.allowTreeAccessForFile(file);
|
||||
assert myVirtualFileFilter instanceof FileTreeAccessFilter : "configured filter does not support this method";
|
||||
((FileTreeAccessFilter)myVirtualFileFilter).allowTreeAccessForFile(file);
|
||||
}
|
||||
|
||||
protected void allowTreeAccessForAllFiles() {
|
||||
myFileTreeAccessFilter.allowTreeAccessForAllFiles();
|
||||
assert myVirtualFileFilter instanceof FileTreeAccessFilter : "configured filter does not support this method";
|
||||
((FileTreeAccessFilter)myVirtualFileFilter).allowTreeAccessForAllFiles();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -22,8 +22,6 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.packageDependencies.DependencyValidationManager;
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -104,12 +102,7 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
|
||||
final Profile projectProfile = myProfiles.get(profile);
|
||||
if (projectProfile != null) {
|
||||
Element profileElement = new Element(PROFILE);
|
||||
try {
|
||||
projectProfile.writeExternal(profileElement);
|
||||
}
|
||||
catch (WriteExternalException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
projectProfile.writeExternal(profileElement);
|
||||
boolean hasSmthToSave = sortedProfiles.length > 1 || isCustomProfileUsed();
|
||||
if (!hasSmthToSave) {
|
||||
for (Element child : profileElement.getChildren()) {
|
||||
@@ -141,16 +134,12 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
|
||||
for (Element o : state.getChildren(PROFILE)) {
|
||||
Profile profile = myApplicationProfileManager.createProfile();
|
||||
profile.setProfileManager(this);
|
||||
try {
|
||||
profile.readExternal(o);
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
profile.readExternal(o);
|
||||
profile.setProjectLevel(true);
|
||||
if (profileKeys.contains(profile.getName())) {
|
||||
updateProfile(profile);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
myProfiles.put(profile.getName(), profile);
|
||||
}
|
||||
}
|
||||
@@ -252,10 +241,6 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
|
||||
});
|
||||
}
|
||||
|
||||
public void removeProfilesListener(@NotNull ProfileChangeAdapter profilesListener) {
|
||||
myProfilesListener.remove(profilesListener);
|
||||
}
|
||||
|
||||
public static class ProfileStateSplitter extends MainConfigurationStateSplitter {
|
||||
@NotNull
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -16,14 +16,14 @@
|
||||
package com.intellij.profile;
|
||||
|
||||
import com.intellij.openapi.options.Scheme;
|
||||
import com.intellij.openapi.util.JDOMExternalizable;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 20-Nov-2005
|
||||
*/
|
||||
public interface Profile extends JDOMExternalizable, Comparable, Scheme {
|
||||
public interface Profile extends Comparable, Scheme {
|
||||
void copyFrom(@NotNull Profile profile);
|
||||
|
||||
void setLocal(boolean isLocal);
|
||||
@@ -48,4 +48,8 @@ public interface Profile extends JDOMExternalizable, Comparable, Scheme {
|
||||
|
||||
@NotNull
|
||||
ProfileManager getProfileManager();
|
||||
|
||||
void readExternal(Element element);
|
||||
|
||||
void writeExternal(Element element);
|
||||
}
|
||||
|
||||
+1
-9
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.codeInspection.ex;
|
||||
|
||||
import com.intellij.codeHighlighting.HighlightDisplayLevel;
|
||||
@@ -27,7 +26,6 @@ import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.options.ExternalInfo;
|
||||
import com.intellij.openapi.options.ExternalizableScheme;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -253,7 +251,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(@NotNull Element element) throws InvalidDataException {
|
||||
public void readExternal(@NotNull Element element) {
|
||||
super.readExternal(element);
|
||||
|
||||
final String version = element.getAttributeValue(VERSION_TAG);
|
||||
@@ -868,12 +866,6 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ExternalInfo getExternalInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ScopeToolState> getAllTools(Project project) {
|
||||
initInspectionTools(project);
|
||||
|
||||
@@ -142,7 +142,7 @@ public class ToolsImpl implements Tools {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void writeExternal(Element inspectionElement) throws WriteExternalException {
|
||||
public void writeExternal(@NotNull Element inspectionElement) throws WriteExternalException {
|
||||
if (myTools != null) {
|
||||
for (ScopeToolState state : myTools) {
|
||||
final Element scopeElement = new Element("scope");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.profile;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.util.xmlb.SmartSerializer;
|
||||
import com.intellij.util.xmlb.annotations.OptionTag;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
@@ -30,8 +27,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Date: 01-Dec-2005
|
||||
*/
|
||||
public abstract class ProfileEx implements Profile {
|
||||
private static final Logger LOG = Logger.getInstance(ProfileEx.class);
|
||||
|
||||
public static final String SCOPE = "scope";
|
||||
public static final String NAME = "name";
|
||||
|
||||
@@ -68,17 +63,9 @@ public abstract class ProfileEx implements Profile {
|
||||
|
||||
@Override
|
||||
public void copyFrom(@NotNull Profile profile) {
|
||||
try {
|
||||
Element config = new Element("config");
|
||||
profile.writeExternal(config);
|
||||
readExternal(config);
|
||||
}
|
||||
catch (WriteExternalException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
Element config = new Element("config");
|
||||
profile.writeExternal(config);
|
||||
readExternal(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -121,7 +108,7 @@ public abstract class ProfileEx implements Profile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
public void readExternal(Element element) {
|
||||
mySerializer.readExternal(this, element);
|
||||
}
|
||||
|
||||
@@ -130,7 +117,7 @@ public abstract class ProfileEx implements Profile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(Element element) throws WriteExternalException {
|
||||
public void writeExternal(Element element) {
|
||||
serializeInto(element, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.configurationStore
|
||||
|
||||
import com.intellij.ide.actions.ExportableItem
|
||||
import com.intellij.ide.actions.getExportableComponentsMap
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.vfs.CharsetToolkit
|
||||
@@ -33,6 +35,7 @@ import org.junit.ClassRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
@@ -109,6 +112,17 @@ internal class ApplicationStoreTest {
|
||||
assertThat(oldFile).doesNotExist()
|
||||
}
|
||||
|
||||
@Test fun `export settings`() {
|
||||
val storageManager = ApplicationManager.getApplication().stateStore.stateStorageManager
|
||||
val optionsPath = storageManager.expandMacros(StoragePathMacros.APP_CONFIG)
|
||||
val rootConfigPath = storageManager.expandMacros(ROOT_CONFIG)
|
||||
val map = getExportableComponentsMap(false, true, storageManager)
|
||||
assertThat(map.size()).isNotEqualTo(0)
|
||||
|
||||
val key = File(optionsPath, "filetypes.xml")
|
||||
assertThat(map.get(key)).containsExactly(ExportableItem(listOf(key, File(rootConfigPath, "filetypes")), "File types", RoamingType.DEFAULT))
|
||||
}
|
||||
|
||||
private fun createComponentData(foo: String) = """<component name="A" foo="$foo" />"""
|
||||
|
||||
@Test fun `remove data from deprecated storage if another component data exists`() {
|
||||
|
||||
@@ -40,7 +40,7 @@ private fun StateStorage.ExternalizationSession.save() {
|
||||
|
||||
private fun StateStorageBase<*>.setStateAndSave(componentName: String, state: String?) {
|
||||
var externalizationSession = startExternalization()!!
|
||||
externalizationSession.setState(null, componentName, if (state == null) Element("state") else JDOMUtil.load(state.reader))
|
||||
externalizationSession.setState(null, componentName, if (state == null) Element("state") else JDOMUtil.load(state.reader()))
|
||||
externalizationSession.save()
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class ModuleStoreTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun VirtualFile.loadModule() = runWriteAction { ModuleManager.getInstance(projectRule.project).loadModule(getPath()) }
|
||||
private fun VirtualFile.loadModule() = runWriteAction { ModuleManager.getInstance(projectRule.project).loadModule(path) }
|
||||
|
||||
fun Path.createModule() = projectRule.createModule(this)
|
||||
}
|
||||
@@ -51,8 +51,7 @@ class ModuleStoreTest {
|
||||
|
||||
@Test fun `set option`() {
|
||||
val moduleFile = runWriteAction {
|
||||
VfsTestUtil.createFile(tempDirManager.newVirtualDirectory("module"), "test.iml", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<module type=\"JAVA_MODULE\" foo=\"bar\" version=\"4\" />")
|
||||
VfsTestUtil.createFile(tempDirManager.newVirtualDirectory("module"), "test.iml", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" foo=\"bar\" version=\"4\" />")
|
||||
}
|
||||
|
||||
moduleFile.loadModule().useAndDispose {
|
||||
@@ -117,7 +116,7 @@ class ModuleStoreTest {
|
||||
assertThat(moduleFile).isRegularFile()
|
||||
|
||||
val virtualFile = LocalFileSystem.getInstance().findFileByPath(modulePath)!!
|
||||
val newData = moduleFile.readText().replace("<content url=\"file://\$MODULE_DIR$/${name}\" />\n", "").toByteArray()
|
||||
val newData = moduleFile.readText().replace("<content url=\"file://\$MODULE_DIR$/$name\" />\n", "").toByteArray()
|
||||
runWriteAction {
|
||||
virtualFile.setBinaryContent(newData)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.impl.ProjectManagerImpl
|
||||
import com.intellij.openapi.util.io.systemIndependentPath
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.testFramework.*
|
||||
import com.intellij.util.PathUtil
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.junit.ClassRule
|
||||
@@ -64,7 +65,7 @@ private fun createOrLoadProject(tempDirManager: TemporaryDirectory, task: (Proje
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectStoreTest {
|
||||
internal class ProjectStoreTest {
|
||||
companion object {
|
||||
@ClassRule val projectRule = ProjectRule()
|
||||
}
|
||||
@@ -76,12 +77,7 @@ class ProjectStoreTest {
|
||||
|
||||
@Language("XML")
|
||||
private val iprFileContent =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<project version=\"4\">\n" +
|
||||
" <component name=\"AATestComponent\">\n" +
|
||||
" <option name=\"value\" value=\"customValue\" />\n" +
|
||||
" </component>\n" +
|
||||
"</project>"
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"AATestComponent\">\n <option name=\"value\" value=\"customValue\" />\n </component>\n</project>"
|
||||
|
||||
@State(name = "AATestComponent", storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE)))
|
||||
private class TestComponent : PersistentStateComponent<TestState> {
|
||||
@@ -103,6 +99,8 @@ class ProjectStoreTest {
|
||||
}) { project ->
|
||||
val testComponent = test(project)
|
||||
|
||||
assertThat(project.basePath).isEqualTo(PathUtil.getParentPath((PathUtil.getParentPath(project.projectFilePath!!))))
|
||||
|
||||
// test reload on external change
|
||||
val file = File(project.stateStore.stateStorageManager.expandMacros(StoragePathMacros.PROJECT_FILE))
|
||||
file.writeText(file.readText().replace("""<option name="value" value="foo" />""", """<option name="value" value="newValue" />"""))
|
||||
@@ -117,6 +115,8 @@ class ProjectStoreTest {
|
||||
@Test fun fileBasedStorage() {
|
||||
loadAndUseProject(tempDirManager, { it.writeChild("test${ProjectFileType.DOT_DEFAULT_EXTENSION}", iprFileContent).path }) { project ->
|
||||
test(project)
|
||||
|
||||
assertThat(project.basePath).isEqualTo(PathUtil.getParentPath(project.projectFilePath!!))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -375,9 +375,6 @@ data class TestScheme(@field:Attribute private var name: String = "", @field:Att
|
||||
override @Transient fun setName(newName: String) {
|
||||
name = newName
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
|
||||
override fun getExternalInfo() = null
|
||||
}
|
||||
|
||||
open class TestSchemesProcessor : BaseSchemeProcessor<TestScheme>() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -18,21 +18,12 @@ package com.intellij.ide.highlighter;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class ArchiveFileType implements FileType {
|
||||
private static final NotNullLazyValue<Icon> ICON = new NotNullLazyValue<Icon>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected Icon compute() {
|
||||
return AllIcons.FileTypes.Archive;
|
||||
}
|
||||
};
|
||||
|
||||
public static final ArchiveFileType INSTANCE = new ArchiveFileType();
|
||||
|
||||
@Override
|
||||
@@ -55,7 +46,7 @@ public class ArchiveFileType implements FileType {
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ICON.getValue();
|
||||
return AllIcons.FileTypes.Archive;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -16,20 +16,12 @@
|
||||
package com.intellij.openapi.fileTypes;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class UnknownFileType implements FileType {
|
||||
private static final NotNullLazyValue<Icon> ICON = new NotNullLazyValue<Icon>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected Icon compute() {
|
||||
return AllIcons.FileTypes.Unknown;
|
||||
}
|
||||
};
|
||||
public static final FileType INSTANCE = new UnknownFileType();
|
||||
|
||||
private UnknownFileType() {}
|
||||
@@ -54,7 +46,7 @@ public class UnknownFileType implements FileType {
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ICON.getValue();
|
||||
return AllIcons.FileTypes.Unknown;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,13 +16,7 @@
|
||||
package com.intellij.openapi.options;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface ExternalizableScheme extends Scheme {
|
||||
@SuppressWarnings({"unused", "deprecation"})
|
||||
@Nullable
|
||||
@Deprecated
|
||||
ExternalInfo getExternalInfo();
|
||||
|
||||
void setName(@NotNull String newName);
|
||||
}
|
||||
|
||||
@@ -16,17 +16,10 @@
|
||||
package com.intellij.openapi.options;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class ExternalizableSchemeAdapter implements ExternalizableScheme {
|
||||
protected String myName;
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public final ExternalInfo getExternalInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public final String getName() {
|
||||
|
||||
@@ -339,6 +339,19 @@ public abstract class PsiElementPattern<T extends PsiElement,Self extends PsiEle
|
||||
});
|
||||
}
|
||||
|
||||
public Self withLastChildSkipping(@NotNull final ElementPattern skip, @NotNull final ElementPattern pattern) {
|
||||
return with(new PatternCondition<T>("withLastChildSkipping") {
|
||||
@Override
|
||||
public boolean accepts(@NotNull T t, ProcessingContext context) {
|
||||
PsiElement last = t.getLastChild();
|
||||
while (last != null && skip.accepts(last)) {
|
||||
last = last.getPrevSibling();
|
||||
}
|
||||
return pattern.accepts(last);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static class Capture<T extends PsiElement> extends PsiElementPattern<T,Capture<T>> {
|
||||
|
||||
protected Capture(final Class<T> aClass) {
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.diff.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.EmptyAction;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.TextEditor;
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class ProxyUndoRedoAction extends DumbAwareAction {
|
||||
@NotNull private final UndoManager myUndoManager;
|
||||
@NotNull private final TextEditor myEditor;
|
||||
private final boolean myUndo;
|
||||
|
||||
private ProxyUndoRedoAction(@NotNull UndoManager manager, @NotNull TextEditor editor, boolean undo) {
|
||||
myUndoManager = manager;
|
||||
myEditor = editor;
|
||||
myUndo = undo;
|
||||
}
|
||||
|
||||
public static void register(@Nullable Project project, @NotNull Editor editor, @NotNull JComponent component) {
|
||||
UndoManager undoManager = project != null ? UndoManager.getInstance(project) : UndoManager.getGlobalInstance();
|
||||
TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(editor);
|
||||
if (undoManager != null) {
|
||||
EmptyAction.setupAction(new ProxyUndoRedoAction(undoManager, textEditor, true), IdeActions.ACTION_UNDO, component);
|
||||
EmptyAction.setupAction(new ProxyUndoRedoAction(undoManager, textEditor, false), IdeActions.ACTION_REDO, component);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(myUndo ? myUndoManager.isUndoAvailable(myEditor) : myUndoManager.isRedoAvailable(myEditor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (myUndo) {
|
||||
myUndoManager.undo(myEditor);
|
||||
}
|
||||
else {
|
||||
myUndoManager.redo(myEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package com.intellij.diff.merge;
|
||||
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.FrameDiffTool;
|
||||
import com.intellij.diff.actions.ProxyUndoRedoAction;
|
||||
import com.intellij.diff.comparison.ByLine;
|
||||
import com.intellij.diff.comparison.ComparisonMergeUtil;
|
||||
import com.intellij.diff.comparison.ComparisonPolicy;
|
||||
@@ -44,8 +45,6 @@ import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.fileEditor.TextEditor;
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
@@ -225,10 +224,7 @@ public class TextMergeTool implements MergeTool {
|
||||
DiffUtil.registerAction(new IgnoreSelectedChangesAction(Side.LEFT, true), myPanel);
|
||||
DiffUtil.registerAction(new IgnoreSelectedChangesAction(Side.RIGHT, true), myPanel);
|
||||
|
||||
if (myUndoManager != null) {
|
||||
new UndoRedoAction(true).register();
|
||||
new UndoRedoAction(false).register();
|
||||
}
|
||||
ProxyUndoRedoAction.register(getProject(), getEditor(ThreeSide.BASE), myContentPanel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1161,43 +1157,6 @@ public class TextMergeTool implements MergeTool {
|
||||
// Helpers
|
||||
//
|
||||
|
||||
private class UndoRedoAction extends DumbAwareAction {
|
||||
private final boolean myUndo;
|
||||
|
||||
public UndoRedoAction(boolean undo) {
|
||||
myUndo = undo;
|
||||
}
|
||||
|
||||
public void register() {
|
||||
EmptyAction.setupAction(this, myUndo ? IdeActions.ACTION_UNDO : IdeActions.ACTION_REDO, myContentPanel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
assert myUndoManager != null;
|
||||
TextEditor textEditor = getTextEditor();
|
||||
e.getPresentation().setEnabled(myUndo ? myUndoManager.isUndoAvailable(textEditor) : myUndoManager.isRedoAvailable(textEditor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
assert myUndoManager != null;
|
||||
TextEditor textEditor = getTextEditor();
|
||||
if (myUndo) {
|
||||
myUndoManager.undo(textEditor);
|
||||
}
|
||||
else {
|
||||
myUndoManager.redo(textEditor);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TextEditor getTextEditor() {
|
||||
EditorEx editor = getEditor(ThreeSide.BASE);
|
||||
return TextEditorProvider.getInstance().getTextEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
private class MyDividerPaintable implements DiffDividerDrawUtil.DividerPaintable {
|
||||
@NotNull private final Side mySide;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.diff.tools.util.side;
|
||||
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.actions.ProxyUndoRedoAction;
|
||||
import com.intellij.diff.actions.impl.FocusOppositePaneAction;
|
||||
import com.intellij.diff.actions.impl.OpenInEditorWithMouseAction;
|
||||
import com.intellij.diff.actions.impl.SetEditorSettingsAction;
|
||||
@@ -80,6 +81,12 @@ public abstract class TwosideTextDiffViewer extends TwosideDiffViewer<TextEditor
|
||||
myEditableEditors = TextDiffViewerUtil.getEditableEditors(getEditors());
|
||||
|
||||
TextDiffViewerUtil.checkDifferentDocuments(myRequest);
|
||||
|
||||
boolean editable1 = DiffUtil.canMakeWritable(getContent1().getDocument());
|
||||
boolean editable2 = DiffUtil.canMakeWritable(getContent2().getDocument());
|
||||
if (editable1 ^ editable2) {
|
||||
ProxyUndoRedoAction.register(getProject(), editable1 ? getEditor1() : getEditor2(), myPanel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-7
@@ -19,7 +19,6 @@ import com.intellij.openapi.editor.colors.ColorKey;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.options.ExternalInfo;
|
||||
import com.intellij.openapi.options.ExternalizableScheme;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -83,10 +82,4 @@ public class EditorColorsSchemeImpl extends AbstractColorsScheme implements Exte
|
||||
newScheme.setName(getName());
|
||||
return newScheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ExternalInfo getExternalInfo() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ package com.intellij.openapi.externalSystem.service.execution;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.filters.TextConsoleBuilderImpl;
|
||||
import com.intellij.execution.filters.TextConsoleBuilderFactory;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
@@ -53,7 +53,7 @@ public class DefaultExternalSystemExecutionConsoleManager implements ExternalSys
|
||||
@NotNull ExecutionEnvironment env,
|
||||
@NotNull ProcessHandler processHandler) throws ExecutionException {
|
||||
myProcessHandler = processHandler;
|
||||
ConsoleView executionConsole = new TextConsoleBuilderImpl(project).getConsole();
|
||||
ConsoleView executionConsole = TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole();
|
||||
executionConsole.attachToProcess(processHandler);
|
||||
return executionConsole;
|
||||
}
|
||||
|
||||
@@ -160,6 +160,7 @@ public class TestStateStorage implements Disposable {
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
IOUtil.deleteAllFilesStartingWith(myFile);
|
||||
}
|
||||
myMap = initializeMap();
|
||||
LOG.error("Repaired after crash", e);
|
||||
|
||||
+3
-3
@@ -115,10 +115,10 @@ public class EnvironmentVariablesData {
|
||||
parent.addContent(envsElement);
|
||||
}
|
||||
|
||||
public void configureCommandLine(@NotNull GeneralCommandLine commandLine, boolean shellParentEnvs) {
|
||||
public void configureCommandLine(@NotNull GeneralCommandLine commandLine, boolean consoleParentEnvs) {
|
||||
if (myPassParentEnvs) {
|
||||
commandLine.withParentEnvironmentType(shellParentEnvs ? GeneralCommandLine.ParentEnvironmentType.CONSOLE
|
||||
: GeneralCommandLine.ParentEnvironmentType.SYSTEM);
|
||||
commandLine.withParentEnvironmentType(consoleParentEnvs ? GeneralCommandLine.ParentEnvironmentType.CONSOLE
|
||||
: GeneralCommandLine.ParentEnvironmentType.SYSTEM);
|
||||
}
|
||||
else {
|
||||
commandLine.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.NONE);
|
||||
|
||||
@@ -51,7 +51,8 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* @author max, andrey.zaytsev
|
||||
*/
|
||||
public class EditorSearchSession implements DataProvider,
|
||||
public class EditorSearchSession implements SearchSession,
|
||||
DataProvider,
|
||||
SelectionListener,
|
||||
SearchResults.SearchResultsListener,
|
||||
SearchReplaceComponent.Listener {
|
||||
@@ -87,8 +88,8 @@ public class EditorSearchSession implements DataProvider,
|
||||
|
||||
myComponent = SearchReplaceComponent
|
||||
.buildFor(project, myEditor.getContentComponent())
|
||||
.addPrimarySearchActions(createPrevOccurrenceAction(),
|
||||
createNextOccurrenceAction(),
|
||||
.addPrimarySearchActions(new PrevOccurrenceAction(),
|
||||
new NextOccurrenceAction(),
|
||||
new FindAllAction(),
|
||||
new Separator(),
|
||||
new AddOccurrenceAction(),
|
||||
@@ -111,8 +112,8 @@ public class EditorSearchSession implements DataProvider,
|
||||
new ExcludeAction())
|
||||
.addExtraReplaceAction(new TogglePreserveCaseAction(),
|
||||
new ToggleSelectionOnlyAction())
|
||||
.addReplaceFieldActions(createPrevOccurrenceAction(),
|
||||
createNextOccurrenceAction())
|
||||
.addReplaceFieldActions(new PrevOccurrenceAction(),
|
||||
new NextOccurrenceAction())
|
||||
.withDataProvider(this)
|
||||
.withCloseAction(new Runnable() {
|
||||
@Override
|
||||
@@ -160,7 +161,7 @@ public class EditorSearchSession implements DataProvider,
|
||||
}
|
||||
updateUIWithFindModel();
|
||||
updateResults(true);
|
||||
syncFindModels(FindManager.getInstance(getProject()).getFindInFileModel(), myFindModel);
|
||||
FindUtil.updateFindInFileModel(getProject(), myFindModel);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -194,6 +195,7 @@ public class EditorSearchSession implements DataProvider,
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SearchReplaceComponent getComponent() {
|
||||
return myComponent;
|
||||
}
|
||||
@@ -219,6 +221,9 @@ public class EditorSearchSession implements DataProvider,
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getData(@NonNls final String dataId) {
|
||||
if (SearchSession.KEY.is(dataId)) {
|
||||
return this;
|
||||
}
|
||||
if (SESSION_KEY.is(dataId)) {
|
||||
return this;
|
||||
}
|
||||
@@ -289,18 +294,27 @@ public class EditorSearchSession implements DataProvider,
|
||||
myFindModel.setMultiline(myComponent.isMultiline());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FindModel getFindModel() {
|
||||
return myFindModel;
|
||||
}
|
||||
|
||||
private static void syncFindModels(FindModel to, FindModel from) {
|
||||
to.setCaseSensitive(from.isCaseSensitive());
|
||||
to.setWholeWordsOnly(from.isWholeWordsOnly());
|
||||
to.setRegularExpressions(from.isRegularExpressions());
|
||||
to.setSearchContext(from.getSearchContext());
|
||||
if (from.isReplaceState()) {
|
||||
to.setPreserveCase(from.isPreserveCase());
|
||||
}
|
||||
@Override
|
||||
public boolean hasMatches() {
|
||||
return mySearchResults != null && mySearchResults.hasMatches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void searchForward() {
|
||||
moveCursor(SearchResults.Direction.DOWN);
|
||||
addTextToRecent(myComponent.getSearchTextComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void searchBackward() {
|
||||
moveCursor(SearchResults.Direction.UP);
|
||||
addTextToRecent(myComponent.getSearchTextComponent());
|
||||
}
|
||||
|
||||
public void updateUIWithFindModel() {
|
||||
@@ -332,16 +346,6 @@ public class EditorSearchSession implements DataProvider,
|
||||
}
|
||||
}
|
||||
|
||||
public void searchBackward() {
|
||||
moveCursor(SearchResults.Direction.UP);
|
||||
addTextToRecent(myComponent.getSearchTextComponent());
|
||||
}
|
||||
|
||||
public void searchForward() {
|
||||
moveCursor(SearchResults.Direction.DOWN);
|
||||
addTextToRecent(myComponent.getSearchTextComponent());
|
||||
}
|
||||
|
||||
public void addTextToRecent(JTextComponent textField) {
|
||||
myComponent.addTextToRecent(textField);
|
||||
}
|
||||
@@ -355,6 +359,7 @@ public class EditorSearchSession implements DataProvider,
|
||||
myLivePreviewController.moveCursor(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
IdeFocusManager.getInstance(getProject()).requestFocus(myEditor.getContentComponent(), false);
|
||||
|
||||
@@ -388,7 +393,7 @@ public class EditorSearchSession implements DataProvider,
|
||||
myComponent.setNotFoundBackground();
|
||||
myClickToHighlightLabel.setVisible(false);
|
||||
mySearchResults.clear();
|
||||
myComponent.setStatusText("Incorrect regular expression");
|
||||
myComponent.setStatusText(INCORRECT_REGEX_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -430,10 +435,6 @@ public class EditorSearchSession implements DataProvider,
|
||||
myFindModel.setStringToFind(text);
|
||||
}
|
||||
|
||||
public boolean hasMatches() {
|
||||
return mySearchResults != null && mySearchResults.hasMatches();
|
||||
}
|
||||
|
||||
public void selectAllOccurrences() {
|
||||
FindUtil.selectSearchResultsInEditor(myEditor, mySearchResults.getOccurrences().iterator(), -1);
|
||||
}
|
||||
@@ -451,27 +452,6 @@ public class EditorSearchSession implements DataProvider,
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
static NextOccurrenceAction createNextOccurrenceAction() {
|
||||
return new NextOccurrenceAction(new PrevNextActionHandler() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
e.getRequiredData(SESSION_KEY).searchForward();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static PrevOccurrenceAction createPrevOccurrenceAction() {
|
||||
return new PrevOccurrenceAction(new PrevNextActionHandler() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
e.getRequiredData(SESSION_KEY).searchBackward();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static abstract class ButtonAction extends DumbAwareAction implements CustomComponentAction, ActionListener {
|
||||
private final String myTitle;
|
||||
private final char myMnemonic;
|
||||
@@ -565,12 +545,4 @@ public class EditorSearchSession implements DataProvider,
|
||||
moveCursor(SearchResults.Direction.DOWN);
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class PrevNextActionHandler implements PrevNextOccurrenceAction.Handler {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
EditorSearchSession search = e.getData(SESSION_KEY);
|
||||
e.getPresentation().setEnabled(search != null && search.hasMatches());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +148,17 @@ public class FindUtil {
|
||||
model.setPromptOnReplace(false);
|
||||
}
|
||||
|
||||
public static void updateFindInFileModel(@Nullable Project project, @NotNull FindModel with) {
|
||||
FindModel model = FindManager.getInstance(project).getFindInFileModel();
|
||||
model.setCaseSensitive(with.isCaseSensitive());
|
||||
model.setWholeWordsOnly(with.isWholeWordsOnly());
|
||||
model.setRegularExpressions(with.isRegularExpressions());
|
||||
model.setSearchContext(with.getSearchContext());
|
||||
if (with.isReplaceState()) {
|
||||
model.setPreserveCase(with.isPreserveCase());
|
||||
}
|
||||
}
|
||||
|
||||
private enum Direction {
|
||||
UP, DOWN
|
||||
}
|
||||
|
||||
@@ -57,9 +57,6 @@ import java.util.EventListener;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchReplaceComponent extends EditorHeaderComponent implements DataProvider {
|
||||
public static final DataKey<SearchReplaceComponent> COMPONENT_KEY = DataKey.create("search-replace-component");
|
||||
public static final DataKey<String> STATUS_TEXT_KEY = DataKey.create("search-replace-status-text");
|
||||
|
||||
private final EventDispatcher<Listener> myEventDispatcher = EventDispatcher.create(Listener.class);
|
||||
|
||||
private final MyTextComponentWrapper mySearchFieldWrapper;
|
||||
@@ -90,7 +87,7 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat
|
||||
private final DataProvider myDataProviderDelegate;
|
||||
|
||||
private boolean myMultilineMode;
|
||||
private String myStatusText;
|
||||
private String myStatusText = "";
|
||||
|
||||
@NotNull
|
||||
public static Builder buildFor(@Nullable Project project, @NotNull JComponent component) {
|
||||
@@ -225,6 +222,11 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat
|
||||
myStatusText = status;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getStatusText() {
|
||||
return myStatusText;
|
||||
}
|
||||
|
||||
public void replace() {
|
||||
if (myReplaceAction != null) {
|
||||
myReplaceAction.run();
|
||||
@@ -258,12 +260,6 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (STATUS_TEXT_KEY.is(dataId)) {
|
||||
return myStatusText;
|
||||
}
|
||||
if (COMPONENT_KEY.is(dataId)) {
|
||||
return this;
|
||||
}
|
||||
if (SpeedSearchSupply.SPEED_SEARCH_CURRENT_QUERY.is(dataId)) {
|
||||
return mySearchTextComponent.getText();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.find;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface SearchSession {
|
||||
DataKey<SearchSession> KEY = DataKey.create("search.replace.session");
|
||||
String INCORRECT_REGEX_MESSAGE = "Incorrect regular expression";
|
||||
|
||||
@NotNull
|
||||
FindModel getFindModel();
|
||||
|
||||
@NotNull
|
||||
SearchReplaceComponent getComponent();
|
||||
|
||||
boolean hasMatches();
|
||||
|
||||
void searchForward();
|
||||
|
||||
void searchBackward();
|
||||
|
||||
void close();
|
||||
}
|
||||
+3
-3
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.SearchSession;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class EditorHeaderSetSearchContextAction extends EditorHeaderToggleAction {
|
||||
@@ -29,12 +29,12 @@ public class EditorHeaderSetSearchContextAction extends EditorHeaderToggleAction
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
protected boolean isSelected(@NotNull SearchSession session) {
|
||||
return session.getFindModel().getSearchContext() == myContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
protected void setSelected(@NotNull SearchSession session, boolean selected) {
|
||||
session.getFindModel().setSearchContext(selected ? myContext : FindModel.SearchContext.ANY);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.SearchSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.actionSystem.ex.CheckboxAction;
|
||||
@@ -34,19 +34,19 @@ public abstract class EditorHeaderToggleAction extends CheckboxAction implements
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
SearchSession search = e.getData(SearchSession.KEY);
|
||||
return search != null && isSelected(search);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean selected) {
|
||||
EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
SearchSession search = e.getData(SearchSession.KEY);
|
||||
if (search != null) {
|
||||
setSelected(search, selected);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isSelected(@NotNull EditorSearchSession session);
|
||||
protected abstract boolean isSelected(@NotNull SearchSession session);
|
||||
|
||||
protected abstract void setSelected(@NotNull EditorSearchSession session, boolean selected);
|
||||
protected abstract void setSelected(@NotNull SearchSession session, boolean selected);
|
||||
}
|
||||
|
||||
+9
-2
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.SearchSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonShortcuts;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
@@ -24,8 +26,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
public final class NextOccurrenceAction extends PrevNextOccurrenceAction {
|
||||
public NextOccurrenceAction(@NotNull Handler handler) {
|
||||
super(IdeActions.ACTION_NEXT_OCCURENCE, handler);
|
||||
public NextOccurrenceAction() {
|
||||
super(IdeActions.ACTION_NEXT_OCCURENCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
e.getRequiredData(SearchSession.KEY).searchForward();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+6
-20
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.SearchReplaceComponent;
|
||||
import com.intellij.find.SearchSession;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -25,28 +25,21 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class PrevNextOccurrenceAction extends DumbAwareAction implements ContextAwareShortcutProvider {
|
||||
private final Handler myHandler;
|
||||
|
||||
PrevNextOccurrenceAction(@NotNull String templateActionId, @NotNull Handler handler) {
|
||||
PrevNextOccurrenceAction(@NotNull String templateActionId) {
|
||||
copyFrom(ActionManager.getInstance().getAction(templateActionId));
|
||||
myHandler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void update(AnActionEvent e) {
|
||||
myHandler.update(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void actionPerformed(AnActionEvent e) {
|
||||
myHandler.actionPerformed(e);
|
||||
SearchSession search = e.getData(SearchSession.KEY);
|
||||
e.getPresentation().setEnabled(search != null && search.hasMatches());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public final ShortcutSet getShortcut(@NotNull DataContext context) {
|
||||
SearchReplaceComponent searchComponent = SearchReplaceComponent.COMPONENT_KEY.getData(context);
|
||||
boolean singleLine = searchComponent != null && !searchComponent.isMultiline();
|
||||
SearchSession search = SearchSession.KEY.getData(context);
|
||||
boolean singleLine = search != null && !search.getFindModel().isMultiline();
|
||||
return Utils.shortcutSetOf(singleLine ? ContainerUtil.concat(getDefaultShortcuts(), getSingleLineShortcuts()) : getDefaultShortcuts());
|
||||
}
|
||||
|
||||
@@ -55,11 +48,4 @@ public abstract class PrevNextOccurrenceAction extends DumbAwareAction implement
|
||||
|
||||
@NotNull
|
||||
protected abstract List<Shortcut> getSingleLineShortcuts();
|
||||
|
||||
|
||||
public interface Handler {
|
||||
void update(AnActionEvent e);
|
||||
|
||||
void actionPerformed(AnActionEvent e);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-2
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.SearchSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.actionSystem.KeyboardShortcut;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
@@ -27,8 +29,13 @@ import java.awt.event.KeyEvent;
|
||||
import java.util.List;
|
||||
|
||||
public final class PrevOccurrenceAction extends PrevNextOccurrenceAction {
|
||||
public PrevOccurrenceAction(@NotNull Handler handler) {
|
||||
super(IdeActions.ACTION_PREVIOUS_OCCURENCE, handler);
|
||||
public PrevOccurrenceAction() {
|
||||
super(IdeActions.ACTION_PREVIOUS_OCCURENCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
e.getRequiredData(SearchSession.KEY).searchBackward();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.SearchReplaceComponent;
|
||||
import com.intellij.find.SearchSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
|
||||
@@ -29,10 +29,11 @@ import java.awt.*;
|
||||
public class StatusTextAction extends DumbAwareAction implements CustomComponentAction {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
String statusText = e.getData(SearchReplaceComponent.STATUS_TEXT_KEY);
|
||||
SearchSession search = e.getData(SearchSession.KEY);
|
||||
String statusText = search == null ? "" : search.getComponent().getStatusText();
|
||||
JLabel label = (JLabel)e.getPresentation().getClientProperty(CUSTOM_COMPONENT_PROPERTY);
|
||||
if (label != null) {
|
||||
label.setText(StringUtil.notNullize(statusText));
|
||||
label.setText(statusText);
|
||||
label.setVisible(StringUtil.isNotEmpty(statusText));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindSettings;
|
||||
import com.intellij.find.SearchSession;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ToggleMatchCase extends EditorHeaderToggleAction {
|
||||
@@ -25,12 +25,12 @@ public class ToggleMatchCase extends EditorHeaderToggleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
protected boolean isSelected(@NotNull SearchSession session) {
|
||||
return session.getFindModel().isCaseSensitive();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
protected void setSelected(@NotNull SearchSession session, boolean selected) {
|
||||
session.getFindModel().setCaseSensitive(selected);
|
||||
FindSettings.getInstance().setLocalCaseSensitive(selected);
|
||||
}
|
||||
|
||||
+3
-2
@@ -17,6 +17,7 @@ package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.SearchSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -35,12 +36,12 @@ public class TogglePreserveCaseAction extends EditorHeaderToggleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
protected boolean isSelected(@NotNull SearchSession session) {
|
||||
return session.getFindModel().isPreserveCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
protected void setSelected(@NotNull SearchSession session, boolean selected) {
|
||||
session.getFindModel().setPreserveCase(selected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.FindSettings;
|
||||
import com.intellij.find.SearchSession;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ToggleRegex extends EditorHeaderToggleAction {
|
||||
@@ -26,12 +26,12 @@ public class ToggleRegex extends EditorHeaderToggleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
protected boolean isSelected(@NotNull SearchSession session) {
|
||||
return session.getFindModel().isRegularExpressions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
protected void setSelected(@NotNull SearchSession session, boolean selected) {
|
||||
FindModel findModel = session.getFindModel();
|
||||
findModel.setRegularExpressions(selected);
|
||||
if (selected) {
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.SearchSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -18,12 +19,12 @@ public class ToggleSelectionOnlyAction extends EditorHeaderToggleAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
protected boolean isSelected(@NotNull SearchSession session) {
|
||||
return !session.getFindModel().isGlobal();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
protected void setSelected(@NotNull SearchSession session, boolean selected) {
|
||||
session.getFindModel().setGlobal(!selected);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
package com.intellij.find.editorHeaderActions;
|
||||
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.FindSettings;
|
||||
import com.intellij.find.SearchSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -14,18 +14,18 @@ public class ToggleWholeWordsOnlyAction extends EditorHeaderToggleAction {
|
||||
public void update(AnActionEvent e) {
|
||||
super.update(e);
|
||||
|
||||
EditorSearchSession session = e.getData(EditorSearchSession.SESSION_KEY);
|
||||
SearchSession session = e.getData(SearchSession.KEY);
|
||||
e.getPresentation().setEnabled(session != null && !session.getFindModel().isRegularExpressions());
|
||||
e.getPresentation().setVisible(session != null && !session.getFindModel().isMultiline());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelected(@NotNull EditorSearchSession session) {
|
||||
protected boolean isSelected(@NotNull SearchSession session) {
|
||||
return session.getFindModel().isWholeWordsOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
|
||||
protected void setSelected(@NotNull SearchSession session, boolean selected) {
|
||||
FindSettings.getInstance().setLocalWholeWordsOnly(selected);
|
||||
session.getFindModel().setWholeWordsOnly(selected);
|
||||
}
|
||||
|
||||
@@ -540,15 +540,7 @@ public abstract class ChooseByNameBase {
|
||||
return; // Allow toolwindows to gain focus (used by QuickDoc shown in a toolwindow)
|
||||
}
|
||||
|
||||
EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
|
||||
if (queue instanceof IdeEventQueue) {
|
||||
if (((IdeEventQueue)queue).wasRootRecentlyClicked(oppositeComponent)) {
|
||||
Component root = SwingUtilities.getRoot(myTextField);
|
||||
if (root == null || root.isShowing()) {
|
||||
hideHint();
|
||||
}
|
||||
}
|
||||
}
|
||||
hideHint();
|
||||
}
|
||||
}
|
||||
}, 5);
|
||||
|
||||
-3
@@ -360,9 +360,6 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable
|
||||
}
|
||||
JDOMUtil.writeDocument(new Document(element), filePath, SystemProperties.getLineSeparator());
|
||||
}
|
||||
catch (WriteExternalException e1) {
|
||||
LOG.error(e1);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
LOG.error(e1);
|
||||
}
|
||||
|
||||
@@ -15,31 +15,43 @@
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.util.ui.JBInsets;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Highlighter;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static java.beans.EventHandler.create;
|
||||
import static java.util.Locale.ENGLISH;
|
||||
|
||||
public class ColorPanel extends JComponent {
|
||||
private final List<ActionListener> myListeners = new CopyOnWriteArrayList<ActionListener>();
|
||||
private final JTextField myTextField = new JTextField();
|
||||
private boolean myEditable;
|
||||
private ActionEvent myEvent;
|
||||
private Color myColor;
|
||||
|
||||
public ColorPanel() {
|
||||
addImpl(myTextField, null, 0);
|
||||
setEditable(true);
|
||||
setMinimumSize(JBUI.size(10, 10));
|
||||
addMouseListener(create(MouseListener.class, this, "onPressed", null, "mousePressed"));
|
||||
addKeyListener(create(KeyListener.class, this, "onPressed", "keyCode", "keyPressed"));
|
||||
addFocusListener(create(FocusListener.class, this, "repaint"));
|
||||
myTextField.addMouseListener(create(MouseListener.class, this, "onPressed", null, "mousePressed"));
|
||||
myTextField.addKeyListener(create(KeyListener.class, this, "onPressed", "keyCode", "keyPressed"));
|
||||
myTextField.setEditable(false);
|
||||
RelativeFont.TINY.install(myTextField);
|
||||
Painter.BACKGROUND.install(myTextField, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") // used from event handler
|
||||
public void onPressed(int keyCode) {
|
||||
if (keyCode == KeyEvent.VK_SPACE) {
|
||||
onPressed();
|
||||
@@ -67,13 +79,10 @@ public class ColorPanel extends JComponent {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
g.setColor(hasFocus() ? JBColor.BLACK : JBColor.border());
|
||||
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
|
||||
if (myColor != null && isEnabled()) {
|
||||
g.setColor(myColor);
|
||||
g.fillRect(2, 2, getWidth() - 4, getHeight() - 4);
|
||||
}
|
||||
public void doLayout() {
|
||||
Rectangle bounds = new Rectangle(getWidth(), getHeight());
|
||||
JBInsets.removeFrom(bounds, getInsets());
|
||||
myTextField.setBounds(bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,26 +90,21 @@ public class ColorPanel extends JComponent {
|
||||
if (isPreferredSizeSet()) {
|
||||
return super.getPreferredSize();
|
||||
}
|
||||
Font font = getFont();
|
||||
Dimension size = new Dimension();
|
||||
Font font = myTextField.getFont();
|
||||
if (font != null) {
|
||||
int size = font.getSize();
|
||||
if (size > 6) {
|
||||
return new Dimension(4 + 2 * size, 4 + size);
|
||||
}
|
||||
FontMetrics fm = myTextField.getFontMetrics(font);
|
||||
size.width = fm.stringWidth(" 000000 ");
|
||||
size.height = fm.getHeight();
|
||||
}
|
||||
return getMinimumSize();
|
||||
JBInsets.addTo(size, myTextField.getInsets());
|
||||
JBInsets.addTo(size, getInsets());
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToolTipText() {
|
||||
if (myColor == null || !isEnabled()) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder buffer = new StringBuilder("0x").append(ColorUtil.toHex(myColor).toUpperCase());
|
||||
if (myEditable && isEnabled()) {
|
||||
buffer.append(" (Click to customize)");
|
||||
}
|
||||
return buffer.toString();
|
||||
return myTextField.getToolTipText();
|
||||
}
|
||||
|
||||
public void removeActionListener(ActionListener actionlistener) {
|
||||
@@ -118,12 +122,91 @@ public class ColorPanel extends JComponent {
|
||||
|
||||
public void setSelectedColor(@Nullable Color color) {
|
||||
myColor = color;
|
||||
repaint();
|
||||
updateSelectedColor();
|
||||
}
|
||||
|
||||
@SuppressWarnings("UseJBColor")
|
||||
private void updateSelectedColor() {
|
||||
boolean enabled = isEnabled();
|
||||
if (enabled && myEditable) {
|
||||
myTextField.setEnabled(true);
|
||||
myTextField.setToolTipText(UIBundle.message("color.panel.select.color.tooltip.text"));
|
||||
}
|
||||
else {
|
||||
myTextField.setEnabled(false);
|
||||
myTextField.setToolTipText(null);
|
||||
}
|
||||
Color color = enabled ? myColor : null;
|
||||
if (color != null) {
|
||||
myTextField.setText(' ' + ColorUtil.toHex(color).toUpperCase(ENGLISH) + ' ');
|
||||
}
|
||||
else {
|
||||
myTextField.setText(null);
|
||||
color = getBackground();
|
||||
}
|
||||
myTextField.setBackground(color);
|
||||
myTextField.setSelectedTextColor(color);
|
||||
if (color != null) {
|
||||
int gray = (int)(0.212656 * color.getRed() + 0.715158 * color.getGreen() + 0.072186 * color.getBlue());
|
||||
int delta = gray < 0x20 ? 0x60 : gray < 0x50 ? 0x40 : gray < 0x80 ? 0x20 : gray < 0xB0 ? -0x20 : gray < 0xE0 ? -0x40 : -0x60;
|
||||
gray += delta;
|
||||
color = new Color(gray, gray, gray);
|
||||
myTextField.setDisabledTextColor(color);
|
||||
myTextField.setSelectionColor(color);
|
||||
gray += delta;
|
||||
color = new Color(gray, gray, gray);
|
||||
myTextField.setForeground(color);
|
||||
}
|
||||
}
|
||||
|
||||
public void setEditable(boolean editable) {
|
||||
myEditable = editable;
|
||||
setFocusable(editable);
|
||||
repaint();
|
||||
updateSelectedColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
updateSelectedColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repaint() {
|
||||
super.repaint();
|
||||
}
|
||||
|
||||
private static class Painter implements Highlighter.HighlightPainter, PropertyChangeListener {
|
||||
private static final String PROPERTY = "highlighter";
|
||||
private static final Painter BACKGROUND = new Painter();
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, int p0, int p1, Shape shape, JTextComponent component) {
|
||||
Color color = component.getBackground();
|
||||
if (color != null) {
|
||||
g.setColor(color);
|
||||
Rectangle bounds = shape instanceof Rectangle ? (Rectangle)shape : shape.getBounds();
|
||||
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
Object source = event.getSource();
|
||||
if ((source instanceof JTextComponent) && PROPERTY.equals(event.getPropertyName())) {
|
||||
install((JTextComponent)source, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void install(JTextComponent component, boolean listener) {
|
||||
try {
|
||||
Highlighter highlighter = component.getHighlighter();
|
||||
if (highlighter != null) highlighter.addHighlight(0, 0, this);
|
||||
}
|
||||
catch (BadLocationException ignored) {
|
||||
}
|
||||
if (listener) {
|
||||
component.addPropertyChangeListener(PROPERTY, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.ui.components;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.ui.GraphicsConfig;
|
||||
import com.intellij.openapi.ui.JBMenuItem;
|
||||
import com.intellij.openapi.ui.JBPopupMenu;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
@@ -26,6 +27,7 @@ import com.intellij.openapi.util.Weighted;
|
||||
import com.intellij.openapi.wm.IdeGlassPane;
|
||||
import com.intellij.openapi.wm.IdeGlassPaneUtil;
|
||||
import com.intellij.ui.ScreenUtil;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.JBInsets;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -362,10 +364,12 @@ public class JBOptionButton extends JButton implements MouseMotionListener, Weig
|
||||
protected void paintChildren(Graphics g) {
|
||||
super.paintChildren(g);
|
||||
if (SystemInfo.isMac && UIUtil.isUnderIntelliJLaF()) {
|
||||
int x = getWidth() - getInsets().right - 8;
|
||||
int x = getWidth() - getInsets().right - 10;
|
||||
Icon icon = AllIcons.Mac.YosemiteOptionButtonSelector;
|
||||
int y = (getHeight() - icon.getIconHeight()) / 2;
|
||||
GraphicsConfig config = isEnabled() ? new GraphicsConfig(g) : GraphicsUtil.paintWithAlpha(g, 0.6f);
|
||||
icon.paintIcon(this, g, x, y);
|
||||
config.restore();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.basic.ComboPopup;
|
||||
import java.applet.Applet;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
@@ -636,11 +637,6 @@ public class IdeEventQueue extends EventQueue {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (me.getButton() != 0) {
|
||||
setLastClickEvent(me);
|
||||
} else if (lastClickEvent != null && Math.abs(System.currentTimeMillis() - lastClickTime) > 200){
|
||||
setLastClickEvent(null);//Obsolete event
|
||||
}
|
||||
if (!myMouseEventDispatcher.dispatchMouseEvent(me)) {
|
||||
defaultDispatchEvent(e);
|
||||
}
|
||||
@@ -684,19 +680,6 @@ public class IdeEventQueue extends EventQueue {
|
||||
}
|
||||
}
|
||||
|
||||
private MouseEvent lastClickEvent;
|
||||
private long lastClickTime;
|
||||
|
||||
private void setLastClickEvent(@Nullable MouseEvent event) {
|
||||
lastClickEvent = event;
|
||||
lastClickTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public boolean wasRootRecentlyClicked(Component component) {
|
||||
return component != null && lastClickEvent != null && lastClickEvent.getComponent() != null &&
|
||||
SwingUtilities.getRoot(lastClickEvent.getComponent()) == SwingUtilities.getRoot(component);
|
||||
}
|
||||
|
||||
private static void fixStickyWindow(KeyboardFocusManager mgr, Window wnd, String resetMethod) {
|
||||
Window showingWindow = wnd;
|
||||
|
||||
|
||||
+15
-15
@@ -19,7 +19,6 @@ import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.util.ElementsChooser;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.components.ExportableComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
@@ -32,6 +31,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.FieldPanel;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import gnu.trove.THashSet;
|
||||
@@ -57,14 +57,14 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
|
||||
private final boolean myShowFilePath;
|
||||
private final String myDescription;
|
||||
|
||||
public ChooseComponentsToExportDialog(@NotNull MultiMap<File, ExportableComponent> fileToComponents,
|
||||
public ChooseComponentsToExportDialog(@NotNull MultiMap<File, ExportableItem> fileToComponents,
|
||||
boolean showFilePath, final String title, String description) {
|
||||
super(false);
|
||||
|
||||
myDescription = description;
|
||||
myShowFilePath = showFilePath;
|
||||
Map<ExportableComponent, ComponentElementProperties> componentToContainingListElement = new LinkedHashMap<ExportableComponent, ComponentElementProperties>();
|
||||
for (ExportableComponent component : fileToComponents.values()) {
|
||||
Map<ExportableItem, ComponentElementProperties> componentToContainingListElement = new LinkedHashMap<ExportableItem, ComponentElementProperties>();
|
||||
for (ExportableItem component : fileToComponents.values()) {
|
||||
if (!addToExistingListElement(component, componentToContainingListElement, fileToComponents)) {
|
||||
ComponentElementProperties componentElementProperties = new ComponentElementProperties();
|
||||
componentElementProperties.addComponent(component);
|
||||
@@ -147,12 +147,12 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
private static boolean addToExistingListElement(@NotNull ExportableComponent component,
|
||||
@NotNull Map<ExportableComponent, ComponentElementProperties> componentToContainingListElement,
|
||||
@NotNull MultiMap<File, ExportableComponent> fileToComponents) {
|
||||
private static boolean addToExistingListElement(@NotNull ExportableItem component,
|
||||
@NotNull Map<ExportableItem, ComponentElementProperties> componentToContainingListElement,
|
||||
@NotNull MultiMap<File, ExportableItem> fileToComponents) {
|
||||
File file = null;
|
||||
for (File exportFile : component.getExportFiles()) {
|
||||
for (ExportableComponent tiedComponent : fileToComponents.get(exportFile)) {
|
||||
for (File exportFile : component.getFiles()) {
|
||||
for (ExportableItem tiedComponent : fileToComponents.get(exportFile)) {
|
||||
if (tiedComponent == component) {
|
||||
continue;
|
||||
}
|
||||
@@ -234,8 +234,8 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
|
||||
return panel;
|
||||
}
|
||||
|
||||
Set<ExportableComponent> getExportableComponents() {
|
||||
Set<ExportableComponent> components = new THashSet<ExportableComponent>();
|
||||
Set<ExportableItem> getExportableComponents() {
|
||||
Set<ExportableItem> components = new THashSet<ExportableItem>();
|
||||
for (ComponentElementProperties elementProperties : myChooser.getMarkedElements()) {
|
||||
components.addAll(elementProperties.myComponents);
|
||||
}
|
||||
@@ -243,9 +243,9 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
private static class ComponentElementProperties implements ElementsChooser.ElementProperties {
|
||||
private final Set<ExportableComponent> myComponents = new HashSet<ExportableComponent>();
|
||||
private final Set<ExportableItem> myComponents = new HashSet<ExportableItem>();
|
||||
|
||||
private boolean addComponent(ExportableComponent component) {
|
||||
private boolean addComponent(ExportableItem component) {
|
||||
return myComponents.add(component);
|
||||
}
|
||||
|
||||
@@ -263,10 +263,10 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
|
||||
|
||||
public String toString() {
|
||||
Set<String> names = new LinkedHashSet<String>();
|
||||
for (ExportableComponent component : myComponents) {
|
||||
for (ExportableItem component : myComponents) {
|
||||
names.add(component.getPresentableName());
|
||||
}
|
||||
return StringUtil.join(names.toArray(new String[names.size()]), ", ");
|
||||
return StringUtil.join(ArrayUtil.toStringArray(names), ", ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,332 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.AbstractBundle;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.ide.plugins.PluginManagerCore;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationImpl;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.components.impl.ServiceManagerImpl;
|
||||
import com.intellij.openapi.components.impl.stores.StateStorageManager;
|
||||
import com.intellij.openapi.components.impl.stores.StoreUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.PluginDescriptor;
|
||||
import com.intellij.openapi.options.OptionsBundle;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.util.PairProcessor;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.io.ZipUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public class ExportSettingsAction extends AnAction implements DumbAware {
|
||||
private static final Logger LOG = Logger.getInstance(ExportSettingsAction.class);
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@Nullable AnActionEvent e) {
|
||||
ApplicationManager.getApplication().saveSettings();
|
||||
|
||||
ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(getExportableComponentsMap(true, true), true,
|
||||
IdeBundle.message("title.select.components.to.export"),
|
||||
IdeBundle.message(
|
||||
"prompt.please.check.all.components.to.export"));
|
||||
if (!dialog.showAndGet()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<ExportableComponent> markedComponents = dialog.getExportableComponents();
|
||||
if (markedComponents.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<File> exportFiles = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
for (ExportableComponent markedComponent : markedComponents) {
|
||||
ContainerUtil.addAll(exportFiles, markedComponent.getExportFiles());
|
||||
}
|
||||
|
||||
final File saveFile = dialog.getExportFile();
|
||||
try {
|
||||
if (saveFile.exists() && Messages.showOkCancelDialog(
|
||||
IdeBundle.message("prompt.overwrite.settings.file", FileUtil.toSystemDependentName(saveFile.getPath())),
|
||||
IdeBundle.message("title.file.already.exists"), Messages.getWarningIcon()) != Messages.OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
MyZipOutputStream zipOut = new MyZipOutputStream(new BufferedOutputStream(new FileOutputStream(saveFile)));
|
||||
try {
|
||||
Set<String> writtenItemRelativePaths = new THashSet<String>();
|
||||
String configRoot = FileUtilRt.toSystemIndependentName(PathManager.getConfigPath());
|
||||
for (File file : exportFiles) {
|
||||
if (file.exists()) {
|
||||
String relativePath = FileUtilRt.getRelativePath(configRoot, FileUtilRt.toSystemIndependentName(file.getAbsolutePath()), '/');
|
||||
assert relativePath != null;
|
||||
ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths);
|
||||
}
|
||||
}
|
||||
|
||||
exportInstalledPlugins(zipOut);
|
||||
|
||||
ZipEntry zipEntry = new ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER);
|
||||
zipOut.putNextEntry(zipEntry);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
finally {
|
||||
zipOut.doClose();
|
||||
}
|
||||
ShowFilePathAction.showDialog(getEventProject(e), IdeBundle.message("message.settings.exported.successfully"),
|
||||
IdeBundle.message("title.export.successful"), saveFile, null);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
Messages.showErrorDialog(IdeBundle.message("error.writing.settings", e1.toString()), IdeBundle.message("title.error.writing.file"));
|
||||
}
|
||||
}
|
||||
|
||||
private static void exportInstalledPlugins(@NotNull MyZipOutputStream zipOut) throws IOException {
|
||||
List<String> plugins = new ArrayList<String>();
|
||||
for (IdeaPluginDescriptor descriptor : PluginManagerCore.getPlugins()) {
|
||||
if (!descriptor.isBundled() && descriptor.isEnabled()) {
|
||||
plugins.add(descriptor.getPluginId().getIdString());
|
||||
}
|
||||
}
|
||||
if (plugins.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZipEntry e = new ZipEntry(PluginManager.INSTALLED_TXT);
|
||||
zipOut.putNextEntry(e);
|
||||
try {
|
||||
PluginManagerCore.writePluginsList(plugins, new OutputStreamWriter(zipOut, CharsetToolkit.UTF8_CHARSET));
|
||||
}
|
||||
finally {
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyZipOutputStream extends ZipOutputStream {
|
||||
private boolean ignoreClose = true;
|
||||
|
||||
public MyZipOutputStream(@NotNull OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (!ignoreClose) {
|
||||
doClose();
|
||||
}
|
||||
}
|
||||
|
||||
public void doClose() throws IOException {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MultiMap<File, ExportableComponent> getExportableComponentsMap(boolean onlyExisting, boolean computePresentableNames) {
|
||||
ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication();
|
||||
StateStorageManager storageManager = ComponentsPackage.getStateStore(application).getStateStorageManager();
|
||||
return getExportableComponentsMap(onlyExisting, computePresentableNames, storageManager);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MultiMap<File, ExportableComponent> getExportableComponentsMap(final boolean onlyExisting, final boolean computePresentableNames, final @NotNull StateStorageManager storageManager) {
|
||||
@SuppressWarnings("deprecation")
|
||||
List<ExportableApplicationComponent> components1 = ComponentsPackage.getComponents(ApplicationManager.getApplication(), ExportableApplicationComponent.class);
|
||||
List<ExportableComponent> components2 = ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent.class);
|
||||
final MultiMap<File, ExportableComponent> result = MultiMap.createLinkedSet();
|
||||
for (ExportableComponent component : ContainerUtil.concat(components1, components2)) {
|
||||
for (File exportFile : component.getExportFiles()) {
|
||||
result.putValue(exportFile, component);
|
||||
}
|
||||
}
|
||||
|
||||
if (onlyExisting) {
|
||||
for (Iterator<File> it = result.keySet().iterator(); it.hasNext(); ) {
|
||||
if (!it.next().exists()) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ServiceManagerImpl.processAllImplementationClasses((ApplicationImpl)ApplicationManager.getApplication(), new PairProcessor<Class<?>, PluginDescriptor>() {
|
||||
@Override
|
||||
public boolean process(@NotNull Class<?> aClass, @Nullable PluginDescriptor pluginDescriptor) {
|
||||
State stateAnnotation = StoreUtil.getStateSpec(aClass);
|
||||
if (stateAnnotation != null && !StringUtil.isEmpty(stateAnnotation.name())) {
|
||||
if (ExportableComponent.class.isAssignableFrom(aClass)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int storageIndex;
|
||||
Storage[] storages = stateAnnotation.storages();
|
||||
if (storages.length == 1) {
|
||||
storageIndex = 0;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
|
||||
Storage storage = storages[storageIndex];
|
||||
if (storage.roamingType() != RoamingType.DISABLED &&
|
||||
storage.storageClass().equals(StateStorage.class) &&
|
||||
storage.scheme() == StorageScheme.DEFAULT &&
|
||||
!StringUtil.isEmpty(storage.file()) &&
|
||||
storage.file().startsWith(StoragePathMacros.APP_CONFIG)) {
|
||||
|
||||
File additionalExportFile = null;
|
||||
if (!StringUtil.isEmpty(stateAnnotation.additionalExportFile())) {
|
||||
String expandedPath = storageManager.expandMacros(stateAnnotation.additionalExportFile());
|
||||
additionalExportFile = new File(expandedPath);
|
||||
if (!additionalExportFile.exists()) {
|
||||
//noinspection deprecation
|
||||
additionalExportFile = new File(storageManager.expandMacros(StoragePathMacros.ROOT_CONFIG) + '/' + expandedPath);
|
||||
}
|
||||
|
||||
if (onlyExisting && !additionalExportFile.exists()) {
|
||||
additionalExportFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
File file = new File(storageManager.expandMacros(storage.file()));
|
||||
boolean fileExists = !onlyExisting || file.exists();
|
||||
if (fileExists || additionalExportFile != null) {
|
||||
File[] files;
|
||||
if (additionalExportFile == null) {
|
||||
files = new File[]{file};
|
||||
}
|
||||
else {
|
||||
files = fileExists ? new File[]{file, additionalExportFile} : new File[]{additionalExportFile};
|
||||
}
|
||||
ExportableComponentItem item = new ExportableComponentItem(files,
|
||||
computePresentableNames
|
||||
? getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor)
|
||||
: "",
|
||||
storage.roamingType());
|
||||
result.putValue(file, item);
|
||||
if (additionalExportFile != null) {
|
||||
result.putValue(additionalExportFile, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getComponentPresentableName(@NotNull State state, @NotNull Class<?> aClass, @Nullable PluginDescriptor pluginDescriptor) {
|
||||
if (state.presentableName() != State.NameGetter.class) {
|
||||
try {
|
||||
return ReflectionUtil.newInstance(state.presentableName()).get();
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
String defaultName = state.name();
|
||||
String resourceBundleName;
|
||||
if (pluginDescriptor != null && pluginDescriptor instanceof IdeaPluginDescriptor && !"com.intellij".equals(pluginDescriptor.getPluginId().getIdString())) {
|
||||
resourceBundleName = ((IdeaPluginDescriptor)pluginDescriptor).getResourceBundleBaseName();
|
||||
}
|
||||
else {
|
||||
resourceBundleName = OptionsBundle.PATH_TO_BUNDLE;
|
||||
}
|
||||
|
||||
if (resourceBundleName == null) {
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
ClassLoader classLoader = pluginDescriptor == null ? null : pluginDescriptor.getPluginClassLoader();
|
||||
classLoader = classLoader == null ? aClass.getClassLoader() : classLoader;
|
||||
if (classLoader != null) {
|
||||
String message = messageOrDefault(classLoader, resourceBundleName, defaultName);
|
||||
if (message != defaultName) {
|
||||
return message;
|
||||
}
|
||||
|
||||
if (PlatformUtils.isRubyMine()) {
|
||||
// ruby plugin in RubyMine has id "com.intellij", so, we cannot set "resource-bundle" in plugin.xml
|
||||
return messageOrDefault(classLoader, "org.jetbrains.plugins.ruby.RBundle", defaultName);
|
||||
}
|
||||
}
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String messageOrDefault(@NotNull ClassLoader classLoader, @NotNull String bundleName, @NotNull String defaultName) {
|
||||
ResourceBundle bundle = AbstractBundle.getResourceBundle(bundleName, classLoader);
|
||||
return bundle == null ? defaultName : CommonBundle.messageOrDefault(bundle, "exportable." + defaultName + ".presentable.name", defaultName);
|
||||
}
|
||||
|
||||
public static final class ExportableComponentItem implements ExportableComponent {
|
||||
private final File[] files;
|
||||
private final String name;
|
||||
private final RoamingType roamingType;
|
||||
|
||||
public ExportableComponentItem(@NotNull File[] files, @NotNull String name, @NotNull RoamingType roamingType) {
|
||||
this.files = files;
|
||||
this.name = name;
|
||||
this.roamingType = roamingType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public File[] getExportFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RoamingType getRoamingType() {
|
||||
return roamingType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ide.actions
|
||||
|
||||
import com.intellij.AbstractBundle
|
||||
import com.intellij.CommonBundle
|
||||
import com.intellij.ide.IdeBundle
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor
|
||||
import com.intellij.ide.plugins.PluginManager
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.application.impl.ApplicationImpl
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.components.impl.ServiceManagerImpl
|
||||
import com.intellij.openapi.components.impl.stores.StateStorageManager
|
||||
import com.intellij.openapi.components.impl.stores.StoreUtil
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.extensions.PluginDescriptor
|
||||
import com.intellij.openapi.options.OptionsBundle
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.CharsetToolkit
|
||||
import com.intellij.util.PairProcessor
|
||||
import com.intellij.util.PlatformUtils
|
||||
import com.intellij.util.ReflectionUtil
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import com.intellij.util.io.ZipUtil
|
||||
import gnu.trove.THashSet
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
private class ExportSettingsAction : AnAction(), DumbAware {
|
||||
override fun actionPerformed(e: AnActionEvent?) {
|
||||
ApplicationManager.getApplication().saveSettings()
|
||||
|
||||
val dialog = ChooseComponentsToExportDialog(getExportableComponentsMap(true, true), true,
|
||||
IdeBundle.message("title.select.components.to.export"),
|
||||
IdeBundle.message(
|
||||
"prompt.please.check.all.components.to.export"))
|
||||
if (!dialog.showAndGet()) {
|
||||
return
|
||||
}
|
||||
|
||||
val markedComponents = dialog.exportableComponents
|
||||
if (markedComponents.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val exportFiles = THashSet(FileUtil.FILE_HASHING_STRATEGY)
|
||||
for (markedComponent in markedComponents) {
|
||||
exportFiles.addAll(markedComponent.files)
|
||||
}
|
||||
|
||||
val saveFile = dialog.exportFile
|
||||
try {
|
||||
if (saveFile.exists() && Messages.showOkCancelDialog(
|
||||
IdeBundle.message("prompt.overwrite.settings.file", FileUtil.toSystemDependentName(saveFile.path)),
|
||||
IdeBundle.message("title.file.already.exists"), Messages.getWarningIcon()) != Messages.OK) {
|
||||
return
|
||||
}
|
||||
|
||||
val zipOut = MyZipOutputStream(BufferedOutputStream(FileOutputStream(saveFile)))
|
||||
try {
|
||||
val writtenItemRelativePaths = THashSet<String>()
|
||||
val configRoot = FileUtilRt.toSystemIndependentName(PathManager.getConfigPath())
|
||||
for (file in exportFiles) {
|
||||
if (file.exists()) {
|
||||
val relativePath = FileUtilRt.getRelativePath(configRoot, FileUtilRt.toSystemIndependentName(file.absolutePath), '/')!!
|
||||
ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths)
|
||||
}
|
||||
}
|
||||
|
||||
exportInstalledPlugins(zipOut)
|
||||
|
||||
val zipEntry = ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER)
|
||||
zipOut.putNextEntry(zipEntry)
|
||||
zipOut.closeEntry()
|
||||
}
|
||||
finally {
|
||||
zipOut.doClose()
|
||||
}
|
||||
ShowFilePathAction.showDialog(AnAction.getEventProject(e), IdeBundle.message("message.settings.exported.successfully"),
|
||||
IdeBundle.message("title.export.successful"), saveFile, null)
|
||||
}
|
||||
catch (e1: IOException) {
|
||||
Messages.showErrorDialog(IdeBundle.message("error.writing.settings", e1.toString()), IdeBundle.message("title.error.writing.file"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyZipOutputStream(out: OutputStream) : ZipOutputStream(out) {
|
||||
override fun close() {
|
||||
}
|
||||
|
||||
fun doClose() {
|
||||
super.close()
|
||||
}
|
||||
}
|
||||
|
||||
data class ExportableItem(val files: List<File>, val presentableName: String, val roamingType: RoamingType)
|
||||
|
||||
private val LOG = Logger.getInstance(ExportSettingsAction::class.java)
|
||||
|
||||
private fun exportInstalledPlugins(zipOut: MyZipOutputStream) {
|
||||
val plugins = ArrayList<String>()
|
||||
for (descriptor in PluginManagerCore.getPlugins()) {
|
||||
if (!descriptor.isBundled && descriptor.isEnabled) {
|
||||
plugins.add(descriptor.pluginId.idString)
|
||||
}
|
||||
}
|
||||
if (plugins.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val e = ZipEntry(PluginManager.INSTALLED_TXT)
|
||||
zipOut.putNextEntry(e)
|
||||
try {
|
||||
PluginManagerCore.writePluginsList(plugins, OutputStreamWriter(zipOut, CharsetToolkit.UTF8_CHARSET))
|
||||
}
|
||||
finally {
|
||||
zipOut.closeEntry()
|
||||
}
|
||||
}
|
||||
|
||||
fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: Boolean, storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.stateStorageManager): MultiMap<File, ExportableItem> {
|
||||
val result = MultiMap.createLinkedSet<File, ExportableItem>()
|
||||
val processor = { component: ExportableComponent ->
|
||||
val item = ExportableItem(component.exportFiles.toList(), component.presentableName, RoamingType.DEFAULT)
|
||||
for (exportFile in item.files) {
|
||||
result.putValue(exportFile, item)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
|
||||
ApplicationManager.getApplication().getComponents(ExportableApplicationComponent::class.java).forEach(processor)
|
||||
ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent::class.java).forEach(processor)
|
||||
|
||||
if (onlyExisting) {
|
||||
val it = result.keySet().iterator()
|
||||
while (it.hasNext()) {
|
||||
if (!it.next().exists()) {
|
||||
it.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ServiceManagerImpl.processAllImplementationClasses(ApplicationManager.getApplication() as ApplicationImpl, object : PairProcessor<Class<*>, PluginDescriptor> {
|
||||
override fun process(aClass: Class<*>, pluginDescriptor: PluginDescriptor?): Boolean {
|
||||
val stateAnnotation = StoreUtil.getStateSpec(aClass)
|
||||
if (stateAnnotation != null && !StringUtil.isEmpty(stateAnnotation.name)) {
|
||||
if (ExportableComponent::class.java.isAssignableFrom(aClass)) {
|
||||
return true
|
||||
}
|
||||
|
||||
val storageIndex: Int
|
||||
val storages = stateAnnotation.storages
|
||||
if (storages.size() == 1) {
|
||||
storageIndex = 0
|
||||
}
|
||||
else {
|
||||
return true
|
||||
}
|
||||
|
||||
val storage = storages[storageIndex]
|
||||
if (storage.roamingType != RoamingType.DISABLED && storage.storageClass == StateStorage::class && storage.scheme == StorageScheme.DEFAULT && !storage.file.isNullOrEmpty()) {
|
||||
var additionalExportFile: File? = null
|
||||
var additionalExportPath = stateAnnotation.additionalExportFile
|
||||
if (additionalExportPath.isNotEmpty()) {
|
||||
// backward compatibility - path can contain macro
|
||||
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
|
||||
if (additionalExportPath[0] != '$') {
|
||||
additionalExportPath = StoragePathMacros.ROOT_CONFIG + "/" + additionalExportPath
|
||||
}
|
||||
additionalExportFile = File(storageManager.expandMacros(additionalExportPath))
|
||||
if (onlyExisting && !additionalExportFile.exists()) {
|
||||
additionalExportFile = null
|
||||
}
|
||||
}
|
||||
|
||||
val file = File(storageManager.expandMacros(storage.file))
|
||||
val fileExists = !onlyExisting || file.exists()
|
||||
if (fileExists || additionalExportFile != null) {
|
||||
val files = if (additionalExportFile == null) listOf(file) else if (fileExists) listOf(file, additionalExportFile) else listOf(additionalExportFile)
|
||||
val item = ExportableItem(files, if (computePresentableNames) getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) else "", storage.roamingType)
|
||||
result.putValue(file, item)
|
||||
if (additionalExportFile != null) {
|
||||
result.putValue(additionalExportFile, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getComponentPresentableName(state: State, aClass: Class<*>, pluginDescriptor: PluginDescriptor?): String {
|
||||
val presentableName = state.presentableName.java
|
||||
if (presentableName != State.NameGetter::class.java) {
|
||||
try {
|
||||
return ReflectionUtil.newInstance(presentableName).get()
|
||||
}
|
||||
catch (e: Exception) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
val defaultName = state.name
|
||||
val resourceBundleName = (if (pluginDescriptor is IdeaPluginDescriptor && "com.intellij" != pluginDescriptor.pluginId.idString) {
|
||||
pluginDescriptor.resourceBundleBaseName
|
||||
}
|
||||
else {
|
||||
OptionsBundle.PATH_TO_BUNDLE
|
||||
}) ?: return defaultName
|
||||
|
||||
var classLoader = pluginDescriptor?.pluginClassLoader ?: aClass.classLoader
|
||||
if (classLoader != null) {
|
||||
val message = messageOrDefault(classLoader, resourceBundleName, defaultName)
|
||||
if (message !== defaultName) {
|
||||
return message
|
||||
}
|
||||
|
||||
if (PlatformUtils.isRubyMine()) {
|
||||
// ruby plugin in RubyMine has id "com.intellij", so, we cannot set "resource-bundle" in plugin.xml
|
||||
return messageOrDefault(classLoader, "org.jetbrains.plugins.ruby.RBundle", defaultName)
|
||||
}
|
||||
}
|
||||
return defaultName
|
||||
}
|
||||
|
||||
private fun messageOrDefault(classLoader: ClassLoader, bundleName: String, defaultName: String): String {
|
||||
val bundle = AbstractBundle.getResourceBundle(bundleName, classLoader) ?: return defaultName
|
||||
return CommonBundle.messageOrDefault(bundle, "exportable.$defaultName.presentable.name", defaultName)
|
||||
}
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.ide.startup.StartupActionScriptManager;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
import com.intellij.openapi.components.ExportableComponent;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.updateSettings.impl.UpdateSettings;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class ImportSettingsAction extends AnAction implements DumbAware {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
final DataContext dataContext = e.getDataContext();
|
||||
final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);
|
||||
ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, IdeBundle.message("title.import.file.location"), IdeBundle.message("prompt.choose.import.file.path")).doWhenDone(new Consumer<String>() {
|
||||
@Override
|
||||
public void consume(String path) {
|
||||
File saveFile = new File(path);
|
||||
try {
|
||||
doImport(saveFile);
|
||||
}
|
||||
catch (ZipException e1) {
|
||||
Messages.showErrorDialog(
|
||||
IdeBundle.message("error.reading.settings.file", presentableFileName(saveFile), e1.getMessage(), promptLocationMessage()),
|
||||
IdeBundle.message("title.invalid.file"));
|
||||
}
|
||||
catch (IOException e1) {
|
||||
Messages.showErrorDialog(IdeBundle.message("error.reading.settings.file.2", presentableFileName(saveFile), e1.getMessage()),
|
||||
IdeBundle.message("title.error.reading.file"));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void doImport(@NotNull File saveFile) throws IOException {
|
||||
if (!saveFile.exists()) {
|
||||
Messages.showErrorDialog(IdeBundle.message("error.cannot.find.file", presentableFileName(saveFile)),
|
||||
IdeBundle.message("title.file.not.found"));
|
||||
return;
|
||||
}
|
||||
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
final ZipEntry magicEntry = new ZipFile(saveFile).getEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER);
|
||||
if (magicEntry == null) {
|
||||
Messages.showErrorDialog(
|
||||
IdeBundle.message("error.file.contains.no.settings.to.import", presentableFileName(saveFile), promptLocationMessage()),
|
||||
IdeBundle.message("title.invalid.file"));
|
||||
return;
|
||||
}
|
||||
|
||||
MultiMap<File, ExportableComponent> fileToComponents = ExportSettingsAction.getExportableComponentsMap(false, true);
|
||||
List<ExportableComponent> components = getComponentsStored(saveFile, fileToComponents.values());
|
||||
fileToComponents.values().retainAll(components);
|
||||
final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(fileToComponents, false,
|
||||
IdeBundle.message("title.select.components.to.import"),
|
||||
IdeBundle.message("prompt.check.components.to.import"));
|
||||
if (!dialog.showAndGet()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Set<ExportableComponent> chosenComponents = dialog.getExportableComponents();
|
||||
Set<String> relativeNamesToExtract = new THashSet<String>();
|
||||
for (ExportableComponent chosenComponent : chosenComponents) {
|
||||
for (File exportFile : chosenComponent.getExportFiles()) {
|
||||
String rPath = FileUtilRt.getRelativePath(new File(PathManager.getConfigPath()), exportFile);
|
||||
assert rPath != null;
|
||||
relativeNamesToExtract.add(FileUtil.toSystemIndependentName(rPath));
|
||||
}
|
||||
}
|
||||
|
||||
relativeNamesToExtract.add(PluginManager.INSTALLED_TXT);
|
||||
|
||||
final File tempFile = new File(PathManager.getPluginTempPath() + "/" + saveFile.getName());
|
||||
FileUtil.copy(saveFile, tempFile);
|
||||
File outDir = new File(PathManager.getConfigPath());
|
||||
final ImportSettingsFilenameFilter filenameFilter = new ImportSettingsFilenameFilter(relativeNamesToExtract);
|
||||
StartupActionScriptManager.addActionCommand(new StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter));
|
||||
// remove temp file
|
||||
StartupActionScriptManager.addActionCommand(new StartupActionScriptManager.DeleteCommand(tempFile));
|
||||
|
||||
UpdateSettings.getInstance().forceCheckForUpdateAfterRestart();
|
||||
|
||||
String key = ApplicationManager.getApplication().isRestartCapable()
|
||||
? "message.settings.imported.successfully.restart"
|
||||
: "message.settings.imported.successfully";
|
||||
if (Messages.showOkCancelDialog(IdeBundle.message(key,
|
||||
ApplicationNamesInfo.getInstance().getProductName(),
|
||||
ApplicationNamesInfo.getInstance().getFullProductName()),
|
||||
IdeBundle.message("title.restart.needed"), Messages.getQuestionIcon()) == Messages.OK) {
|
||||
((ApplicationEx)ApplicationManager.getApplication()).restart(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static String presentableFileName(@NotNull File file) {
|
||||
return "'" + FileUtil.toSystemDependentName(file.getPath()) + "'";
|
||||
}
|
||||
|
||||
private static String promptLocationMessage() {
|
||||
return IdeBundle.message("message.please.ensure.correct.settings");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<ExportableComponent> getComponentsStored(@NotNull File settings,
|
||||
@NotNull Collection<? extends ExportableComponent> registeredComponents) throws IOException {
|
||||
THashSet<String> zipEntries = new THashSet<String>();
|
||||
ZipFile zip = new ZipFile(settings);
|
||||
try {
|
||||
Enumeration enumeration = zip.entries();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
ZipEntry zipEntry = (ZipEntry)enumeration.nextElement();
|
||||
zipEntries.add(zipEntry.getName());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
zip.close();
|
||||
}
|
||||
|
||||
File configPath = new File(PathManager.getConfigPath());
|
||||
List<ExportableComponent> components = new ArrayList<ExportableComponent>();
|
||||
|
||||
for (ExportableComponent component : registeredComponents) {
|
||||
for (File exportFile : component.getExportFiles()) {
|
||||
String relativePath = FileUtilRt.getRelativePath(configPath, exportFile);
|
||||
assert relativePath != null;
|
||||
relativePath = FileUtilRt.toSystemIndependentName(relativePath);
|
||||
if (exportFile.getName().indexOf('.') == -1 && !exportFile.isFile()) {
|
||||
relativePath += '/';
|
||||
}
|
||||
if (zipEntries.contains(relativePath)) {
|
||||
components.add(component);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ide.actions
|
||||
|
||||
import com.intellij.ide.IdeBundle
|
||||
import com.intellij.ide.plugins.PluginManager
|
||||
import com.intellij.ide.startup.StartupActionScriptManager
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.application.ex.ApplicationEx
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.updateSettings.impl.UpdateSettings
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import com.intellij.util.Consumer
|
||||
import gnu.trove.THashSet
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import java.util.zip.ZipException
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
private class ImportSettingsAction : AnAction(), DumbAware {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val dataContext = e.dataContext
|
||||
val component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext)
|
||||
ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, IdeBundle.message("title.import.file.location"), IdeBundle.message("prompt.choose.import.file.path")).doWhenDone(object : Consumer<String> {
|
||||
override fun consume(path: String) {
|
||||
val saveFile = File(path)
|
||||
try {
|
||||
doImport(saveFile)
|
||||
}
|
||||
catch (e1: ZipException) {
|
||||
Messages.showErrorDialog(
|
||||
IdeBundle.message("error.reading.settings.file", presentableFileName(saveFile), e1.getMessage(), promptLocationMessage()),
|
||||
IdeBundle.message("title.invalid.file"))
|
||||
}
|
||||
catch (e1: IOException) {
|
||||
Messages.showErrorDialog(IdeBundle.message("error.reading.settings.file.2", presentableFileName(saveFile), e1.getMessage()),
|
||||
IdeBundle.message("title.error.reading.file"))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun doImport(saveFile: File) {
|
||||
if (!saveFile.exists()) {
|
||||
Messages.showErrorDialog(IdeBundle.message("error.cannot.find.file", presentableFileName(saveFile)),
|
||||
IdeBundle.message("title.file.not.found"))
|
||||
return
|
||||
}
|
||||
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
val magicEntry = ZipFile(saveFile).getEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER)
|
||||
if (magicEntry == null) {
|
||||
Messages.showErrorDialog(
|
||||
IdeBundle.message("error.file.contains.no.settings.to.import", presentableFileName(saveFile), promptLocationMessage()),
|
||||
IdeBundle.message("title.invalid.file"))
|
||||
return
|
||||
}
|
||||
|
||||
val fileToComponents = getExportableComponentsMap(false, true)
|
||||
val components = getComponentsStored(saveFile, fileToComponents.values())
|
||||
fileToComponents.values().retainAll(components)
|
||||
val dialog = ChooseComponentsToExportDialog(fileToComponents, false,
|
||||
IdeBundle.message("title.select.components.to.import"),
|
||||
IdeBundle.message("prompt.check.components.to.import"))
|
||||
if (!dialog.showAndGet()) {
|
||||
return
|
||||
}
|
||||
|
||||
val chosenComponents = dialog.exportableComponents
|
||||
val relativeNamesToExtract = THashSet<String>()
|
||||
for (chosenComponent in chosenComponents) {
|
||||
for (exportFile in chosenComponent.files) {
|
||||
relativeNamesToExtract.add(FileUtil.toSystemIndependentName(FileUtilRt.getRelativePath(File(PathManager.getConfigPath()), exportFile)!!))
|
||||
}
|
||||
}
|
||||
|
||||
relativeNamesToExtract.add(PluginManager.INSTALLED_TXT)
|
||||
|
||||
val tempFile = File(PathManager.getPluginTempPath(), saveFile.name)
|
||||
FileUtil.copy(saveFile, tempFile)
|
||||
val outDir = File(PathManager.getConfigPath())
|
||||
val filenameFilter = ImportSettingsFilenameFilter(relativeNamesToExtract)
|
||||
StartupActionScriptManager.addActionCommand(StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter))
|
||||
// remove temp file
|
||||
StartupActionScriptManager.addActionCommand(StartupActionScriptManager.DeleteCommand(tempFile))
|
||||
|
||||
UpdateSettings.getInstance().forceCheckForUpdateAfterRestart()
|
||||
|
||||
val key = if (ApplicationManager.getApplication().isRestartCapable)
|
||||
"message.settings.imported.successfully.restart"
|
||||
else
|
||||
"message.settings.imported.successfully"
|
||||
if (Messages.showOkCancelDialog(IdeBundle.message(key,
|
||||
ApplicationNamesInfo.getInstance().productName,
|
||||
ApplicationNamesInfo.getInstance().fullProductName),
|
||||
IdeBundle.message("title.restart.needed"), Messages.getQuestionIcon()) == Messages.OK) {
|
||||
(ApplicationManager.getApplication() as ApplicationEx).restart(true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun presentableFileName(file: File) = "'" + FileUtil.toSystemDependentName(file.path) + "'"
|
||||
|
||||
private fun promptLocationMessage() = IdeBundle.message("message.please.ensure.correct.settings")
|
||||
|
||||
private fun getComponentsStored(settings: File, registeredComponents: Collection<ExportableItem>): List<ExportableItem> {
|
||||
val zipEntries = THashSet<String>()
|
||||
val zipFile = ZipFile(settings)
|
||||
try {
|
||||
val enumeration = zipFile.entries()
|
||||
while (enumeration.hasMoreElements()) {
|
||||
zipEntries.add(enumeration.nextElement().name)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
zipFile.close()
|
||||
}
|
||||
|
||||
val configPath = File(PathManager.getConfigPath())
|
||||
val components = ArrayList<ExportableItem>()
|
||||
for (component in registeredComponents) {
|
||||
for (exportFile in component.files) {
|
||||
var relativePath = FileUtilRt.getRelativePath(configPath, exportFile)!!
|
||||
relativePath = FileUtilRt.toSystemIndependentName(relativePath)
|
||||
if (exportFile.name.indexOf('.') == -1 && !exportFile.isFile) {
|
||||
relativePath += '/'
|
||||
}
|
||||
if (zipEntries.contains(relativePath)) {
|
||||
components.add(component)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return components
|
||||
}
|
||||
}
|
||||
+19
-13
@@ -45,6 +45,10 @@ public class DarculaButtonUI extends BasicButtonUI {
|
||||
return c instanceof JButton && "square".equals(((JButton)c).getClientProperty("JButton.buttonType"));
|
||||
}
|
||||
|
||||
public static boolean isDefaultButton(JComponent c) {
|
||||
return c instanceof JButton && ((JButton)c).isDefaultButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
int w = c.getWidth();
|
||||
@@ -64,7 +68,7 @@ public class DarculaButtonUI extends BasicButtonUI {
|
||||
final Insets ins = border.getBorderInsets(c);
|
||||
final int yOff = (ins.top + ins.bottom) / 4;
|
||||
if (!square) {
|
||||
if (c instanceof JButton && ((JButton)c).isDefaultButton()) {
|
||||
if (isDefaultButton(c)) {
|
||||
((Graphics2D)g).setPaint(UIUtil.getGradientPaint(0, 0, getSelectedButtonColor1(), 0, h, getSelectedButtonColor2()));
|
||||
}
|
||||
else {
|
||||
@@ -87,7 +91,7 @@ public class DarculaButtonUI extends BasicButtonUI {
|
||||
AbstractButton button = (AbstractButton)c;
|
||||
ButtonModel model = button.getModel();
|
||||
Color fg = button.getForeground();
|
||||
if (fg instanceof UIResource && button instanceof JButton && ((JButton)button).isDefaultButton()) {
|
||||
if (fg instanceof UIResource && isDefaultButton(button)) {
|
||||
final Color selectedFg = UIManager.getColor("Button.darcula.selectedButtonForeground");
|
||||
if (selectedFg != null) {
|
||||
fg = selectedFg;
|
||||
@@ -104,19 +108,21 @@ public class DarculaButtonUI extends BasicButtonUI {
|
||||
textRect.y + metrics.getAscent() + getTextShiftOffset());
|
||||
}
|
||||
else {
|
||||
g.setColor(UIManager.getColor("Button.darcula.disabledText.shadow"));
|
||||
SwingUtilities2.drawStringUnderlineCharAt(c, g, text, -1,
|
||||
textRect.x + getTextShiftOffset()+1,
|
||||
textRect.y + metrics.getAscent() + getTextShiftOffset()+1);
|
||||
g.setColor(UIManager.getColor("Button.disabledText"));
|
||||
SwingUtilities2.drawStringUnderlineCharAt(c, g, text, -1,
|
||||
textRect.x + getTextShiftOffset(),
|
||||
textRect.y + metrics.getAscent() + getTextShiftOffset());
|
||||
|
||||
|
||||
paintDisabledText(g, text, c, textRect, metrics);
|
||||
}
|
||||
}
|
||||
|
||||
protected void paintDisabledText(Graphics g, String text, JComponent c, Rectangle textRect, FontMetrics metrics) {
|
||||
g.setColor(UIManager.getColor("Button.darcula.disabledText.shadow"));
|
||||
SwingUtilities2.drawStringUnderlineCharAt(c, g, text, -1,
|
||||
textRect.x + getTextShiftOffset()+1,
|
||||
textRect.y + metrics.getAscent() + getTextShiftOffset()+1);
|
||||
g.setColor(UIManager.getColor("Button.disabledText"));
|
||||
SwingUtilities2.drawStringUnderlineCharAt(c, g, text, -1,
|
||||
textRect.x + getTextShiftOffset(),
|
||||
textRect.y + metrics.getAscent() + getTextShiftOffset());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect) {
|
||||
Border border = c.getBorder();
|
||||
@@ -137,7 +143,7 @@ public class DarculaButtonUI extends BasicButtonUI {
|
||||
@Override
|
||||
public void update(Graphics g, JComponent c) {
|
||||
super.update(g, c);
|
||||
if (c instanceof JButton && ((JButton)c).isDefaultButton() && !SystemInfo.isMac) {
|
||||
if (isDefaultButton(c) && !SystemInfo.isMac) {
|
||||
if (!c.getFont().isBold()) {
|
||||
c.setFont(c.getFont().deriveFont(Font.BOLD));
|
||||
}
|
||||
|
||||
@@ -17,10 +17,12 @@ package com.intellij.ide.ui.laf.darcula.ui;
|
||||
|
||||
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
|
||||
import com.intellij.openapi.ui.GraphicsConfig;
|
||||
import com.intellij.ui.ColorPanel;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.text.JTextComponent;
|
||||
@@ -39,6 +41,9 @@ public class DarculaTextBorder implements Border, UIResource {
|
||||
else if (TextFieldWithPopupHandlerUI.isSearchField(c)) {
|
||||
return JBUI.insets(vOffset, 4 + 16 + 3, vOffset, 7 + 16).asUIResource();
|
||||
}
|
||||
else if (c instanceof JTextField && c.getParent() instanceof ColorPanel) {
|
||||
return JBUI.insets(3, 3, 2, 2).asUIResource();
|
||||
}
|
||||
else {
|
||||
return JBUI.insets(vOffset, 7, vOffset, 7).asUIResource();
|
||||
}
|
||||
|
||||
+13
-1
@@ -109,7 +109,7 @@ public class MacIntelliJButtonUI extends DarculaButtonUI {
|
||||
}
|
||||
|
||||
private static Icon getIcon(String suffix, AbstractButton button) {
|
||||
boolean isDefault = button instanceof JButton && ((JButton)button).isDefaultButton();
|
||||
boolean isDefault = isDefaultButton(button);
|
||||
boolean isFocused = button.hasFocus();
|
||||
boolean combo = button.getClientProperty("styleCombo") == Boolean.TRUE;
|
||||
String comboPrefix = combo ? "Combo" : "";
|
||||
@@ -146,4 +146,16 @@ public class MacIntelliJButtonUI extends DarculaButtonUI {
|
||||
Dimension size = super.getPreferredSize(c);
|
||||
return new Dimension(size.width + 16, 27);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintDisabledText(Graphics g, String text, JComponent c, Rectangle textRect, FontMetrics metrics) {
|
||||
int x = textRect.x + getTextShiftOffset();
|
||||
int y = textRect.y + metrics.getAscent() + getTextShiftOffset();
|
||||
if (isDefaultButton(c)) {
|
||||
g.setColor(Gray.xCC);
|
||||
} else {
|
||||
g.setColor(UIManager.getColor("Button.disabledText"));
|
||||
}
|
||||
SwingUtilities2.drawStringUnderlineCharAt(c, g, text, -1, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package com.intellij.idea;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
@@ -33,88 +30,134 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.io.BuiltInServer;
|
||||
import org.jetbrains.io.MessageDecoder;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
*/
|
||||
public final class SocketLock {
|
||||
private static final Logger LOG = Logger.getInstance(SocketLock.class);
|
||||
|
||||
@NonNls private static final String ACTIVATE_COMMAND = "activate ";
|
||||
|
||||
private final String configPath;
|
||||
private final String systemPath;
|
||||
|
||||
public enum ActivateStatus {ACTIVATED, NO_INSTANCE, CANNOT_ACTIVATE}
|
||||
|
||||
private final AtomicReference<Consumer<List<String>>> activateListener = new AtomicReference<Consumer<List<String>>>();
|
||||
private static final String PORT_FILE = "port";
|
||||
private static final String ACTIVATE_COMMAND = "activate ";
|
||||
private static final String PORT_LOCK_FILE = "port.lock";
|
||||
|
||||
private BuiltInServer server;
|
||||
private final String myConfigPath;
|
||||
private final String mySystemPath;
|
||||
private final AtomicReference<Consumer<List<String>>> myActivateListener = new AtomicReference<Consumer<List<String>>>();
|
||||
private BuiltInServer myServer;
|
||||
|
||||
public SocketLock(@NotNull String configPath, @NotNull String systemPath) {
|
||||
this.configPath = canonicalPath(configPath);
|
||||
this.systemPath = canonicalPath(systemPath);
|
||||
myConfigPath = canonicalPath(configPath);
|
||||
mySystemPath = canonicalPath(systemPath);
|
||||
}
|
||||
|
||||
public void setExternalInstanceListener(@Nullable Consumer<List<String>> consumer) {
|
||||
activateListener.set(consumer);
|
||||
myActivateListener.set(consumer);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("enter: destroyProcess()");
|
||||
}
|
||||
log("enter: dispose()");
|
||||
|
||||
BuiltInServer server = myServer;
|
||||
if (server == null) return;
|
||||
|
||||
BuiltInServer server = this.server;
|
||||
boolean doRemovePortMarker = server != null;
|
||||
try {
|
||||
if (server != null) {
|
||||
Disposer.dispose(server);
|
||||
}
|
||||
Disposer.dispose(server);
|
||||
}
|
||||
finally {
|
||||
if (doRemovePortMarker) {
|
||||
try {
|
||||
executeAndClose(new Executor<Void>() {
|
||||
@Override
|
||||
public Void execute(@NotNull List<Closeable> closeables) throws IOException {
|
||||
File config = new File(configPath);
|
||||
File system = new File(systemPath);
|
||||
lockPortMarker(config, closeables);
|
||||
lockPortMarker(system, closeables);
|
||||
FileUtil.delete(new File(config, "port"));
|
||||
FileUtil.delete(new File(system, "port"));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
try {
|
||||
underLocks(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
FileUtil.delete(new File(myConfigPath, PORT_FILE));
|
||||
FileUtil.delete(new File(mySystemPath, PORT_FILE));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
Logger.getInstance(SocketLock.class).warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BuiltInServer getServer() {
|
||||
return server;
|
||||
return myServer;
|
||||
}
|
||||
|
||||
private static void lockPortMarker(@NotNull File parent, @NotNull List<Closeable> list) throws IOException {
|
||||
FileUtilRt.createDirectory(parent);
|
||||
FileOutputStream stream = new FileOutputStream(new File(parent, "port.lock"), true);
|
||||
list.add(stream);
|
||||
@NotNull
|
||||
public ActivateStatus lock() throws Exception {
|
||||
return lock(ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ActivateStatus lock(@NotNull final String[] args) throws Exception {
|
||||
log("enter: lock(config=%s system=%s)", myConfigPath, mySystemPath);
|
||||
|
||||
return underLocks(new Callable<ActivateStatus>() {
|
||||
@Override
|
||||
public ActivateStatus call() throws Exception {
|
||||
File portMarkerC = new File(myConfigPath, PORT_FILE);
|
||||
File portMarkerS = new File(mySystemPath, PORT_FILE);
|
||||
|
||||
MultiMap<Integer, String> portToPath = MultiMap.createSmart();
|
||||
addExistingPort(portMarkerC, myConfigPath, portToPath);
|
||||
addExistingPort(portMarkerS, mySystemPath, portToPath);
|
||||
if (!portToPath.isEmpty()) {
|
||||
for (Map.Entry<Integer, Collection<String>> entry : portToPath.entrySet()) {
|
||||
ActivateStatus status = tryActivate(entry.getKey(), entry.getValue(), args);
|
||||
if (status != ActivateStatus.NO_INSTANCE) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final String[] lockedPaths = {myConfigPath, mySystemPath};
|
||||
myServer = BuiltInServer.start(1, 6942, 50, false, new NotNullProducer<ChannelHandler>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public ChannelHandler produce() {
|
||||
return new MyChannelInboundHandler(lockedPaths, myActivateListener);
|
||||
}
|
||||
});
|
||||
|
||||
byte[] portBytes = Integer.toString(myServer.getPort()).getBytes(CharsetToolkit.UTF8_CHARSET);
|
||||
FileUtil.writeToFile(portMarkerC, portBytes);
|
||||
FileUtil.writeToFile(portMarkerS, portBytes);
|
||||
return ActivateStatus.NO_INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private <V> V underLocks(@NotNull Callable<V> action) throws Exception {
|
||||
FileUtilRt.createDirectory(new File(myConfigPath));
|
||||
FileOutputStream lock1 = new FileOutputStream(new File(myConfigPath, PORT_LOCK_FILE), true);
|
||||
try {
|
||||
FileUtilRt.createDirectory(new File(mySystemPath));
|
||||
FileOutputStream lock2 = new FileOutputStream(new File(mySystemPath, PORT_LOCK_FILE), true);
|
||||
try {
|
||||
return action.call();
|
||||
}
|
||||
finally {
|
||||
lock2.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock1.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void addExistingPort(@NotNull File portMarker, @NotNull String path, @NotNull MultiMap<Integer, String> portToPath) {
|
||||
@@ -122,179 +165,81 @@ public final class SocketLock {
|
||||
try {
|
||||
portToPath.putValue(Integer.parseInt(FileUtilRt.loadFile(portMarker)), path);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.debug(e);
|
||||
catch (Exception e) {
|
||||
log(e);
|
||||
// don't delete - we overwrite it on write in any case
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ActivateStatus lock() {
|
||||
return lock(ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ActivateStatus lock(@NotNull final String[] args) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("enter: lock(configPath='" + configPath + "', systemPath='" + systemPath + "')");
|
||||
}
|
||||
|
||||
try {
|
||||
final File config = new File(configPath);
|
||||
final File system = new File(systemPath);
|
||||
final File portMarkerC = new File(config, "port");
|
||||
final File portMarkerS = new File(system, "port");
|
||||
return executeAndClose(new Executor<ActivateStatus>() {
|
||||
@Override
|
||||
public ActivateStatus execute(@NotNull List<Closeable> closeables) throws Throwable {
|
||||
lockPortMarker(config, closeables);
|
||||
lockPortMarker(system, closeables);
|
||||
MultiMap<Integer, String> portToPath = MultiMap.createSmart();
|
||||
addExistingPort(portMarkerC, configPath, portToPath);
|
||||
addExistingPort(portMarkerS, systemPath, portToPath);
|
||||
if (!portToPath.isEmpty()) {
|
||||
for (Map.Entry<Integer, Collection<String>> entry : portToPath.entrySet()) {
|
||||
ActivateStatus status = tryActivate(entry.getKey(), entry.getValue(), args);
|
||||
if (status != ActivateStatus.NO_INSTANCE) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final String[] lockedPaths = {configPath, systemPath};
|
||||
server = BuiltInServer.start(1, 6942, 50, false, new NotNullProducer<ChannelHandler>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public ChannelHandler produce() {
|
||||
return new MyChannelInboundHandler(lockedPaths, activateListener);
|
||||
}
|
||||
});
|
||||
|
||||
byte[] portBytes = Integer.toString(server.getPort()).getBytes(CharsetToolkit.UTF8_CHARSET);
|
||||
FileUtil.writeToFile(portMarkerC, portBytes);
|
||||
FileUtil.writeToFile(portMarkerS, portBytes);
|
||||
return ActivateStatus.NO_INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
|
||||
if (Main.isHeadless()) {
|
||||
Main.showMessage("Cannot lock system folders", e);
|
||||
}
|
||||
else {
|
||||
String pathToLogFile = PathManager.getLogPath() + "/idea.log file".replace('/', File.separatorChar);
|
||||
JOptionPane.showMessageDialog(
|
||||
JOptionPane.getRootFrame(),
|
||||
CommonBundle.message("cannot.start.other.instance.is.running.error.message", ApplicationNamesInfo.getInstance().getProductName(),
|
||||
pathToLogFile),
|
||||
CommonBundle.message("title.warning"),
|
||||
JOptionPane.WARNING_MESSAGE
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private interface Executor<T> {
|
||||
T execute(@NotNull List<Closeable> closeables) throws Throwable;
|
||||
}
|
||||
|
||||
private static <T> T executeAndClose(@NotNull Executor<T> executor) throws Throwable {
|
||||
List<Closeable> closeables = new ArrayList<Closeable>();
|
||||
try {
|
||||
return executor.execute(closeables);
|
||||
}
|
||||
finally {
|
||||
for (Closeable closeable : closeables) {
|
||||
try {
|
||||
closeable.close();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"SocketOpenedButNotSafelyClosed", "IOResourceOpenedButNotSafelyClosed"})
|
||||
@NotNull
|
||||
private static ActivateStatus tryActivate(int portNumber, @NotNull Collection<String> paths, @NotNull String[] args) {
|
||||
Socket socket = null;
|
||||
try {
|
||||
socket = new Socket(NetUtils.getLoopbackAddress(), portNumber);
|
||||
socket.setSoTimeout(300);
|
||||
Socket socket = new Socket(NetUtils.getLoopbackAddress(), portNumber);
|
||||
try {
|
||||
socket.setSoTimeout(300);
|
||||
|
||||
boolean result = false;
|
||||
DataInputStream in = new DataInputStream(socket.getInputStream());
|
||||
while (true) {
|
||||
try {
|
||||
String path = in.readUTF();
|
||||
if (paths.contains(path)) {
|
||||
result = true;
|
||||
// don't break - read all input
|
||||
boolean result = false;
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed") DataInputStream in = new DataInputStream(socket.getInputStream());
|
||||
while (true) {
|
||||
try {
|
||||
String path = in.readUTF();
|
||||
if (paths.contains(path)) {
|
||||
result = true; // don't break - read all input
|
||||
}
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
break;
|
||||
|
||||
if (result) {
|
||||
try {
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed") DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
||||
out.writeUTF(ACTIVATE_COMMAND + new File(".").getAbsolutePath() + "\0" + StringUtil.join(args, "\0"));
|
||||
out.flush();
|
||||
String response = in.readUTF();
|
||||
if (response.equals("ok")) {
|
||||
return ActivateStatus.ACTIVATED;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
log(e);
|
||||
}
|
||||
|
||||
return ActivateStatus.CANNOT_ACTIVATE;
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
try {
|
||||
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
||||
out.writeUTF(ACTIVATE_COMMAND + new File(".").getAbsolutePath() + "\0" + StringUtil.join(args, "\0"));
|
||||
out.flush();
|
||||
String response = in.readUTF();
|
||||
if (response.equals("ok")) {
|
||||
return ActivateStatus.ACTIVATED;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
return ActivateStatus.CANNOT_ACTIVATE;
|
||||
finally {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.debug(e);
|
||||
}
|
||||
finally {
|
||||
if (socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.debug(e);
|
||||
}
|
||||
}
|
||||
log(e);
|
||||
}
|
||||
|
||||
return ActivateStatus.NO_INSTANCE;
|
||||
}
|
||||
|
||||
private static class MyChannelInboundHandler extends MessageDecoder {
|
||||
private final String[] lockedPaths;
|
||||
private State state = State.HEADER;
|
||||
private final AtomicReference<Consumer<List<String>>> activateListener;
|
||||
|
||||
public MyChannelInboundHandler(@NotNull String[] lockedPaths, @NotNull AtomicReference<Consumer<List<String>>> activateListener) {
|
||||
this.lockedPaths = lockedPaths;
|
||||
this.activateListener = activateListener;
|
||||
}
|
||||
|
||||
private enum State {HEADER, CONTENT}
|
||||
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
private final String[] myLockedPaths;
|
||||
private final AtomicReference<Consumer<List<String>>> myActivateListener;
|
||||
private State myState = State.HEADER;
|
||||
|
||||
public MyChannelInboundHandler(@NotNull String[] lockedPaths, @NotNull AtomicReference<Consumer<List<String>>> activateListener) {
|
||||
myLockedPaths = lockedPaths;
|
||||
myActivateListener = activateListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext context) throws Exception {
|
||||
ByteBuf buffer = context.alloc().ioBuffer(1024);
|
||||
boolean success = false;
|
||||
try {
|
||||
ByteBufOutputStream out = new ByteBufOutputStream(buffer);
|
||||
for (String path : lockedPaths) {
|
||||
for (String path : myLockedPaths) {
|
||||
if (path != null) {
|
||||
out.writeUTF(path);
|
||||
}
|
||||
@@ -310,11 +255,10 @@ public final class SocketLock {
|
||||
context.writeAndFlush(buffer);
|
||||
}
|
||||
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
@Override
|
||||
protected void messageReceived(@NotNull ChannelHandlerContext context, @NotNull ByteBuf input) throws Exception {
|
||||
while (true) {
|
||||
switch (state) {
|
||||
switch (myState) {
|
||||
case HEADER: {
|
||||
ByteBuf buffer = getBufferIfSufficient(input, 2, context);
|
||||
if (buffer == null) {
|
||||
@@ -322,7 +266,7 @@ public final class SocketLock {
|
||||
}
|
||||
|
||||
contentLength = buffer.readUnsignedShort();
|
||||
state = State.CONTENT;
|
||||
myState = State.CONTENT;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -334,7 +278,7 @@ public final class SocketLock {
|
||||
|
||||
if (StringUtil.startsWith(command, ACTIVATE_COMMAND)) {
|
||||
List<String> args = StringUtil.split(command.subSequence(ACTIVATE_COMMAND.length(), command.length()).toString(), "\0");
|
||||
Consumer<List<String>> listener = activateListener.get();
|
||||
Consumer<List<String>> listener = myActivateListener.get();
|
||||
if (listener != null) {
|
||||
listener.consume(args);
|
||||
}
|
||||
@@ -357,8 +301,20 @@ public final class SocketLock {
|
||||
private static String canonicalPath(@NotNull String configPath) {
|
||||
try {
|
||||
return new File(configPath).getCanonicalPath();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
return configPath;
|
||||
}
|
||||
}
|
||||
|
||||
private static void log(Exception e) {
|
||||
Logger.getInstance(SocketLock.class).debug(e);
|
||||
}
|
||||
|
||||
private static void log(String format, Object... args) {
|
||||
Logger logger = Logger.getInstance(SocketLock.class);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format(format, args));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,6 +244,7 @@ public class StartupUtil {
|
||||
finally { writer.close(); }
|
||||
}
|
||||
|
||||
@SuppressWarnings("SSBasedInspection")
|
||||
private static void delete(File ideTempFile) {
|
||||
if (!FileUtilRt.delete(ideTempFile)) {
|
||||
ideTempFile.deleteOnExit();
|
||||
@@ -251,25 +252,36 @@ public class StartupUtil {
|
||||
}
|
||||
|
||||
private synchronized static boolean lockSystemFolders(String[] args) {
|
||||
assert ourLock == null;
|
||||
if (ourLock != null) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
ourLock = new SocketLock(PathManager.getConfigPath(), PathManager.getSystemPath());
|
||||
|
||||
SocketLock.ActivateStatus activateStatus = ourLock.lock(args);
|
||||
if (activateStatus != SocketLock.ActivateStatus.NO_INSTANCE) {
|
||||
if (activateStatus != null && (Main.isHeadless() || activateStatus == SocketLock.ActivateStatus.CANNOT_ACTIVATE)) {
|
||||
String message = "Only one instance of " + ApplicationNamesInfo.getInstance().getFullProductName() + " can be run at a time.";
|
||||
Main.showMessage("Too Many Instances", message, true);
|
||||
}
|
||||
SocketLock.ActivateStatus status;
|
||||
try {
|
||||
status = ourLock.lock(args);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Main.showMessage("Cannot Lock System Folders", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ourLock.dispose();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
if (status == SocketLock.ActivateStatus.NO_INSTANCE) {
|
||||
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ourLock.dispose();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
else if (Main.isHeadless() || status == SocketLock.ActivateStatus.CANNOT_ACTIVATE) {
|
||||
String message = "Only one instance of " + ApplicationNamesInfo.getInstance().getFullProductName() + " can be run at a time.";
|
||||
Main.showMessage("Too Many Instances", message, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void fixProcessEnvironment(Logger log) {
|
||||
|
||||
+30
@@ -80,6 +80,36 @@ import java.awt.geom.AffineTransform;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Gutter content (left to right):
|
||||
* <ul>
|
||||
* <li>GAP_BETWEEN_AREAS</li>
|
||||
* <li>Line numbers area
|
||||
* <ul>
|
||||
* <li>Line numbers</li>
|
||||
* <li>GAP_BETWEEN_AREAS</li>
|
||||
* <li>Additional line numbers (used in diff)</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>GAP_BETWEEN_AREAS</li>
|
||||
* <li>Annotations area
|
||||
* <ul>
|
||||
* <li>Annotations</li>
|
||||
* <li>Annotations extra (used in distraction free mode)</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>GAP_BETWEEN_AREAS</li>
|
||||
* <li>Line markers area
|
||||
* <ul>
|
||||
* <li>Left free painters</li>
|
||||
* <li>Icons</li>
|
||||
* <li>GAP_BETWEEN_AREAS</li>
|
||||
* <li>Free painters</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Folding area</li>
|
||||
*</ul>
|
||||
*/
|
||||
class EditorGutterComponentImpl extends EditorGutterComponentEx implements MouseListener, MouseMotionListener, DataProvider {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorGutterComponentImpl");
|
||||
private static final int START_ICON_AREA_WIDTH = 15;
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.lang.Commenter;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileTypes.*;
|
||||
import com.intellij.openapi.fileTypes.ex.ExternalizableFileType;
|
||||
import com.intellij.openapi.options.ExternalInfo;
|
||||
import com.intellij.openapi.options.ExternalizableScheme;
|
||||
import com.intellij.openapi.options.SettingsEditor;
|
||||
import com.intellij.openapi.util.*;
|
||||
@@ -415,10 +414,4 @@ public class AbstractFileType extends UserFileType<AbstractFileType> implements
|
||||
public void setCommenter(final Commenter commenter) {
|
||||
myCommenter = commenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ExternalInfo getExternalInfo() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@State(
|
||||
name = "FileTypeManager",
|
||||
storages = @Storage(file = StoragePathMacros.APP_CONFIG + "/filetypes.xml"),
|
||||
storages = @Storage(file = "filetypes.xml"),
|
||||
additionalExportFile = FileTypeManagerImpl.FILE_SPEC
|
||||
)
|
||||
public class FileTypeManagerImpl extends FileTypeManagerEx implements PersistentStateComponent<Element>, ApplicationComponent, Disposable {
|
||||
|
||||
+23
-2
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
package com.intellij.openapi.progress.util;
|
||||
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.ui.GraphicsConfig;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.NotNullProducer;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -36,8 +39,26 @@ import java.awt.geom.Rectangle2D;
|
||||
public class ColorProgressBar extends JComponent {
|
||||
private static final Dimension PREFERRED_SIZE = new Dimension(146, 17);
|
||||
|
||||
public static final Color GREEN = new JBColor(new Color(0x6cad74), new Color(0x4a8c53));
|
||||
public static final Color RED = new JBColor(new Color(0xd67b76), new Color(0xe55757));
|
||||
public static final Color GREEN = new JBColor(new NotNullProducer<Color>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Color produce() {
|
||||
UISettings settings = UISettings.getInstance();
|
||||
return settings == null || null == settings.COLOR_BLINDNESS
|
||||
? new JBColor(new Color(0x6cad74), new Color(0x4a8c53))
|
||||
: new JBColor(new Color(0x6ca69c), new Color(0x639990));
|
||||
}
|
||||
});
|
||||
public static final Color RED = new JBColor(new NotNullProducer<Color>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Color produce() {
|
||||
UISettings settings = UISettings.getInstance();
|
||||
return settings == null || null == settings.COLOR_BLINDNESS
|
||||
? new JBColor(new Color(0xd67b76), new Color(0xe55757))
|
||||
: new JBColor(new Color(0xcc7447), new Color(0xcc7447));
|
||||
}
|
||||
});
|
||||
public static final Color RED_TEXT = new JBColor(new Color(0xb81708), new Color(0xdb5c5c));
|
||||
public static final Color BLUE = new JBColor(new Color(1, 68, 208), JBColor.blue);
|
||||
public static final Color YELLOW = new JBColor(new Color(0xa67a21), new Color(0x91703a));
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.openapi.roots.ui.util;
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -17,6 +17,8 @@ package org.jetbrains.io;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.NotNullProducer;
|
||||
import com.intellij.util.net.NetUtils;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
@@ -52,16 +54,25 @@ public class BuiltInServer implements Disposable {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BuiltInServer start(int workerCount, int firstPort, int portsCount, boolean tryAnyPort, @Nullable NotNullProducer<ChannelHandler> channelHandler) throws Throwable {
|
||||
return start(new NioEventLoopGroup(workerCount, PooledThreadExecutor.INSTANCE), true, firstPort, portsCount, tryAnyPort, channelHandler);
|
||||
public static BuiltInServer start(int workerCount,
|
||||
int firstPort,
|
||||
int portsCount,
|
||||
boolean tryAnyPort,
|
||||
@Nullable NotNullProducer<ChannelHandler> handler) throws Exception {
|
||||
return start(new NioEventLoopGroup(workerCount, PooledThreadExecutor.INSTANCE), true, firstPort, portsCount, tryAnyPort, handler);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BuiltInServer start(@NotNull EventLoopGroup eventLoopGroup, boolean isOwnerOfEventLoopGroup, int firstPort, int portsCount, boolean tryAnyPort, @Nullable NotNullProducer<ChannelHandler> channelHandler) throws Throwable {
|
||||
public static BuiltInServer start(@NotNull EventLoopGroup eventLoopGroup,
|
||||
boolean isEventLoopGroupOwner,
|
||||
int firstPort,
|
||||
int portsCount,
|
||||
boolean tryAnyPort,
|
||||
@Nullable NotNullProducer<ChannelHandler> handler) throws Exception {
|
||||
ChannelRegistrar channelRegistrar = new ChannelRegistrar();
|
||||
ServerBootstrap bootstrap = NettyUtil.nioServerBootstrap(eventLoopGroup);
|
||||
configureChildHandler(bootstrap, channelRegistrar, channelHandler);
|
||||
return new BuiltInServer(eventLoopGroup, bind(firstPort, portsCount, tryAnyPort, bootstrap, channelRegistrar), isOwnerOfEventLoopGroup);
|
||||
configureChildHandler(bootstrap, channelRegistrar, handler);
|
||||
return new BuiltInServer(eventLoopGroup, bind(firstPort, portsCount, tryAnyPort, bootstrap, channelRegistrar), isEventLoopGroupOwner);
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
@@ -73,7 +84,9 @@ public class BuiltInServer implements Disposable {
|
||||
return eventLoopGroup;
|
||||
}
|
||||
|
||||
static void configureChildHandler(@NotNull ServerBootstrap bootstrap, @NotNull final ChannelRegistrar channelRegistrar, final @Nullable NotNullProducer<ChannelHandler> channelHandler) {
|
||||
static void configureChildHandler(@NotNull ServerBootstrap bootstrap,
|
||||
@NotNull final ChannelRegistrar channelRegistrar,
|
||||
final @Nullable NotNullProducer<ChannelHandler> channelHandler) {
|
||||
final PortUnificationServerHandler portUnificationServerHandler = channelHandler == null ? new PortUnificationServerHandler() : null;
|
||||
bootstrap.childHandler(new ChannelInitializer() {
|
||||
@Override
|
||||
@@ -83,41 +96,41 @@ public class BuiltInServer implements Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isPortForbidden(int port) {
|
||||
for (int forbiddenPort : FORBIDDEN_PORTS) {
|
||||
if (port == forbiddenPort) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static int bind(int firstPort,
|
||||
int portsCount,
|
||||
boolean tryAnyPort,
|
||||
@NotNull ServerBootstrap bootstrap,
|
||||
@NotNull ChannelRegistrar channelRegistrar) throws Exception {
|
||||
InetAddress address = NetUtils.getLoopbackAddress();
|
||||
|
||||
private static int bind(int firstPort, int portsCount, boolean tryAnyPort, @NotNull ServerBootstrap bootstrap, @NotNull ChannelRegistrar channelRegistrar) throws Throwable {
|
||||
InetAddress loopbackAddress = NetUtils.getLoopbackAddress();
|
||||
for (int i = 0; i < portsCount; i++) {
|
||||
int port = firstPort + i;
|
||||
|
||||
if (isPortForbidden(i)) {
|
||||
if (ArrayUtil.indexOf(FORBIDDEN_PORTS, i) >= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ChannelFuture future = bootstrap.bind(loopbackAddress, port).awaitUninterruptibly();
|
||||
ChannelFuture future = bootstrap.bind(address, port).awaitUninterruptibly();
|
||||
if (future.isSuccess()) {
|
||||
channelRegistrar.add(future.channel());
|
||||
return port;
|
||||
}
|
||||
else if (!tryAnyPort && i == (portsCount - 1)) {
|
||||
throw future.cause();
|
||||
ExceptionUtil.rethrowAll(future.cause());
|
||||
}
|
||||
}
|
||||
|
||||
LOG.info("We cannot bind to our default range, so, try to bind to any free port");
|
||||
ChannelFuture future = bootstrap.bind(loopbackAddress, 0).awaitUninterruptibly();
|
||||
ChannelFuture future = bootstrap.bind(address, 0).awaitUninterruptibly();
|
||||
if (future.isSuccess()) {
|
||||
channelRegistrar.add(future.channel());
|
||||
return ((InetSocketAddress)future.channel().localAddress()).getPort();
|
||||
}
|
||||
else {
|
||||
throw future.cause();
|
||||
ExceptionUtil.rethrowAll(future.cause());
|
||||
}
|
||||
|
||||
return -1; // unreachable
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -141,10 +141,7 @@ local.vcs.action.name.undo.command=Undo {0}
|
||||
local.vcs.action.name.redo.command=Redo {0}
|
||||
|
||||
error.reading.color.scheme.from.file.error.message=Error reading color scheme from {0}
|
||||
corrupted.scheme.file.message.title=Corrupted File
|
||||
button.background=&Background
|
||||
vcs.configurable.general.tab.title=General
|
||||
cannot.start.other.instance.is.running.error.message={0} was unable to create a local connection in order to check whether\nother instance of {0} is currently running on the same machine.\nRunning multiple instances of {0} on the same machine may cause unpredictable\nresults because of sharing system folders.\nPlease troubleshoot your TCP/IP configuration and/or local firewall settings.\nand attach the {1}
|
||||
button.load.file=Load File
|
||||
date.frequency=Once {0}
|
||||
name.label.text=Na&me:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
color.panel.select.color.dialog.description=Select Color
|
||||
color.panel.select.color.tooltip.text=Click to customize
|
||||
insert.file.path.to.text.action.name=Insert Path
|
||||
order.entries.panel.export.column.name=Export
|
||||
tree.view.expand.all.action.name=Expand All
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// This file contains list of broken plugins.
|
||||
// Each line contains plugin ID and list of versions that are broken.
|
||||
// If plugin name or version contains a space you can quote it like in command line.
|
||||
NodeJS 142.4100 142.3224 142.2650 142.2492 142.2481 142.2064 141.1108 140.2045 140.1669 140.642 139.173 139.105 139.496 139.1 139.8 138.2196 138.2254 138.1684 138.1744 138.1879 138.2051 138.1367 138.1495 138.1189 138.1145 138.937 138.1013 138.921 138.447 138.172 138.317 138.21 138.35 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141
|
||||
NodeJS 142.4426 142.4100 142.3858 142.3224 142.2650 142.2492 142.2481 142.2064 141.1108 140.2045 140.1669 140.642 139.173 139.105 139.496 139.1 139.8 138.2196 138.2254 138.1684 138.1744 138.1879 138.2051 138.1367 138.1495 138.1189 138.1145 138.937 138.1013 138.921 138.447 138.172 138.317 138.21 138.35 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141
|
||||
com.jetbrains.php 140.2765 141.332 139.732 139.659 139.496 139.173 139.105 138.2502 138.2000.2262 138.1751 138.1806 138.1505 138.1161 138.826 136.1768 136.1672 134.1456 133.982 133.679 133.51 133.326 131.98 131.374 131.332 131.235 131.205 130.1639 130.1481 130.1176 129.91 129.814 129.672 129.362 127.67 127.100 126.334 123.66 122.875 121.62 121.390 121.215 121.12
|
||||
com.jetbrains.lang.ejs 131.17 131.12
|
||||
com.jetbrains.twig 133.51 130.1639
|
||||
org.jetbrains.plugins.ruby 8.0.0.20180821 8.0.0.20150708 8.0.0.20150624 8.0.0.20150616 7.0.0.20150216 7.0.0.20150204 7.0.0.20141010 7.0.0.20140915 7.0.0.20140901 7.0.0.20140807 6.0.0.20140207 6.5.2.20140512 7.0.0.20140704 7.0.0.20140707 7.0.0.20140724
|
||||
Pythonid "142.176 v4.5" 4.1 "4.1 141.4 EAP" 3.1 4.0.25 4.0.26
|
||||
Karma 140.2109 138.1684 138.1879 138.317 138.21 134.1163 134.1039 134.686 134.31
|
||||
Karma 142.3390 142.2492 142.2064 140.2109 138.1684 138.1879 138.317 138.21 134.1163 134.1039 134.686 134.31
|
||||
org.intellij.scala 1.8.5 1.8.0 1.8.2 1.8.4 1.7.4 1.7.2 1.6.2 1.6.1 1.6.0 1.2.67.3.EAP 1.3.2-14.1 1.3.3-14.1 1.0.93.10.EAP 1.0.93.4.EAP 1.0.93.9.EAP 1.0.58 1.0.16 1.0.14 1.0.13 0.42.28 0.42.23 0.40.20 0.40.18 0.40.16 0.32.593 0.32.562 0.32.558 0.32.550 0.32.520 0.32.512
|
||||
org.jetbrains.kannotator 0.2.420
|
||||
org.jetbrains.kotlin 0.10.555 0.10.4 0.8.1615 0.7.1360 0.7.1376 0.8.7
|
||||
SBT 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0 1.5.1 1.6.0 1.6.1
|
||||
"JSTestDriver Plugin" 140.2109 140.1669 140.727 138.317 138.21 136.1141 134.1163 134.686 134.31 134.307 134.1039
|
||||
"JSTestDriver Plugin" 142.2492 142.2064 140.2109 140.1669 140.727 138.317 138.21 136.1141 134.1163 134.686 134.31 134.307 134.1039
|
||||
AngularJS 142.1935 141.2 140.1968 139.1112 139.12 134.1243 134.1341 134.1444 135.1063 135.565 135.831 135.937 138.1242 138.1988 134.1094 0.1.8 0.1.9
|
||||
com.jetbrains.plugins.ini4idea 0.4 0.5 0.6 0.7 0.8 0.8.1 0.9 0.9.1 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 130.1176
|
||||
org.jetbrains.plugins.vagrant 0.1 0.2 0.3 0.4
|
||||
|
||||
@@ -85,7 +85,7 @@ public class ApplicationImplTest extends LightPlatformTestCase {
|
||||
String msg = "acquireReadActionLock(" + l2 + "ms) vs runReadAction(" + l1 + "ms). Ratio: " + ratioPercent + "%";
|
||||
System.out.println(msg);
|
||||
if (Math.abs(ratioPercent) > 20) {
|
||||
return "Suspiciously different times for " + msg;
|
||||
return "Suspiciously different times for " + msg +" (in "+(ratioPercent<0 ? "my" : "Maxim's") +" favor)";
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
@@ -415,7 +415,7 @@ public class ApplicationImplTest extends LightPlatformTestCase {
|
||||
assertFalse(application.tryRunReadAction(EmptyRunnable.getInstance()));
|
||||
assertTrue(application.isWriteActionInProgress());
|
||||
assertFalse(application.isWriteAccessAllowed());
|
||||
assertTrue(application.isWriteActionPending());
|
||||
assertFalse(application.isWriteActionPending());
|
||||
}
|
||||
|
||||
holdWrite.set(false);
|
||||
@@ -449,11 +449,12 @@ public class ApplicationImplTest extends LightPlatformTestCase {
|
||||
try {
|
||||
System.out.println("write lock acquired");
|
||||
writeAcquired.set(true);
|
||||
assertTrue(application.isWriteActionInProgress());
|
||||
assertTrue(application.isWriteAccessAllowed());
|
||||
assertTrue(application.isWriteActionPending());
|
||||
|
||||
while (holdWrite.get() && ok());
|
||||
while (holdWrite.get() && ok()) {
|
||||
assertTrue(application.isWriteActionInProgress());
|
||||
assertTrue(application.isWriteAccessAllowed());
|
||||
assertFalse(application.isWriteActionPending());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writeReleased.set(true);
|
||||
|
||||
@@ -50,7 +50,7 @@ public class LockSupportTest {
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testUseCanonicalPathLock() {
|
||||
public void testUseCanonicalPathLock() throws Exception {
|
||||
assumeThat(SystemInfo.isFileSystemCaseSensitive, is(false));
|
||||
|
||||
String path1 = myTempDir.getPath();
|
||||
@@ -69,7 +69,7 @@ public class LockSupportTest {
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testLock() {
|
||||
public void testLock() throws Exception {
|
||||
SocketLock lock = new SocketLock(myTempDir.getPath() + "/c", myTempDir.getPath() + "/s");
|
||||
try {
|
||||
assertThat(lock.lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE));
|
||||
@@ -80,8 +80,8 @@ public class LockSupportTest {
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testTwoLocks() {
|
||||
List<SocketLock> toClose = new ArrayList<SocketLock>();
|
||||
public void testTwoLocks() throws Exception {
|
||||
List<SocketLock> toClose = new ArrayList<>();
|
||||
try {
|
||||
assertThat(createLock(toClose, myTempDir, "1", "1-").lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE));
|
||||
assertThat(createLock(toClose, myTempDir, "1.1", "1-1").lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE));
|
||||
@@ -92,9 +92,7 @@ public class LockSupportTest {
|
||||
assertThat(createLock(toClose, myTempDir, "1.1", "1-1").lock(), equalTo(SocketLock.ActivateStatus.ACTIVATED));
|
||||
}
|
||||
finally {
|
||||
for (SocketLock lock : toClose) {
|
||||
lock.dispose();
|
||||
}
|
||||
toClose.forEach(SocketLock::dispose);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +104,7 @@ public class LockSupportTest {
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testDispose() {
|
||||
public void testDispose() throws Exception {
|
||||
SocketLock lock1 = new SocketLock(myTempDir.getPath() + "/1", myTempDir.getPath() + "/1-");
|
||||
SocketLock lock2 = new SocketLock(myTempDir.getPath() + "/1", myTempDir.getPath() + "/1-");
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ public @interface State {
|
||||
*/
|
||||
boolean defaultStateAsResource() default false;
|
||||
|
||||
/**
|
||||
* Additional export path (relative to application-level configuration root directory).
|
||||
*/
|
||||
String additionalExportFile() default "";
|
||||
|
||||
Class<? extends NameGetter> presentableName() default NameGetter.class;
|
||||
|
||||
+22
-4
@@ -17,10 +17,7 @@ package com.intellij.remoteServer.impl.configuration.deployment;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.configurations.ConfigurationFactory;
|
||||
import com.intellij.execution.configurations.RunConfigurationBase;
|
||||
import com.intellij.execution.configurations.RunProfileState;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationException;
|
||||
import com.intellij.execution.configurations.*;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.Result;
|
||||
@@ -218,6 +215,27 @@ public class DeployToServerRunConfiguration<S extends ServerConfiguration, D ext
|
||||
super.writeExternal(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunConfiguration clone() {
|
||||
Element element = new Element("tag");
|
||||
try {
|
||||
writeExternal(element);
|
||||
}
|
||||
catch (WriteExternalException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
|
||||
DeployToServerRunConfiguration result = (DeployToServerRunConfiguration)super.clone();
|
||||
|
||||
try {
|
||||
result.readExternal(element);
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class ConfigurationState {
|
||||
@Attribute("server-name")
|
||||
public String myServerName;
|
||||
|
||||
+1
-1
@@ -428,7 +428,7 @@ public class OutputToGeneralTestEventsConverter implements ProcessOutputConsumer
|
||||
|
||||
public void visitTestFailed(@NotNull final TestFailed testFailed) {
|
||||
final Map<String, String> attributes = testFailed.getAttributes();
|
||||
assert testFailed.getFailureMessage() != null : "No failure message for: " + myTestFrameworkName;
|
||||
LOG.assertTrue(testFailed.getFailureMessage() != null, "No failure message for: " + myTestFrameworkName);
|
||||
final boolean testError = attributes.get(ATTR_KEY_TEST_ERROR) != null;
|
||||
TestFailedEvent testFailedEvent = new TestFailedEvent(testFailed, testError,
|
||||
attributes.get(ATTR_KEY_EXPECTED_FILE_PATH),
|
||||
|
||||
+7
-4
@@ -117,6 +117,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel
|
||||
private AbstractTestProxy myLastSelected;
|
||||
private Alarm myUpdateQueue;
|
||||
private Set<Update> myRequests = Collections.synchronizedSet(new HashSet<Update>());
|
||||
private boolean myDisposed = false;
|
||||
|
||||
public SMTestRunnerResultsForm(@NotNull final JComponent console,
|
||||
final TestConsoleProperties consoleProperties) {
|
||||
@@ -337,13 +338,14 @@ public class SMTestRunnerResultsForm extends TestResultsPanel
|
||||
addToHistory(testsRoot, myProperties, this);
|
||||
}
|
||||
|
||||
private static void addToHistory(final SMTestProxy.SMRootTestProxy root,
|
||||
TestConsoleProperties consoleProperties,
|
||||
Disposable parentDisposable) {
|
||||
private void addToHistory(final SMTestProxy.SMRootTestProxy root,
|
||||
TestConsoleProperties consoleProperties,
|
||||
Disposable parentDisposable) {
|
||||
final RunProfile configuration = consoleProperties.getConfiguration();
|
||||
if (configuration instanceof RunConfiguration &&
|
||||
!(consoleProperties instanceof ImportedTestConsoleProperties) &&
|
||||
!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
!ApplicationManager.getApplication().isUnitTestMode() &&
|
||||
!myDisposed) {
|
||||
final MySaveHistoryTask backgroundable = new MySaveHistoryTask(consoleProperties, root, (RunConfiguration)configuration);
|
||||
final BackgroundableProcessIndicator processIndicator = new BackgroundableProcessIndicator(backgroundable);
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@@ -532,6 +534,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel
|
||||
myShowStatisticForProxyHandler = null;
|
||||
myEventListeners.clear();
|
||||
myStatisticsPane.doDispose();
|
||||
myDisposed = true;
|
||||
}
|
||||
|
||||
public void showStatisticsForSelectedProxy() {
|
||||
|
||||
+7
@@ -3291,5 +3291,12 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
assertEquals("find declarations with only one field", 1, findMatchesCount(source, "int '_a;"));
|
||||
assertEquals("find all declarations", 4, findMatchesCount(source, "int '_a+;"));
|
||||
assertEquals("find all fields", 9, findMatchesCount(source, "int 'a+;"));
|
||||
|
||||
String source2 = "class ABC {" +
|
||||
" String u;" +
|
||||
" String s,t," +
|
||||
" void m() {}" +
|
||||
"}";
|
||||
assertEquals("find incomplete code", 1, findMatchesCount(source2, "'_a '_b{2,100};"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class TestCaseLoader {
|
||||
public TestCaseLoader(String classFilterName, boolean forceLoadPerformanceTests) {
|
||||
myForceLoadPerformanceTests = forceLoadPerformanceTests;
|
||||
String patterns = System.getProperty(TARGET_TEST_PATTERNS);
|
||||
if (patterns != null) {
|
||||
if (!StringUtil.isEmpty(patterns)) {
|
||||
myTestClassesFilter = new PatternListTestClassFilter(StringUtil.split(patterns, ";"));
|
||||
System.out.println("Using patterns: [" + patterns +"]");
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ debugger.close.dialog.on.navigate=true
|
||||
debugger.close.dialog.on.navigate.description=Close evaluate dialog on Jump to (type) source action
|
||||
debugger.async.smart.step.into=true
|
||||
debugger.async.smart.step.into.description=Smart step into anonymous class methods in any thread
|
||||
debugger.monitor.blocked.threads=false
|
||||
debugger.monitor.blocked.threads=true
|
||||
debugger.monitor.blocked.threads.description=Watch if a thread we do stepping in is blocked by another suspended thread
|
||||
|
||||
analyze.exceptions.on.the.fly=false
|
||||
@@ -646,7 +646,7 @@ tests.view.old.statistics.panel=false
|
||||
tfs.set.connection.timeout=false
|
||||
|
||||
application.deactivation.timeout=1500
|
||||
ide.mac.yosemite.laf=true
|
||||
ide.mac.yosemite.laf=false
|
||||
ide.mac.yosemite.laf.restartRequired=true
|
||||
ide.mac.yosemite.laf.description=Replaces Aqua LaF to enhanced IntelliJ LaF
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ public class LowMemoryWatcher {
|
||||
private static final Runnable ourJanitor = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LOG.info("Low memory signal received.");
|
||||
try {
|
||||
for (LowMemoryWatcher watcher : ourInstances) {
|
||||
try {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user